xfs: format logged extents directly into the CIL
authorChristoph Hellwig <hch@infradead.org>
Fri, 13 Dec 2013 00:34:04 +0000 (11:34 +1100)
committerDave Chinner <david@fromorbit.com>
Fri, 13 Dec 2013 00:34:04 +0000 (11:34 +1100)
With the new iop_format scheme there is no need to have a temporary buffer
to format logged extents into, we can do so directly into the CIL.  This
also allows to remove the shortcut for big endian systems that probably
hasn't gotten a lot of test coverage for a long time.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_inode_fork.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h

index cfee14a..06abaee 100644 (file)
@@ -721,15 +721,16 @@ xfs_idestroy_fork(
 }
 
 /*
- * xfs_iextents_copy()
+ * Convert in-core extents to on-disk form
  *
- * This is called to copy the REAL extents (as opposed to the delayed
- * allocation extents) from the inode into the given buffer.  It
- * returns the number of bytes copied into the buffer.
+ * For either the data or attr fork in extent format, we need to endian convert
+ * the in-core extent as we place them into the on-disk inode.
  *
- * If there are no delayed allocation extents, then we can just
- * memcpy() the extents into the buffer.  Otherwise, we need to
- * examine each extent in turn and skip those which are delayed.
+ * In the case of the data fork, the in-core and on-disk fork sizes can be
+ * different due to delayed allocation extents. We only copy on-disk extents
+ * here, so callers must always use the physical fork size to determine the
+ * size of the buffer passed to this routine.  We will return the size actually
+ * used.
  */
 int
 xfs_iextents_copy(
index 6ab318f..45224d2 100644 (file)
@@ -145,43 +145,6 @@ xfs_inode_item_size(
                xfs_inode_item_attr_fork_size(iip, nvecs, nbytes);
 }
 
-/*
- * xfs_inode_item_format_extents - convert in-core extents to on-disk form
- *
- * For either the data or attr fork in extent format, we need to endian convert
- * the in-core extent as we place them into the on-disk inode. In this case, we
- * need to do this conversion before we write the extents into the log. Because
- * we don't have the disk inode to write into here, we allocate a buffer and
- * format the extents into it via xfs_iextents_copy(). We free the buffer in
- * the unlock routine after the copy for the log has been made.
- *
- * In the case of the data fork, the in-core and on-disk fork sizes can be
- * different due to delayed allocation extents. We only log on-disk extents
- * here, so always use the physical fork size to determine the size of the
- * buffer we need to allocate.
- */
-STATIC int
-xfs_inode_item_format_extents(
-       struct xfs_inode        *ip,
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp,
-       int                     whichfork,
-       int                     type)
-{
-       xfs_bmbt_rec_t          *ext_buffer;
-       int                     len;
-
-       ext_buffer = kmem_alloc(XFS_IFORK_SIZE(ip, whichfork), KM_SLEEP);
-       if (whichfork == XFS_DATA_FORK)
-               ip->i_itemp->ili_extents_buf = ext_buffer;
-       else
-               ip->i_itemp->ili_aextents_buf = ext_buffer;
-
-       len = xfs_iextents_copy(ip, ext_buffer, whichfork);
-       xlog_copy_iovec(lv, vecp, type, ext_buffer, len);
-       return len;
-}
-
 /*
  * If this is a v1 format inode, then we need to log it as such.  This means
  * that we have to copy the link count from the new field to the old.  We
@@ -229,30 +192,18 @@ xfs_inode_item_format_data_fork(
                if ((iip->ili_fields & XFS_ILOG_DEXT) &&
                    ip->i_d.di_nextents > 0 &&
                    ip->i_df.if_bytes > 0) {
+                       struct xfs_bmbt_rec *p;
+
                        ASSERT(ip->i_df.if_u1.if_extents != NULL);
                        ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0);
-                       ASSERT(iip->ili_extents_buf == NULL);
-
-#ifdef XFS_NATIVE_HOST
-                       if (ip->i_d.di_nextents == ip->i_df.if_bytes /
-                                               (uint)sizeof(xfs_bmbt_rec_t)) {
-                               /*
-                                * There are no delayed allocation
-                                * extents, so just point to the
-                                * real extents array.
-                                */
-                               xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IEXT,
-                                               ip->i_df.if_u1.if_extents,
-                                               ip->i_df.if_bytes);
-                               ilf->ilf_dsize = ip->i_df.if_bytes;
-                       } else
-#endif
-                       {
-                               ilf->ilf_dsize =
-                                       xfs_inode_item_format_extents(ip, lv, vecp,
-                                               XFS_DATA_FORK, XLOG_REG_TYPE_IEXT);
-                               ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes);
-                       }
+
+                       p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
+                       data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK);
+                       xlog_finish_iovec(lv, *vecp, data_bytes);
+
+                       ASSERT(data_bytes <= ip->i_df.if_bytes);
+
+                       ilf->ilf_dsize = data_bytes;
                        ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_DEXT;
@@ -339,24 +290,17 @@ xfs_inode_item_format_attr_fork(
                if ((iip->ili_fields & XFS_ILOG_AEXT) &&
                    ip->i_d.di_anextents > 0 &&
                    ip->i_afp->if_bytes > 0) {
+                       struct xfs_bmbt_rec *p;
+
                        ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) ==
                                ip->i_d.di_anextents);
                        ASSERT(ip->i_afp->if_u1.if_extents != NULL);
-#ifdef XFS_NATIVE_HOST
-                       /*
-                        * There are not delayed allocation extents
-                        * for attributes, so just point at the array.
-                        */
-                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT,
-                                       ip->i_afp->if_u1.if_extents,
-                                       ip->i_afp->if_bytes);
-                       ilf->ilf_asize = ip->i_afp->if_bytes;
-#else
-                       ASSERT(iip->ili_aextents_buf == NULL);
-                       ilf->ilf_asize =
-                               xfs_inode_item_format_extents(ip, lv, vecp,
-                                       XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT);
-#endif
+
+                       p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT);
+                       data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK);
+                       xlog_finish_iovec(lv, *vecp, data_bytes);
+
+                       ilf->ilf_asize = data_bytes;
                        ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_AEXT;
@@ -571,27 +515,6 @@ xfs_inode_item_unlock(
        ASSERT(ip->i_itemp != NULL);
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
-       /*
-        * If the inode needed a separate buffer with which to log
-        * its extents, then free it now.
-        */
-       if (iip->ili_extents_buf != NULL) {
-               ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS);
-               ASSERT(ip->i_d.di_nextents > 0);
-               ASSERT(iip->ili_fields & XFS_ILOG_DEXT);
-               ASSERT(ip->i_df.if_bytes > 0);
-               kmem_free(iip->ili_extents_buf);
-               iip->ili_extents_buf = NULL;
-       }
-       if (iip->ili_aextents_buf != NULL) {
-               ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS);
-               ASSERT(ip->i_d.di_anextents > 0);
-               ASSERT(iip->ili_fields & XFS_ILOG_AEXT);
-               ASSERT(ip->i_afp->if_bytes > 0);
-               kmem_free(iip->ili_aextents_buf);
-               iip->ili_aextents_buf = NULL;
-       }
-
        lock_flags = iip->ili_lock_flags;
        iip->ili_lock_flags = 0;
        if (lock_flags)
index dce4d65..29b5f2b 100644 (file)
@@ -34,10 +34,6 @@ typedef struct xfs_inode_log_item {
        unsigned short          ili_logged;        /* flushed logged data */
        unsigned int            ili_last_fields;   /* fields when flushed */
        unsigned int            ili_fields;        /* fields to be logged */
-       struct xfs_bmbt_rec     *ili_extents_buf;  /* array of logged
-                                                     data exts */
-       struct xfs_bmbt_rec     *ili_aextents_buf; /* array of logged
-                                                     attr exts */
        xfs_inode_log_format_t  ili_format;        /* logged structure */
 } xfs_inode_log_item_t;