]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/xfs/xfs_inode_item.c
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[karo-tx-linux.git] / fs / xfs / xfs_inode_item.c
index c75e14beff0645942682d1b3d53e74f7c1b1772b..686889b4a1e5d8211e895a1384aadf6faa7de697 100644 (file)
@@ -145,42 +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_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(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
@@ -212,8 +176,9 @@ xfs_inode_item_format_v1_inode(
 STATIC void
 xfs_inode_item_format_data_fork(
        struct xfs_inode_log_item *iip,
-       struct xfs_log_iovec    **vecp,
-       int                     *nvecs)
+       struct xfs_inode_log_format *ilf,
+       struct xfs_log_vec      *lv,
+       struct xfs_log_iovec    **vecp)
 {
        struct xfs_inode        *ip = iip->ili_inode;
        size_t                  data_bytes;
@@ -227,31 +192,19 @@ 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(vecp, XLOG_REG_TYPE_IEXT,
-                                               ip->i_df.if_u1.if_extents,
-                                               ip->i_df.if_bytes);
-                               iip->ili_format.ilf_dsize = ip->i_df.if_bytes;
-                       } else
-#endif
-                       {
-                               iip->ili_format.ilf_dsize =
-                                       xfs_inode_item_format_extents(ip, vecp,
-                                               XFS_DATA_FORK, XLOG_REG_TYPE_IEXT);
-                               ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes);
-                       }
-                       (*nvecs)++;
+
+                       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;
                }
@@ -264,11 +217,11 @@ xfs_inode_item_format_data_fork(
                if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
                    ip->i_df.if_broot_bytes > 0) {
                        ASSERT(ip->i_df.if_broot != NULL);
-                       xlog_copy_iovec(vecp, XLOG_REG_TYPE_IBROOT,
+                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT,
                                        ip->i_df.if_broot,
                                        ip->i_df.if_broot_bytes);
-                       (*nvecs)++;
-                       iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
+                       ilf->ilf_dsize = ip->i_df.if_broot_bytes;
+                       ilf->ilf_size++;
                } else {
                        ASSERT(!(iip->ili_fields &
                                 XFS_ILOG_DBROOT));
@@ -291,10 +244,10 @@ xfs_inode_item_format_data_fork(
                               ip->i_df.if_real_bytes == data_bytes);
                        ASSERT(ip->i_df.if_u1.if_data != NULL);
                        ASSERT(ip->i_d.di_size > 0);
-                       xlog_copy_iovec(vecp, XLOG_REG_TYPE_ILOCAL,
+                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL,
                                        ip->i_df.if_u1.if_data, data_bytes);
-                       (*nvecs)++;
-                       iip->ili_format.ilf_dsize = (unsigned)data_bytes;
+                       ilf->ilf_dsize = (unsigned)data_bytes;
+                       ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_DDATA;
                }
@@ -303,19 +256,15 @@ xfs_inode_item_format_data_fork(
                iip->ili_fields &=
                        ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
                          XFS_ILOG_DEXT | XFS_ILOG_UUID);
-               if (iip->ili_fields & XFS_ILOG_DEV) {
-                       iip->ili_format.ilf_u.ilfu_rdev =
-                               ip->i_df.if_u2.if_rdev;
-               }
+               if (iip->ili_fields & XFS_ILOG_DEV)
+                       ilf->ilf_u.ilfu_rdev = ip->i_df.if_u2.if_rdev;
                break;
        case XFS_DINODE_FMT_UUID:
                iip->ili_fields &=
                        ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
                          XFS_ILOG_DEXT | XFS_ILOG_DEV);
-               if (iip->ili_fields & XFS_ILOG_UUID) {
-                       iip->ili_format.ilf_u.ilfu_uuid =
-                               ip->i_df.if_u2.if_uuid;
-               }
+               if (iip->ili_fields & XFS_ILOG_UUID)
+                       ilf->ilf_u.ilfu_uuid = ip->i_df.if_u2.if_uuid;
                break;
        default:
                ASSERT(0);
@@ -326,8 +275,9 @@ xfs_inode_item_format_data_fork(
 STATIC void
 xfs_inode_item_format_attr_fork(
        struct xfs_inode_log_item *iip,
-       struct xfs_log_iovec    **vecp,
-       int                     *nvecs)
+       struct xfs_inode_log_format *ilf,
+       struct xfs_log_vec      *lv,
+       struct xfs_log_iovec    **vecp)
 {
        struct xfs_inode        *ip = iip->ili_inode;
        size_t                  data_bytes;
@@ -340,25 +290,18 @@ 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(vecp, XLOG_REG_TYPE_IATTR_EXT,
-                                       ip->i_afp->if_u1.if_extents,
-                                       ip->i_afp->if_bytes);
-                       iip->ili_format.ilf_asize = ip->i_afp->if_bytes;
-#else
-                       ASSERT(iip->ili_aextents_buf == NULL);
-                       iip->ili_format.ilf_asize =
-                               xfs_inode_item_format_extents(ip, vecp,
-                                       XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT);
-#endif
-                       (*nvecs)++;
+
+                       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;
                }
@@ -371,11 +314,11 @@ xfs_inode_item_format_attr_fork(
                    ip->i_afp->if_broot_bytes > 0) {
                        ASSERT(ip->i_afp->if_broot != NULL);
 
-                       xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_BROOT,
+                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT,
                                        ip->i_afp->if_broot,
                                        ip->i_afp->if_broot_bytes);
-                       (*nvecs)++;
-                       iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
+                       ilf->ilf_asize = ip->i_afp->if_broot_bytes;
+                       ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_ABROOT;
                }
@@ -395,11 +338,11 @@ xfs_inode_item_format_attr_fork(
                        ASSERT(ip->i_afp->if_real_bytes == 0 ||
                               ip->i_afp->if_real_bytes == data_bytes);
                        ASSERT(ip->i_afp->if_u1.if_data != NULL);
-                       xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_LOCAL,
+                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
                                        ip->i_afp->if_u1.if_data,
                                        data_bytes);
-                       (*nvecs)++;
-                       iip->ili_format.ilf_asize = (unsigned)data_bytes;
+                       ilf->ilf_asize = (unsigned)data_bytes;
+                       ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_ADATA;
                }
@@ -420,42 +363,39 @@ xfs_inode_item_format_attr_fork(
 STATIC void
 xfs_inode_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *vecp)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
-       uint                    nvecs;
-
-       xlog_copy_iovec(&vecp, XLOG_REG_TYPE_IFORMAT,
-                       &iip->ili_format,
-                       sizeof(struct xfs_inode_log_format));
-       nvecs = 1;
-
-       xlog_copy_iovec(&vecp, XLOG_REG_TYPE_ICORE,
-                       &ip->i_d,
-                       xfs_icdinode_size(ip->i_d.di_version));
-       nvecs++;
+       struct xfs_inode_log_format *ilf;
+       struct xfs_log_iovec    *vecp = NULL;
+
+       ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT);
+       ilf->ilf_type = XFS_LI_INODE;
+       ilf->ilf_ino = ip->i_ino;
+       ilf->ilf_blkno = ip->i_imap.im_blkno;
+       ilf->ilf_len = ip->i_imap.im_len;
+       ilf->ilf_boffset = ip->i_imap.im_boffset;
+       ilf->ilf_fields = XFS_ILOG_CORE;
+       ilf->ilf_size = 2; /* format + core */
+       xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format));
 
        if (ip->i_d.di_version == 1)
                xfs_inode_item_format_v1_inode(ip);
+       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE,
+                       &ip->i_d,
+                       xfs_icdinode_size(ip->i_d.di_version));
 
-       xfs_inode_item_format_data_fork(iip, &vecp, &nvecs);
+       xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
        if (XFS_IFORK_Q(ip)) {
-               xfs_inode_item_format_attr_fork(iip, &vecp, &nvecs);
+               xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
        } else {
                iip->ili_fields &=
                        ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
        }
 
-       /*
-        * Now update the log format that goes out to disk from the in-core
-        * values.  We always write the inode core to make the arithmetic
-        * games in recovery easier, which isn't a big deal as just about any
-        * transaction would dirty it anyway.
-        */
-       iip->ili_format.ilf_fields = XFS_ILOG_CORE |
-               (iip->ili_fields & ~XFS_ILOG_TIMESTAMP);
-       iip->ili_format.ilf_size = nvecs;
+       /* update the format with the exact fields we actually logged */
+       ilf->ilf_fields |= (iip->ili_fields & ~XFS_ILOG_TIMESTAMP);
 }
 
 /*
@@ -573,27 +513,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)
@@ -680,11 +599,6 @@ xfs_inode_item_init(
        iip->ili_inode = ip;
        xfs_log_item_init(mp, &iip->ili_item, XFS_LI_INODE,
                                                &xfs_inode_item_ops);
-       iip->ili_format.ilf_type = XFS_LI_INODE;
-       iip->ili_format.ilf_ino = ip->i_ino;
-       iip->ili_format.ilf_blkno = ip->i_imap.im_blkno;
-       iip->ili_format.ilf_len = ip->i_imap.im_len;
-       iip->ili_format.ilf_boffset = ip->i_imap.im_boffset;
 }
 
 /*