]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge tag 'xfs-for-linus-v3.14-rc1' of git://oss.sgi.com/xfs/xfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Jan 2014 17:16:20 +0000 (09:16 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Jan 2014 17:16:20 +0000 (09:16 -0800)
Pull xfs update from Ben Myers:
 "This is primarily bug fixes, many of which you already have.  New
  stuff includes a series to decouple the in-memory and on-disk log
  format, helpers in the area of inode clusters, and i_version handling.

  We decided to try to use more topic branches this release, so there
  are some merge commits in there on account of that.  I'm afraid I
  didn't do a good job of putting meaningful comments in the first
  couple of merges.  Sorry about that.  I think I have the hang of it
  now.

  For 3.14-rc1 there are fixes in the areas of remote attributes,
  discard, growfs, memory leaks in recovery, directory v2, quotas, the
  MAINTAINERS file, allocation alignment, extent list locking, and in
  xfs_bmapi_allocate.  There are cleanups in xfs_setsize_buftarg,
  removing unused macros, quotas, setattr, and freeing of inode
  clusters.  The in-memory and on-disk log format have been decoupled, a
  common helper to calculate the number of blocks in an inode cluster
  has been added, and handling of i_version has been pulled into the
  filesystems that use it.

   - cleanup in xfs_setsize_buftarg
   - removal of remaining unused flags for vop toss/flush/flushinval
   - fix for memory corruption in xfs_attrlist_by_handle
   - fix for out-of-date comment in xfs_trans_dqlockedjoin
   - fix for discard if range length is less than one block
   - fix for overrun of agfl buffer using growfs on v4 superblock
     filesystems
   - pull i_version handling out into the filesystems that use it
   - don't leak recovery items on error
   - fix for memory leak in xfs_dir2_node_removename
   - several cleanups for quotas
   - fix bad assertion in xfs_qm_vop_create_dqattach
   - cleanup for xfs_setattr_mode, and add xfs_setattr_time
   - fix quota assert in xfs_setattr_nonsize
   - fix an infinite loop when turning off group/project quota before
     user quota
   - fix for temporary buffer allocation failure in xfs_dir2_block_to_sf
     with large directory block sizes
   - fix Dave's email address in MAINTAINERS
   - cleanup calculation of freed inode cluster blocks
   - fix alignment of initial file allocations to match filesystem
     geometry
   - decouple in-memory and on-disk log format
   - introduce a common helper to calculate the number of filesystem
     blocks in an inode cluster
   - fixes for extent list locking
   - fix for off-by-one in xfs_attr3_rmt_verify
   - fix for missing destroy_work_on_stack in xfs_bmapi_allocate"

* tag 'xfs-for-linus-v3.14-rc1' of git://oss.sgi.com/xfs/xfs: (51 commits)
  xfs: Calling destroy_work_on_stack() to pair with INIT_WORK_ONSTACK()
  xfs: fix off-by-one error in xfs_attr3_rmt_verify
  xfs: assert that we hold the ilock for extent map access
  xfs: use xfs_ilock_attr_map_shared in xfs_attr_list_int
  xfs: use xfs_ilock_attr_map_shared in xfs_attr_get
  xfs: use xfs_ilock_data_map_shared in xfs_qm_dqiterate
  xfs: use xfs_ilock_data_map_shared in xfs_qm_dqtobp
  xfs: take the ilock around xfs_bmapi_read in xfs_zero_remaining_bytes
  xfs: reinstate the ilock in xfs_readdir
  xfs: add xfs_ilock_attr_map_shared
  xfs: rename xfs_ilock_map_shared
  xfs: remove xfs_iunlock_map_shared
  xfs: no need to lock the inode in xfs_find_handle
  xfs: use xfs_icluster_size_fsb in xfs_imap
  xfs: use xfs_icluster_size_fsb in xfs_ifree_cluster
  xfs: use xfs_icluster_size_fsb in xfs_ialloc_inode_init
  xfs: use xfs_icluster_size_fsb in xfs_bulkstat
  xfs: introduce a common helper xfs_icluster_size_fsb
  xfs: get rid of XFS_IALLOC_BLOCKS macros
  xfs: get rid of XFS_INODE_CLUSTER_SIZE macros
  ...

40 files changed:
fs/attr.c
fs/btrfs/inode.c
fs/ext4/inode.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr_list.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dir2_readdir.c
fs/xfs/xfs_dir2_sf.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_dquot_item.c
fs/xfs/xfs_dquot_item.h
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_file.c
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc.h
fs/xfs/xfs_icreate_item.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_fork.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_itable.c
fs/xfs/xfs_log.h
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_qm.h
fs/xfs/xfs_qm_syscalls.c
fs/xfs/xfs_quota_priv.h [deleted file]
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans_dquot.c
fs/xfs/xfs_trans_resv.c
fs/xfs/xfs_trans_space.h
fs/xfs/xfs_vnode.h

index 267968d946739a2f3c17a20b4ffb5776e21ece75..5d4e59d56e854a158614302531cd15d1e8d0b5b6 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -202,11 +202,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
                        return -EPERM;
        }
 
-       if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) {
-               if (attr->ia_size != inode->i_size)
-                       inode_inc_iversion(inode);
-       }
-
        if ((ia_valid & ATTR_MODE)) {
                umode_t amode = attr->ia_mode;
                /* Flag setting protected by i_mutex */
index f1a77449d032b1fbd481eb16cd232653e5bfbefa..471a4f7f4044d4171f823e996ff89b68d237abb0 100644 (file)
@@ -4354,8 +4354,12 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)
         * these flags set.  For all other operations the VFS set these flags
         * explicitly if it wants a timestamp update.
         */
-       if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME))))
-               inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
+       if (newsize != oldsize) {
+               inode_inc_iversion(inode);
+               if (!(mask & (ATTR_CTIME | ATTR_MTIME)))
+                       inode->i_ctime = inode->i_mtime =
+                               current_fs_time(inode->i_sb);
+       }
 
        if (newsize > oldsize) {
                truncate_pagecache(inode, newsize);
index 61d49ff22c81f844cb8bc6324ad3aa70d649fb7b..31fa964742bcba1b0f9dbd494e469feb56ee8428 100644 (file)
@@ -4586,6 +4586,10 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        if (attr->ia_size > sbi->s_bitmap_maxbytes)
                                return -EFBIG;
                }
+
+               if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size)
+                       inode_inc_iversion(inode);
+
                if (S_ISREG(inode->i_mode) &&
                    (attr->ia_size < inode->i_size)) {
                        if (ext4_should_order_data(inode)) {
index 71c8c9d2b8826a0ed22d886fb3327d2ff0784fc3..a26739451b535cf02a8016c423583f76a26bac72 100644 (file)
@@ -1217,7 +1217,7 @@ __xfs_get_blocks(
                lockmode = XFS_ILOCK_EXCL;
                xfs_ilock(ip, lockmode);
        } else {
-               lockmode = xfs_ilock_map_shared(ip);
+               lockmode = xfs_ilock_data_map_shared(ip);
        }
 
        ASSERT(offset <= mp->m_super->s_maxbytes);
index b86127072ac3c2b9bd201b34cf208c3f1735cd68..01b6a0102fbdd4d153612740d95c4f00fda691f7 100644 (file)
@@ -164,6 +164,7 @@ xfs_attr_get(
 {
        int             error;
        struct xfs_name xname;
+       uint            lock_mode;
 
        XFS_STATS_INC(xs_attr_get);
 
@@ -174,9 +175,9 @@ xfs_attr_get(
        if (error)
                return error;
 
-       xfs_ilock(ip, XFS_ILOCK_SHARED);
+       lock_mode = xfs_ilock_attr_map_shared(ip);
        error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags);
-       xfs_iunlock(ip, XFS_ILOCK_SHARED);
+       xfs_iunlock(ip, lock_mode);
        return(error);
 }
 
index 2d174b12815345b5aafacb7046caf6a0bc98d147..01db96f60cf05abf1f42e20252cdff4de0ebea0d 100644 (file)
@@ -507,17 +507,17 @@ xfs_attr_list_int(
 {
        int error;
        xfs_inode_t *dp = context->dp;
+       uint            lock_mode;
 
        XFS_STATS_INC(xs_attr_list);
 
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return EIO;
 
-       xfs_ilock(dp, XFS_ILOCK_SHARED);
-
        /*
         * Decide on what work routines to call based on the inode size.
         */
+       lock_mode = xfs_ilock_attr_map_shared(dp);
        if (!xfs_inode_hasattr(dp)) {
                error = 0;
        } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
@@ -527,9 +527,7 @@ xfs_attr_list_int(
        } else {
                error = xfs_attr_node_list(context);
        }
-
-       xfs_iunlock(dp, XFS_ILOCK_SHARED);
-
+       xfs_iunlock(dp, lock_mode);
        return error;
 }
 
index 3b2c14b6f0fb13efd7a3aa89abc05d0a8334a5ff..152543c4ca7031e718bc921b82e9e0a72955de11 100644 (file)
@@ -4013,6 +4013,7 @@ xfs_bmapi_read(
        ASSERT(*nmap >= 1);
        ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE|
                           XFS_BMAPI_IGSTATE)));
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL));
 
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -4207,6 +4208,7 @@ xfs_bmapi_delay(
        ASSERT(*nmap >= 1);
        ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
        ASSERT(!(flags & ~XFS_BMAPI_ENTIRE));
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS &&
@@ -4500,6 +4502,7 @@ xfs_bmapi_write(
        ASSERT(tp != NULL);
        ASSERT(len > 0);
        ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -5051,6 +5054,7 @@ xfs_bunmapi(
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
        ASSERT(len > 0);
        ASSERT(nexts >= 0);
 
index 82e0dab46ee52cc991a7130d8f671e011eef10a3..f264616080cac0c6bdfdc084c188b15505aa92e7 100644 (file)
@@ -618,22 +618,27 @@ xfs_getbmap(
                return XFS_ERROR(ENOMEM);
 
        xfs_ilock(ip, XFS_IOLOCK_SHARED);
-       if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) {
-               if (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size) {
+       if (whichfork == XFS_DATA_FORK) {
+               if (!(iflags & BMV_IF_DELALLOC) &&
+                   (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size)) {
                        error = -filemap_write_and_wait(VFS_I(ip)->i_mapping);
                        if (error)
                                goto out_unlock_iolock;
+
+                       /*
+                        * Even after flushing the inode, there can still be
+                        * delalloc blocks on the inode beyond EOF due to
+                        * speculative preallocation.  These are not removed
+                        * until the release function is called or the inode
+                        * is inactivated.  Hence we cannot assert here that
+                        * ip->i_delayed_blks == 0.
+                        */
                }
-               /*
-                * even after flushing the inode, there can still be delalloc
-                * blocks on the inode beyond EOF due to speculative
-                * preallocation. These are not removed until the release
-                * function is called or the inode is inactivated. Hence we
-                * cannot assert here that ip->i_delayed_blks == 0.
-                */
-       }
 
-       lock = xfs_ilock_map_shared(ip);
+               lock = xfs_ilock_data_map_shared(ip);
+       } else {
+               lock = xfs_ilock_attr_map_shared(ip);
+       }
 
        /*
         * Don't let nex be bigger than the number of extents
@@ -738,7 +743,7 @@ xfs_getbmap(
  out_free_map:
        kmem_free(map);
  out_unlock_ilock:
-       xfs_iunlock_map_shared(ip, lock);
+       xfs_iunlock(ip, lock);
  out_unlock_iolock:
        xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
@@ -1169,9 +1174,15 @@ xfs_zero_remaining_bytes(
        xfs_buf_unlock(bp);
 
        for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
+               uint lock_mode;
+
                offset_fsb = XFS_B_TO_FSBT(mp, offset);
                nimap = 1;
+
+               lock_mode = xfs_ilock_data_map_shared(ip);
                error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0);
+               xfs_iunlock(ip, lock_mode);
+
                if (error || nimap < 1)
                        break;
                ASSERT(imap.br_blockcount >= 1);
index afe7645e4b2b8b7746665ed35a0d55da6ce11e3b..9fccfb59429119be16786e1fd2d9b6104546ef93 100644 (file)
@@ -1593,12 +1593,11 @@ xfs_free_buftarg(
        kmem_free(btp);
 }
 
-STATIC int
-xfs_setsize_buftarg_flags(
+int
+xfs_setsize_buftarg(
        xfs_buftarg_t           *btp,
        unsigned int            blocksize,
-       unsigned int            sectorsize,
-       int                     verbose)
+       unsigned int            sectorsize)
 {
        btp->bt_bsize = blocksize;
        btp->bt_sshift = ffs(sectorsize) - 1;
@@ -1619,26 +1618,17 @@ xfs_setsize_buftarg_flags(
 }
 
 /*
- *     When allocating the initial buffer target we have not yet
- *     read in the superblock, so don't know what sized sectors
- *     are being used at this early stage.  Play safe.
+ * When allocating the initial buffer target we have not yet
+ * read in the superblock, so don't know what sized sectors
+ * are being used at this early stage.  Play safe.
  */
 STATIC int
 xfs_setsize_buftarg_early(
        xfs_buftarg_t           *btp,
        struct block_device     *bdev)
 {
-       return xfs_setsize_buftarg_flags(btp,
-                       PAGE_SIZE, bdev_logical_block_size(bdev), 0);
-}
-
-int
-xfs_setsize_buftarg(
-       xfs_buftarg_t           *btp,
-       unsigned int            blocksize,
-       unsigned int            sectorsize)
-{
-       return xfs_setsize_buftarg_flags(btp, blocksize, sectorsize, 1);
+       return xfs_setsize_buftarg(btp, PAGE_SIZE,
+                                  bdev_logical_block_size(bdev));
 }
 
 xfs_buftarg_t *
index 2227b9b050bb30248d986b343dd33e42c7978529..33149113e333bd8b536d71c80b234b5d39fcb53e 100644 (file)
@@ -182,21 +182,47 @@ xfs_buf_item_size(
        trace_xfs_buf_item_size(bip);
 }
 
-static struct xfs_log_iovec *
+static inline void
+xfs_buf_item_copy_iovec(
+       struct xfs_log_vec      *lv,
+       struct xfs_log_iovec    **vecp,
+       struct xfs_buf          *bp,
+       uint                    offset,
+       int                     first_bit,
+       uint                    nbits)
+{
+       offset += first_bit * XFS_BLF_CHUNK;
+       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BCHUNK,
+                       xfs_buf_offset(bp, offset),
+                       nbits * XFS_BLF_CHUNK);
+}
+
+static inline bool
+xfs_buf_item_straddle(
+       struct xfs_buf          *bp,
+       uint                    offset,
+       int                     next_bit,
+       int                     last_bit)
+{
+       return xfs_buf_offset(bp, offset + (next_bit << XFS_BLF_SHIFT)) !=
+               (xfs_buf_offset(bp, offset + (last_bit << XFS_BLF_SHIFT)) +
+                XFS_BLF_CHUNK);
+}
+
+static void
 xfs_buf_item_format_segment(
        struct xfs_buf_log_item *bip,
-       struct xfs_log_iovec    *vecp,
+       struct xfs_log_vec      *lv,
+       struct xfs_log_iovec    **vecp,
        uint                    offset,
        struct xfs_buf_log_format *blfp)
 {
        struct xfs_buf  *bp = bip->bli_buf;
        uint            base_size;
-       uint            nvecs;
        int             first_bit;
        int             last_bit;
        int             next_bit;
        uint            nbits;
-       uint            buffer_offset;
 
        /* copy the flags across from the base format item */
        blfp->blf_flags = bip->__bli_format.blf_flags;
@@ -208,21 +234,17 @@ xfs_buf_item_format_segment(
         */
        base_size = xfs_buf_log_format_size(blfp);
 
-       nvecs = 0;
        first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0);
        if (!(bip->bli_flags & XFS_BLI_STALE) && first_bit == -1) {
                /*
                 * If the map is not be dirty in the transaction, mark
                 * the size as zero and do not advance the vector pointer.
                 */
-               goto out;
+               return;
        }
 
-       vecp->i_addr = blfp;
-       vecp->i_len = base_size;
-       vecp->i_type = XLOG_REG_TYPE_BFORMAT;
-       vecp++;
-       nvecs = 1;
+       blfp = xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size);
+       blfp->blf_size = 1;
 
        if (bip->bli_flags & XFS_BLI_STALE) {
                /*
@@ -232,14 +254,13 @@ xfs_buf_item_format_segment(
                 */
                trace_xfs_buf_item_format_stale(bip);
                ASSERT(blfp->blf_flags & XFS_BLF_CANCEL);
-               goto out;
+               return;
        }
 
 
        /*
         * Fill in an iovec for each set of contiguous chunks.
         */
-
        last_bit = first_bit;
        nbits = 1;
        for (;;) {
@@ -252,42 +273,22 @@ xfs_buf_item_format_segment(
                next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size,
                                        (uint)last_bit + 1);
                /*
-                * If we run out of bits fill in the last iovec and get
-                * out of the loop.
-                * Else if we start a new set of bits then fill in the
-                * iovec for the series we were looking at and start
-                * counting the bits in the new one.
-                * Else we're still in the same set of bits so just
-                * keep counting and scanning.
+                * If we run out of bits fill in the last iovec and get out of
+                * the loop.  Else if we start a new set of bits then fill in
+                * the iovec for the series we were looking at and start
+                * counting the bits in the new one.  Else we're still in the
+                * same set of bits so just keep counting and scanning.
                 */
                if (next_bit == -1) {
-                       buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
-                       vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
-                       vecp->i_len = nbits * XFS_BLF_CHUNK;
-                       vecp->i_type = XLOG_REG_TYPE_BCHUNK;
-                       nvecs++;
+                       xfs_buf_item_copy_iovec(lv, vecp, bp, offset,
+                                               first_bit, nbits);
+                       blfp->blf_size++;
                        break;
-               } else if (next_bit != last_bit + 1) {
-                       buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
-                       vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
-                       vecp->i_len = nbits * XFS_BLF_CHUNK;
-                       vecp->i_type = XLOG_REG_TYPE_BCHUNK;
-                       nvecs++;
-                       vecp++;
-                       first_bit = next_bit;
-                       last_bit = next_bit;
-                       nbits = 1;
-               } else if (xfs_buf_offset(bp, offset +
-                                             (next_bit << XFS_BLF_SHIFT)) !=
-                          (xfs_buf_offset(bp, offset +
-                                              (last_bit << XFS_BLF_SHIFT)) +
-                           XFS_BLF_CHUNK)) {
-                       buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
-                       vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
-                       vecp->i_len = nbits * XFS_BLF_CHUNK;
-                       vecp->i_type = XLOG_REG_TYPE_BCHUNK;
-                       nvecs++;
-                       vecp++;
+               } else if (next_bit != last_bit + 1 ||
+                          xfs_buf_item_straddle(bp, offset, next_bit, last_bit)) {
+                       xfs_buf_item_copy_iovec(lv, vecp, bp, offset,
+                                               first_bit, nbits);
+                       blfp->blf_size++;
                        first_bit = next_bit;
                        last_bit = next_bit;
                        nbits = 1;
@@ -296,9 +297,6 @@ xfs_buf_item_format_segment(
                        nbits++;
                }
        }
-out:
-       blfp->blf_size = nvecs;
-       return vecp;
 }
 
 /*
@@ -310,10 +308,11 @@ out:
 STATIC void
 xfs_buf_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *vecp)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_buf_log_item *bip = BUF_ITEM(lip);
        struct xfs_buf          *bp = bip->bli_buf;
+       struct xfs_log_iovec    *vecp = NULL;
        uint                    offset = 0;
        int                     i;
 
@@ -354,8 +353,8 @@ xfs_buf_item_format(
        }
 
        for (i = 0; i < bip->bli_format_count; i++) {
-               vecp = xfs_buf_item_format_segment(bip, vecp, offset,
-                                               &bip->bli_formats[i]);
+               xfs_buf_item_format_segment(bip, lv, &vecp, offset,
+                                           &bip->bli_formats[i]);
                offset += bp->b_maps[i].bm_len;
        }
 
index c4e50c6ed5845fb94a46c77a0f4f1ae987d4d87f..aead369e1c30471f5b176661afc4e2ee7beb5afa 100644 (file)
@@ -674,6 +674,7 @@ xfs_readdir(
 {
        int             rval;           /* return value */
        int             v;              /* type-checking value */
+       uint            lock_mode;
 
        trace_xfs_readdir(dp);
 
@@ -683,6 +684,7 @@ xfs_readdir(
        ASSERT(S_ISDIR(dp->i_d.di_mode));
        XFS_STATS_INC(xs_dir_getdents);
 
+       lock_mode = xfs_ilock_data_map_shared(dp);
        if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
                rval = xfs_dir2_sf_getdents(dp, ctx);
        else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
@@ -691,5 +693,7 @@ xfs_readdir(
                rval = xfs_dir2_block_getdents(dp, ctx);
        else
                rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
+       xfs_iunlock(dp, lock_mode);
+
        return rval;
 }
index aafc6e46cb5803620998399bea5da520aa720f83..3725fb1b902b8becf5f594524fd8143026aee03e 100644 (file)
@@ -170,6 +170,7 @@ xfs_dir2_block_to_sf(
        char                    *ptr;           /* current data pointer */
        xfs_dir2_sf_entry_t     *sfep;          /* shortform entry */
        xfs_dir2_sf_hdr_t       *sfp;           /* shortform directory header */
+       xfs_dir2_sf_hdr_t       *dst;           /* temporary data buffer */
 
        trace_xfs_dir2_block_to_sf(args);
 
@@ -177,35 +178,20 @@ xfs_dir2_block_to_sf(
        mp = dp->i_mount;
 
        /*
-        * Make a copy of the block data, so we can shrink the inode
-        * and add local data.
+        * allocate a temporary destination buffer the size of the inode
+        * to format the data into. Once we have formatted the data, we
+        * can free the block and copy the formatted data into the inode literal
+        * area.
         */
-       hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP);
-       memcpy(hdr, bp->b_addr, mp->m_dirblksize);
-       logflags = XFS_ILOG_CORE;
-       if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) {
-               ASSERT(error != ENOSPC);
-               goto out;
-       }
+       dst = kmem_alloc(mp->m_sb.sb_inodesize, KM_SLEEP);
+       hdr = bp->b_addr;
 
-       /*
-        * The buffer is now unconditionally gone, whether
-        * xfs_dir2_shrink_inode worked or not.
-        *
-        * Convert the inode to local format.
-        */
-       dp->i_df.if_flags &= ~XFS_IFEXTENTS;
-       dp->i_df.if_flags |= XFS_IFINLINE;
-       dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
-       ASSERT(dp->i_df.if_bytes == 0);
-       xfs_idata_realloc(dp, size, XFS_DATA_FORK);
-       logflags |= XFS_ILOG_DDATA;
        /*
         * Copy the header into the newly allocate local space.
         */
-       sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
+       sfp = (xfs_dir2_sf_hdr_t *)dst;
        memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count));
-       dp->i_d.di_size = size;
+
        /*
         * Set up to loop over the block's entries.
         */
@@ -258,10 +244,34 @@ xfs_dir2_block_to_sf(
                ptr += dp->d_ops->data_entsize(dep->namelen);
        }
        ASSERT((char *)sfep - (char *)sfp == size);
+
+       /* now we are done with the block, we can shrink the inode */
+       logflags = XFS_ILOG_CORE;
+       error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp);
+       if (error) {
+               ASSERT(error != ENOSPC);
+               goto out;
+       }
+
+       /*
+        * The buffer is now unconditionally gone, whether
+        * xfs_dir2_shrink_inode worked or not.
+        *
+        * Convert the inode to local format and copy the data in.
+        */
+       dp->i_df.if_flags &= ~XFS_IFEXTENTS;
+       dp->i_df.if_flags |= XFS_IFINLINE;
+       dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
+       ASSERT(dp->i_df.if_bytes == 0);
+       xfs_idata_realloc(dp, size, XFS_DATA_FORK);
+
+       logflags |= XFS_ILOG_DDATA;
+       memcpy(dp->i_df.if_u1.if_data, dst, size);
+       dp->i_d.di_size = size;
        xfs_dir2_sf_check(args);
 out:
        xfs_trans_log_inode(args->trans, dp, logflags);
-       kmem_free(hdr);
+       kmem_free(dst);
        return error;
 }
 
index 6b1e695caf0ebf8bf256150d2efc9483667b837d..7aeb4c895b3294e84731b44f6f75487d6a655c3e 100644 (file)
@@ -469,16 +469,17 @@ xfs_qm_dqtobp(
        struct xfs_mount        *mp = dqp->q_mount;
        xfs_dqid_t              id = be32_to_cpu(dqp->q_core.d_id);
        struct xfs_trans        *tp = (tpp ? *tpp : NULL);
+       uint                    lock_mode;
 
        dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
 
-       xfs_ilock(quotip, XFS_ILOCK_SHARED);
+       lock_mode = xfs_ilock_data_map_shared(quotip);
        if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
                /*
                 * Return if this type of quotas is turned off while we
                 * didn't have the quota inode lock.
                 */
-               xfs_iunlock(quotip, XFS_ILOCK_SHARED);
+               xfs_iunlock(quotip, lock_mode);
                return ESRCH;
        }
 
@@ -488,7 +489,7 @@ xfs_qm_dqtobp(
        error = xfs_bmapi_read(quotip, dqp->q_fileoffset,
                               XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0);
 
-       xfs_iunlock(quotip, XFS_ILOCK_SHARED);
+       xfs_iunlock(quotip, lock_mode);
        if (error)
                return error;
 
index 92e5f62eefc6612fb5890631edd42629af1e768b..f33fbaaa4d8a924978d9df42cc58e6774ac749be 100644 (file)
@@ -57,20 +57,24 @@ xfs_qm_dquot_logitem_size(
 STATIC void
 xfs_qm_dquot_logitem_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *logvec)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_dq_logitem   *qlip = DQUOT_ITEM(lip);
-
-       logvec->i_addr = &qlip->qli_format;
-       logvec->i_len  = sizeof(xfs_dq_logformat_t);
-       logvec->i_type = XLOG_REG_TYPE_QFORMAT;
-       logvec++;
-       logvec->i_addr = &qlip->qli_dquot->q_core;
-       logvec->i_len  = sizeof(xfs_disk_dquot_t);
-       logvec->i_type = XLOG_REG_TYPE_DQUOT;
-
-       qlip->qli_format.qlf_size = 2;
-
+       struct xfs_log_iovec    *vecp = NULL;
+       struct xfs_dq_logformat *qlf;
+
+       qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT);
+       qlf->qlf_type = XFS_LI_DQUOT;
+       qlf->qlf_size = 2;
+       qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id);
+       qlf->qlf_blkno = qlip->qli_dquot->q_blkno;
+       qlf->qlf_len = 1;
+       qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
+       xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
+
+       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
+                       &qlip->qli_dquot->q_core,
+                       sizeof(struct xfs_disk_dquot));
 }
 
 /*
@@ -257,18 +261,6 @@ xfs_qm_dquot_logitem_init(
        xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT,
                                        &xfs_dquot_item_ops);
        lp->qli_dquot = dqp;
-       lp->qli_format.qlf_type = XFS_LI_DQUOT;
-       lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
-       lp->qli_format.qlf_blkno = dqp->q_blkno;
-       lp->qli_format.qlf_len = 1;
-       /*
-        * This is just the offset of this dquot within its buffer
-        * (which is currently 1 FSB and probably won't change).
-        * Hence 32 bits for this offset should be just fine.
-        * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t))
-        * here, and recompute it at recovery time.
-        */
-       lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset;
 }
 
 /*------------------  QUOTAOFF LOG ITEMS  -------------------*/
@@ -294,26 +286,20 @@ xfs_qm_qoff_logitem_size(
        *nbytes += sizeof(struct xfs_qoff_logitem);
 }
 
-/*
- * This is called to fill in the vector of log iovecs for the
- * given quotaoff log item. We use only 1 iovec, and we point that
- * at the quotaoff_log_format structure embedded in the quotaoff item.
- * It is at this point that we assert that all of the extent
- * slots in the quotaoff item have been filled.
- */
 STATIC void
 xfs_qm_qoff_logitem_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *log_vector)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip);
-
-       ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF);
-
-       log_vector->i_addr = &qflip->qql_format;
-       log_vector->i_len = sizeof(xfs_qoff_logitem_t);
-       log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF;
-       qflip->qql_format.qf_size = 1;
+       struct xfs_log_iovec    *vecp = NULL;
+       struct xfs_qoff_logformat *qlf;
+
+       qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF);
+       qlf->qf_type = XFS_LI_QUOTAOFF;
+       qlf->qf_size = 1;
+       qlf->qf_flags = qflip->qql_flags;
+       xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem));
 }
 
 /*
@@ -453,8 +439,7 @@ xfs_qm_qoff_logitem_init(
        xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ?
                        &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops);
        qf->qql_item.li_mountp = mp;
-       qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
-       qf->qql_format.qf_flags = flags;
        qf->qql_start_lip = start;
+       qf->qql_flags = flags;
        return qf;
 }
index 5acae2ada70b0343e9f7d58f11b85d74259e62fb..502e9464634a3eaef114bc53a9cd6ed9d4122355 100644 (file)
@@ -27,13 +27,12 @@ typedef struct xfs_dq_logitem {
        xfs_log_item_t           qli_item;         /* common portion */
        struct xfs_dquot        *qli_dquot;        /* dquot ptr */
        xfs_lsn_t                qli_flush_lsn;    /* lsn at last flush */
-       xfs_dq_logformat_t       qli_format;       /* logged structure */
 } xfs_dq_logitem_t;
 
 typedef struct xfs_qoff_logitem {
        xfs_log_item_t           qql_item;      /* common portion */
        struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */
-       xfs_qoff_logformat_t     qql_format;    /* logged structure */
+       unsigned int            qql_flags;
 } xfs_qoff_logitem_t;
 
 
index 3680d04f973fa1c9de4390079a5c5ba3d8e69eae..fb7a4c1ce1c537255294d66e79639699658544b1 100644 (file)
@@ -26,6 +26,7 @@
 #include "xfs_trans_priv.h"
 #include "xfs_buf_item.h"
 #include "xfs_extfree_item.h"
+#include "xfs_log.h"
 
 
 kmem_zone_t    *xfs_efi_zone;
@@ -101,9 +102,10 @@ xfs_efi_item_size(
 STATIC void
 xfs_efi_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *log_vector)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_efi_log_item *efip = EFI_ITEM(lip);
+       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(atomic_read(&efip->efi_next_extent) ==
                                efip->efi_format.efi_nextents);
@@ -111,10 +113,9 @@ xfs_efi_item_format(
        efip->efi_format.efi_type = XFS_LI_EFI;
        efip->efi_format.efi_size = 1;
 
-       log_vector->i_addr = &efip->efi_format;
-       log_vector->i_len = xfs_efi_item_sizeof(efip);
-       log_vector->i_type = XLOG_REG_TYPE_EFI_FORMAT;
-       ASSERT(log_vector->i_len >= sizeof(xfs_efi_log_format_t));
+       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT,
+                       &efip->efi_format,
+                       xfs_efi_item_sizeof(efip));
 }
 
 
@@ -368,19 +369,19 @@ xfs_efd_item_size(
 STATIC void
 xfs_efd_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *log_vector)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
+       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
 
        efdp->efd_format.efd_type = XFS_LI_EFD;
        efdp->efd_format.efd_size = 1;
 
-       log_vector->i_addr = &efdp->efd_format;
-       log_vector->i_len = xfs_efd_item_sizeof(efdp);
-       log_vector->i_type = XLOG_REG_TYPE_EFD_FORMAT;
-       ASSERT(log_vector->i_len >= sizeof(xfs_efd_log_format_t));
+       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT,
+                       &efdp->efd_format,
+                       xfs_efd_item_sizeof(efdp));
 }
 
 /*
index 52c91e1437255c60d1f56041d4eceea4601f6265..e001215926326c6a87ce1d5d9887a11aafeb84ca 100644 (file)
@@ -912,7 +912,7 @@ xfs_dir_open(
         * If there are any blocks, read-ahead block 0 as we're almost
         * certain to have the next operation be a read there.
         */
-       mode = xfs_ilock_map_shared(ip);
+       mode = xfs_ilock_data_map_shared(ip);
        if (ip->i_d.di_nextents > 0)
                xfs_dir3_data_readahead(NULL, ip, 0, -1);
        xfs_iunlock(ip, mode);
@@ -1215,7 +1215,7 @@ xfs_seek_data(
        uint                    lock;
        int                     error;
 
-       lock = xfs_ilock_map_shared(ip);
+       lock = xfs_ilock_data_map_shared(ip);
 
        isize = i_size_read(inode);
        if (start >= isize) {
@@ -1294,7 +1294,7 @@ out:
        offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
 
 out_unlock:
-       xfs_iunlock_map_shared(ip, lock);
+       xfs_iunlock(ip, lock);
 
        if (error)
                return -error;
@@ -1319,7 +1319,7 @@ xfs_seek_hole(
        if (XFS_FORCED_SHUTDOWN(mp))
                return -XFS_ERROR(EIO);
 
-       lock = xfs_ilock_map_shared(ip);
+       lock = xfs_ilock_data_map_shared(ip);
 
        isize = i_size_read(inode);
        if (start >= isize) {
@@ -1402,7 +1402,7 @@ out:
        offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
 
 out_unlock:
-       xfs_iunlock_map_shared(ip, lock);
+       xfs_iunlock(ip, lock);
 
        if (error)
                return -error;
index e87719c5bebe128988a0993c4dc0f703cd3733ca..5d7f105a1c82e932175ce61b3dfce66b2282966e 100644 (file)
@@ -52,7 +52,7 @@ xfs_ialloc_cluster_alignment(
 {
        if (xfs_sb_version_hasalign(&args->mp->m_sb) &&
            args->mp->m_sb.sb_inoalignmt >=
-            XFS_B_TO_FSBT(args->mp, XFS_INODE_CLUSTER_SIZE(args->mp)))
+            XFS_B_TO_FSBT(args->mp, args->mp->m_inode_cluster_size))
                return args->mp->m_sb.sb_inoalignmt;
        return 1;
 }
@@ -170,27 +170,20 @@ xfs_ialloc_inode_init(
 {
        struct xfs_buf          *fbuf;
        struct xfs_dinode       *free;
-       int                     blks_per_cluster, nbufs, ninodes;
+       int                     nbufs, blks_per_cluster, inodes_per_cluster;
        int                     version;
        int                     i, j;
        xfs_daddr_t             d;
        xfs_ino_t               ino = 0;
 
        /*
-        * Loop over the new block(s), filling in the inodes.
-        * For small block sizes, manipulate the inodes in buffers
-        * which are multiples of the blocks size.
+        * Loop over the new block(s), filling in the inodes.  For small block
+        * sizes, manipulate the inodes in buffers  which are multiples of the
+        * blocks size.
         */
-       if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
-               blks_per_cluster = 1;
-               nbufs = length;
-               ninodes = mp->m_sb.sb_inopblock;
-       } else {
-               blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
-                                  mp->m_sb.sb_blocksize;
-               nbufs = length / blks_per_cluster;
-               ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
-       }
+       blks_per_cluster = xfs_icluster_size_fsb(mp);
+       inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
+       nbufs = length / blks_per_cluster;
 
        /*
         * Figure out what version number to use in the inodes we create.  If
@@ -225,7 +218,7 @@ xfs_ialloc_inode_init(
                 * they track in the AIL as if they were physically logged.
                 */
                if (tp)
-                       xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp),
+                       xfs_icreate_log(tp, agno, agbno, mp->m_ialloc_inos,
                                        mp->m_sb.sb_inodesize, length, gen);
        } else if (xfs_sb_version_hasnlink(&mp->m_sb))
                version = 2;
@@ -246,7 +239,7 @@ xfs_ialloc_inode_init(
                /* Initialize the inode buffers and log them appropriately. */
                fbuf->b_ops = &xfs_inode_buf_ops;
                xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
-               for (i = 0; i < ninodes; i++) {
+               for (i = 0; i < inodes_per_cluster; i++) {
                        int     ioffset = i << mp->m_sb.sb_inodelog;
                        uint    isize = xfs_dinode_size(version);
 
@@ -329,11 +322,11 @@ xfs_ialloc_ag_alloc(
         * Locking will ensure that we don't have two callers in here
         * at one time.
         */
-       newlen = XFS_IALLOC_INODES(args.mp);
+       newlen = args.mp->m_ialloc_inos;
        if (args.mp->m_maxicount &&
            args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount)
                return XFS_ERROR(ENOSPC);
-       args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
+       args.minlen = args.maxlen = args.mp->m_ialloc_blks;
        /*
         * First try to allocate inodes contiguous with the last-allocated
         * chunk of inodes.  If the filesystem is striped, this will fill
@@ -343,7 +336,7 @@ xfs_ialloc_ag_alloc(
        newino = be32_to_cpu(agi->agi_newino);
        agno = be32_to_cpu(agi->agi_seqno);
        args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
-                       XFS_IALLOC_BLOCKS(args.mp);
+                    args.mp->m_ialloc_blks;
        if (likely(newino != NULLAGINO &&
                  (args.agbno < be32_to_cpu(agi->agi_length)))) {
                args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
@@ -585,7 +578,7 @@ xfs_ialloc_ag_select(
                 * Is there enough free space for the file plus a block of
                 * inodes? (if we need to allocate some)?
                 */
-               ineed = XFS_IALLOC_BLOCKS(mp);
+               ineed = mp->m_ialloc_blks;
                longest = pag->pagf_longest;
                if (!longest)
                        longest = pag->pagf_flcount > 0;
@@ -999,7 +992,7 @@ xfs_dialloc(
         * inode.
         */
        if (mp->m_maxicount &&
-           mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) {
+           mp->m_sb.sb_icount + mp->m_ialloc_inos > mp->m_maxicount) {
                noroom = 1;
                okalloc = 0;
        }
@@ -1202,7 +1195,7 @@ xfs_difree(
         * When an inode cluster is free, it becomes eligible for removal
         */
        if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
-           (rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
+           (rec.ir_freecount == mp->m_ialloc_inos)) {
 
                *delete = 1;
                *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
@@ -1212,7 +1205,7 @@ xfs_difree(
                 * AGI and Superblock inode counts, and mark the disk space
                 * to be freed when the transaction is committed.
                 */
-               ilen = XFS_IALLOC_INODES(mp);
+               ilen = mp->m_ialloc_inos;
                be32_add_cpu(&agi->agi_count, -ilen);
                be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
                xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
@@ -1228,9 +1221,9 @@ xfs_difree(
                        goto error0;
                }
 
-               xfs_bmap_add_free(XFS_AGB_TO_FSB(mp,
-                               agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)),
-                               XFS_IALLOC_BLOCKS(mp), flist, mp);
+               xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, agno,
+                                 XFS_AGINO_TO_AGBNO(mp, rec.ir_startino)),
+                                 mp->m_ialloc_blks, flist, mp);
        } else {
                *delete = 0;
 
@@ -1311,7 +1304,7 @@ xfs_imap_lookup(
 
        /* check that the returned record contains the required inode */
        if (rec.ir_startino > agino ||
-           rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino)
+           rec.ir_startino + mp->m_ialloc_inos <= agino)
                return EINVAL;
 
        /* for untrusted inodes check it is allocated first */
@@ -1384,7 +1377,7 @@ xfs_imap(
                return XFS_ERROR(EINVAL);
        }
 
-       blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
+       blks_per_cluster = xfs_icluster_size_fsb(mp);
 
        /*
         * For bulkstat and handle lookups, we have an untrusted inode number
@@ -1405,7 +1398,7 @@ xfs_imap(
         * If the inode cluster size is the same as the blocksize or
         * smaller we get to the buffer by simple arithmetics.
         */
-       if (XFS_INODE_CLUSTER_SIZE(mp) <= mp->m_sb.sb_blocksize) {
+       if (blks_per_cluster == 1) {
                offset = XFS_INO_TO_OFFSET(mp, ino);
                ASSERT(offset < mp->m_sb.sb_inopblock);
 
index a8f76a5ff4184b316c53b78cb22445006926e90f..812365d17e672d5a79b34ffac2550202c095b0f2 100644 (file)
@@ -25,17 +25,18 @@ struct xfs_mount;
 struct xfs_trans;
 struct xfs_btree_cur;
 
-/*
- * Allocation parameters for inode allocation.
- */
-#define        XFS_IALLOC_INODES(mp)   (mp)->m_ialloc_inos
-#define        XFS_IALLOC_BLOCKS(mp)   (mp)->m_ialloc_blks
-
-/*
- * Move inodes in clusters of this size.
- */
+/* Move inodes in clusters of this size */
 #define        XFS_INODE_BIG_CLUSTER_SIZE      8192
-#define        XFS_INODE_CLUSTER_SIZE(mp)      (mp)->m_inode_cluster_size
+
+/* Calculate and return the number of filesystem blocks per inode cluster */
+static inline int
+xfs_icluster_size_fsb(
+       struct xfs_mount        *mp)
+{
+       if (mp->m_sb.sb_blocksize >= mp->m_inode_cluster_size)
+               return 1;
+       return mp->m_inode_cluster_size >> mp->m_sb.sb_blocklog;
+}
 
 /*
  * Make an inode pointer out of the buffer/offset.
index d2eaccfa73f4b14c622e66b39787396433e87604..7e4549233251e06332f40fede7007574b92b4f9a 100644 (file)
@@ -28,6 +28,7 @@
 #include "xfs_trans_priv.h"
 #include "xfs_error.h"
 #include "xfs_icreate_item.h"
+#include "xfs_log.h"
 
 kmem_zone_t    *xfs_icreate_zone;              /* inode create item zone */
 
@@ -58,13 +59,14 @@ xfs_icreate_item_size(
 STATIC void
 xfs_icreate_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *log_vector)
+       struct xfs_log_vec      *lv)
 {
        struct xfs_icreate_item *icp = ICR_ITEM(lip);
+       struct xfs_log_iovec    *vecp = NULL;
 
-       log_vector->i_addr = (xfs_caddr_t)&icp->ic_format;
-       log_vector->i_len  = sizeof(struct xfs_icreate_log);
-       log_vector->i_type = XLOG_REG_TYPE_ICREATE;
+       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICREATE,
+                       &icp->ic_format,
+                       sizeof(struct xfs_icreate_log));
 }
 
 
index 001aa893ed594020d76bc30cdffb05dfeaa24371..3a137e9f9a7dac3fb72f1687bf086b1273d83890 100644 (file)
@@ -77,48 +77,44 @@ xfs_get_extsz_hint(
 }
 
 /*
- * This is a wrapper routine around the xfs_ilock() routine used to centralize
- * some grungy code.  It is used in places that wish to lock the inode solely
- * for reading the extents.  The reason these places can't just call
- * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the
- * extents from disk for a file in b-tree format.  If the inode is in b-tree
- * format, then we need to lock the inode exclusively until the extents are read
- * in.  Locking it exclusively all the time would limit our parallelism
- * unnecessarily, though.  What we do instead is check to see if the extents
- * have been read in yet, and only lock the inode exclusively if they have not.
+ * These two are wrapper routines around the xfs_ilock() routine used to
+ * centralize some grungy code.  They are used in places that wish to lock the
+ * inode solely for reading the extents.  The reason these places can't just
+ * call xfs_ilock(ip, XFS_ILOCK_SHARED) is that the inode lock also guards to
+ * bringing in of the extents from disk for a file in b-tree format.  If the
+ * inode is in b-tree format, then we need to lock the inode exclusively until
+ * the extents are read in.  Locking it exclusively all the time would limit
+ * our parallelism unnecessarily, though.  What we do instead is check to see
+ * if the extents have been read in yet, and only lock the inode exclusively
+ * if they have not.
  *
- * The function returns a value which should be given to the corresponding
- * xfs_iunlock_map_shared().  This value is the mode in which the lock was
- * actually taken.
+ * The functions return a value which should be given to the corresponding
+ * xfs_iunlock() call.
  */
 uint
-xfs_ilock_map_shared(
-       xfs_inode_t     *ip)
+xfs_ilock_data_map_shared(
+       struct xfs_inode        *ip)
 {
-       uint    lock_mode;
+       uint                    lock_mode = XFS_ILOCK_SHARED;
 
-       if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) &&
-           ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) {
+       if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
+           (ip->i_df.if_flags & XFS_IFEXTENTS) == 0)
                lock_mode = XFS_ILOCK_EXCL;
-       } else {
-               lock_mode = XFS_ILOCK_SHARED;
-       }
-
        xfs_ilock(ip, lock_mode);
-
        return lock_mode;
 }
 
-/*
- * This is simply the unlock routine to go with xfs_ilock_map_shared().
- * All it does is call xfs_iunlock() with the given lock_mode.
- */
-void
-xfs_iunlock_map_shared(
-       xfs_inode_t     *ip,
-       unsigned int    lock_mode)
+uint
+xfs_ilock_attr_map_shared(
+       struct xfs_inode        *ip)
 {
-       xfs_iunlock(ip, lock_mode);
+       uint                    lock_mode = XFS_ILOCK_SHARED;
+
+       if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE &&
+           (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0)
+               lock_mode = XFS_ILOCK_EXCL;
+       xfs_ilock(ip, lock_mode);
+       return lock_mode;
 }
 
 /*
@@ -588,9 +584,9 @@ xfs_lookup(
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return XFS_ERROR(EIO);
 
-       lock_mode = xfs_ilock_map_shared(dp);
+       lock_mode = xfs_ilock_data_map_shared(dp);
        error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
-       xfs_iunlock_map_shared(dp, lock_mode);
+       xfs_iunlock(dp, lock_mode);
 
        if (error)
                goto out;
@@ -2141,8 +2137,8 @@ xfs_ifree_cluster(
 {
        xfs_mount_t             *mp = free_ip->i_mount;
        int                     blks_per_cluster;
+       int                     inodes_per_cluster;
        int                     nbufs;
-       int                     ninodes;
        int                     i, j;
        xfs_daddr_t             blkno;
        xfs_buf_t               *bp;
@@ -2152,18 +2148,11 @@ xfs_ifree_cluster(
        struct xfs_perag        *pag;
 
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
-       if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
-               blks_per_cluster = 1;
-               ninodes = mp->m_sb.sb_inopblock;
-               nbufs = XFS_IALLOC_BLOCKS(mp);
-       } else {
-               blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
-                                       mp->m_sb.sb_blocksize;
-               ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
-               nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster;
-       }
+       blks_per_cluster = xfs_icluster_size_fsb(mp);
+       inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
+       nbufs = mp->m_ialloc_blks / blks_per_cluster;
 
-       for (j = 0; j < nbufs; j++, inum += ninodes) {
+       for (j = 0; j < nbufs; j++, inum += inodes_per_cluster) {
                blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
                                         XFS_INO_TO_AGBNO(mp, inum));
 
@@ -2225,7 +2214,7 @@ xfs_ifree_cluster(
                 * transaction stale above, which means there is no point in
                 * even trying to lock them.
                 */
-               for (i = 0; i < ninodes; i++) {
+               for (i = 0; i < inodes_per_cluster; i++) {
 retry:
                        rcu_read_lock();
                        ip = radix_tree_lookup(&pag->pag_ici_root,
@@ -2906,13 +2895,13 @@ xfs_iflush_cluster(
 
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
 
-       inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog;
+       inodes_per_cluster = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
        ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
        ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
        if (!ilist)
                goto out_put;
 
-       mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
+       mask = ~(((mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog)) - 1);
        first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask;
        rcu_read_lock();
        /* really need a gang lookup range call here */
index 9e6efccbae04f23f86581767e09f61304dc55ac4..65e2350f449c9c4c086b8e6cd0de1f07f82c7fc8 100644 (file)
@@ -337,8 +337,8 @@ int         xfs_ilock_nowait(xfs_inode_t *, uint);
 void           xfs_iunlock(xfs_inode_t *, uint);
 void           xfs_ilock_demote(xfs_inode_t *, uint);
 int            xfs_isilocked(xfs_inode_t *, uint);
-uint           xfs_ilock_map_shared(xfs_inode_t *);
-void           xfs_iunlock_map_shared(xfs_inode_t *, uint);
+uint           xfs_ilock_data_map_shared(struct xfs_inode *);
+uint           xfs_ilock_attr_map_shared(struct xfs_inode *);
 int            xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t,
                           xfs_nlink_t, xfs_dev_t, prid_t, int,
                           struct xfs_buf **, xfs_inode_t **);
index cfee14a83cfe601d90bdc6732cc608746aaf3e03..73514c0486b710fdfcbcc53a2a5683498cf782fc 100644 (file)
@@ -431,6 +431,8 @@ xfs_iread_extents(
        xfs_ifork_t     *ifp;
        xfs_extnum_t    nextents;
 
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
        if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
                XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
                                 ip->i_mount);
@@ -721,15 +723,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 7c0d391f9a6e0bd3f4f6a72cc6f0e65323cc7183..686889b4a1e5d8211e895a1384aadf6faa7de697 100644 (file)
@@ -30,6 +30,7 @@
 #include "xfs_trace.h"
 #include "xfs_trans_priv.h"
 #include "xfs_dinode.h"
+#include "xfs_log.h"
 
 
 kmem_zone_t    *xfs_ili_zone;          /* inode log item zone */
@@ -39,27 +40,14 @@ static inline struct xfs_inode_log_item *INODE_ITEM(struct xfs_log_item *lip)
        return container_of(lip, struct xfs_inode_log_item, ili_item);
 }
 
-
-/*
- * This returns the number of iovecs needed to log the given inode item.
- *
- * We need one iovec for the inode log format structure, one for the
- * inode core, and possibly one for the inode data/extents/b-tree root
- * and one for the inode attribute data/extents/b-tree root.
- */
 STATIC void
-xfs_inode_item_size(
-       struct xfs_log_item     *lip,
+xfs_inode_item_data_fork_size(
+       struct xfs_inode_log_item *iip,
        int                     *nvecs,
        int                     *nbytes)
 {
-       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
 
-       *nvecs += 2;
-       *nbytes += sizeof(struct xfs_inode_log_format) +
-                  xfs_icdinode_size(ip->i_d.di_version);
-
        switch (ip->i_d.di_format) {
        case XFS_DINODE_FMT_EXTENTS:
                if ((iip->ili_fields & XFS_ILOG_DEXT) &&
@@ -70,7 +58,6 @@ xfs_inode_item_size(
                        *nvecs += 1;
                }
                break;
-
        case XFS_DINODE_FMT_BTREE:
                if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
                    ip->i_df.if_broot_bytes > 0) {
@@ -78,7 +65,6 @@ xfs_inode_item_size(
                        *nvecs += 1;
                }
                break;
-
        case XFS_DINODE_FMT_LOCAL:
                if ((iip->ili_fields & XFS_ILOG_DDATA) &&
                    ip->i_df.if_bytes > 0) {
@@ -90,19 +76,20 @@ xfs_inode_item_size(
        case XFS_DINODE_FMT_DEV:
        case XFS_DINODE_FMT_UUID:
                break;
-
        default:
                ASSERT(0);
                break;
        }
+}
 
-       if (!XFS_IFORK_Q(ip))
-               return;
-
+STATIC void
+xfs_inode_item_attr_fork_size(
+       struct xfs_inode_log_item *iip,
+       int                     *nvecs,
+       int                     *nbytes)
+{
+       struct xfs_inode        *ip = iip->ili_inode;
 
-       /*
-        * Log any necessary attribute data.
-        */
        switch (ip->i_d.di_aformat) {
        case XFS_DINODE_FMT_EXTENTS:
                if ((iip->ili_fields & XFS_ILOG_AEXT) &&
@@ -113,7 +100,6 @@ xfs_inode_item_size(
                        *nvecs += 1;
                }
                break;
-
        case XFS_DINODE_FMT_BTREE:
                if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
                    ip->i_afp->if_broot_bytes > 0) {
@@ -121,7 +107,6 @@ xfs_inode_item_size(
                        *nvecs += 1;
                }
                break;
-
        case XFS_DINODE_FMT_LOCAL:
                if ((iip->ili_fields & XFS_ILOG_ADATA) &&
                    ip->i_afp->if_bytes > 0) {
@@ -129,7 +114,6 @@ xfs_inode_item_size(
                        *nvecs += 1;
                }
                break;
-
        default:
                ASSERT(0);
                break;
@@ -137,98 +121,67 @@ xfs_inode_item_size(
 }
 
 /*
- * 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.
+ * This returns the number of iovecs needed to log the given inode item.
  *
- * 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.
+ * We need one iovec for the inode log format structure, one for the
+ * inode core, and possibly one for the inode data/extents/b-tree root
+ * and one for the inode attribute data/extents/b-tree root.
  */
 STATIC void
-xfs_inode_item_format_extents(
-       struct xfs_inode        *ip,
-       struct xfs_log_iovec    *vecp,
-       int                     whichfork,
-       int                     type)
+xfs_inode_item_size(
+       struct xfs_log_item     *lip,
+       int                     *nvecs,
+       int                     *nbytes)
 {
-       xfs_bmbt_rec_t          *ext_buffer;
+       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+       struct xfs_inode        *ip = iip->ili_inode;
 
-       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;
+       *nvecs += 2;
+       *nbytes += sizeof(struct xfs_inode_log_format) +
+                  xfs_icdinode_size(ip->i_d.di_version);
 
-       vecp->i_addr = ext_buffer;
-       vecp->i_len = xfs_iextents_copy(ip, ext_buffer, whichfork);
-       vecp->i_type = type;
+       xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
+       if (XFS_IFORK_Q(ip))
+               xfs_inode_item_attr_fork_size(iip, nvecs, nbytes);
 }
 
 /*
- * This is called to fill in the vector of log iovecs for the
- * given inode log item.  It fills the first item with an inode
- * log format structure, the second with the on-disk inode structure,
- * and a possible third and/or fourth with the inode data/extents/b-tree
- * root and inode attributes data/extents/b-tree root.
+ * 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
+ * don't have to worry about the new fields, because nothing trusts them as
+ * long as the old inode version number is there.
  */
 STATIC void
-xfs_inode_item_format(
-       struct xfs_log_item     *lip,
-       struct xfs_log_iovec    *vecp)
+xfs_inode_item_format_v1_inode(
+       struct xfs_inode        *ip)
+{
+       if (!xfs_sb_version_hasnlink(&ip->i_mount->m_sb)) {
+               /*
+                * Convert it back.
+                */
+               ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
+               ip->i_d.di_onlink = ip->i_d.di_nlink;
+       } else {
+               /*
+                * The superblock version has already been bumped,
+                * so just make the conversion to the new inode
+                * format permanent.
+                */
+               ip->i_d.di_version = 2;
+               ip->i_d.di_onlink = 0;
+               memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
+       }
+}
+
+STATIC void
+xfs_inode_item_format_data_fork(
+       struct xfs_inode_log_item *iip,
+       struct xfs_inode_log_format *ilf,
+       struct xfs_log_vec      *lv,
+       struct xfs_log_iovec    **vecp)
 {
-       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
-       uint                    nvecs;
        size_t                  data_bytes;
-       xfs_mount_t             *mp;
-
-       vecp->i_addr = &iip->ili_format;
-       vecp->i_len  = sizeof(xfs_inode_log_format_t);
-       vecp->i_type = XLOG_REG_TYPE_IFORMAT;
-       vecp++;
-       nvecs        = 1;
-
-       vecp->i_addr = &ip->i_d;
-       vecp->i_len  = xfs_icdinode_size(ip->i_d.di_version);
-       vecp->i_type = XLOG_REG_TYPE_ICORE;
-       vecp++;
-       nvecs++;
-
-       /*
-        * If this is really an old 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 don't have to worry
-        * about the new fields, because nothing trusts them as long as
-        * the old inode version number is there.  If the superblock already
-        * has a new version number, then we don't bother converting back.
-        */
-       mp = ip->i_mount;
-       ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb));
-       if (ip->i_d.di_version == 1) {
-               if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
-                       /*
-                        * Convert it back.
-                        */
-                       ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
-                       ip->i_d.di_onlink = ip->i_d.di_nlink;
-               } else {
-                       /*
-                        * The superblock version has already been bumped,
-                        * so just make the conversion to the new inode
-                        * format permanent.
-                        */
-                       ip->i_d.di_version = 2;
-                       ip->i_d.di_onlink = 0;
-                       memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
-               }
-       }
 
        switch (ip->i_d.di_format) {
        case XFS_DINODE_FMT_EXTENTS:
@@ -239,36 +192,23 @@ xfs_inode_item_format(
                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.
-                                */
-                               vecp->i_addr = ip->i_df.if_u1.if_extents;
-                               vecp->i_len = ip->i_df.if_bytes;
-                               vecp->i_type = XLOG_REG_TYPE_IEXT;
-                       } else
-#endif
-                       {
-                               xfs_inode_item_format_extents(ip, vecp,
-                                       XFS_DATA_FORK, XLOG_REG_TYPE_IEXT);
-                       }
-                       ASSERT(vecp->i_len <= ip->i_df.if_bytes);
-                       iip->ili_format.ilf_dsize = vecp->i_len;
-                       vecp++;
-                       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;
                }
                break;
-
        case XFS_DINODE_FMT_BTREE:
                iip->ili_fields &=
                        ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
@@ -277,80 +217,70 @@ xfs_inode_item_format(
                if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
                    ip->i_df.if_broot_bytes > 0) {
                        ASSERT(ip->i_df.if_broot != NULL);
-                       vecp->i_addr = ip->i_df.if_broot;
-                       vecp->i_len = ip->i_df.if_broot_bytes;
-                       vecp->i_type = XLOG_REG_TYPE_IBROOT;
-                       vecp++;
-                       nvecs++;
-                       iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
+                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT,
+                                       ip->i_df.if_broot,
+                                       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));
                        iip->ili_fields &= ~XFS_ILOG_DBROOT;
                }
                break;
-
        case XFS_DINODE_FMT_LOCAL:
                iip->ili_fields &=
                        ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
                          XFS_ILOG_DEV | XFS_ILOG_UUID);
                if ((iip->ili_fields & XFS_ILOG_DDATA) &&
                    ip->i_df.if_bytes > 0) {
-                       ASSERT(ip->i_df.if_u1.if_data != NULL);
-                       ASSERT(ip->i_d.di_size > 0);
-
-                       vecp->i_addr = ip->i_df.if_u1.if_data;
                        /*
                         * Round i_bytes up to a word boundary.
                         * The underlying memory is guaranteed to
                         * to be there by xfs_idata_realloc().
                         */
                        data_bytes = roundup(ip->i_df.if_bytes, 4);
-                       ASSERT((ip->i_df.if_real_bytes == 0) ||
-                              (ip->i_df.if_real_bytes == data_bytes));
-                       vecp->i_len = (int)data_bytes;
-                       vecp->i_type = XLOG_REG_TYPE_ILOCAL;
-                       vecp++;
-                       nvecs++;
-                       iip->ili_format.ilf_dsize = (unsigned)data_bytes;
+                       ASSERT(ip->i_df.if_real_bytes == 0 ||
+                              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(lv, vecp, XLOG_REG_TYPE_ILOCAL,
+                                       ip->i_df.if_u1.if_data, data_bytes);
+                       ilf->ilf_dsize = (unsigned)data_bytes;
+                       ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_DDATA;
                }
                break;
-
        case XFS_DINODE_FMT_DEV:
                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);
                break;
        }
+}
 
-       /*
-        * If there are no attributes associated with the file, then we're done.
-        */
-       if (!XFS_IFORK_Q(ip)) {
-               iip->ili_fields &=
-                       ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
-               goto out;
-       }
+STATIC void
+xfs_inode_item_format_attr_fork(
+       struct xfs_inode_log_item *iip,
+       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;
 
        switch (ip->i_d.di_aformat) {
        case XFS_DINODE_FMT_EXTENTS:
@@ -360,30 +290,22 @@ xfs_inode_item_format(
                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.
-                        */
-                       vecp->i_addr = ip->i_afp->if_u1.if_extents;
-                       vecp->i_len = ip->i_afp->if_bytes;
-                       vecp->i_type = XLOG_REG_TYPE_IATTR_EXT;
-#else
-                       ASSERT(iip->ili_aextents_buf == NULL);
-                       xfs_inode_item_format_extents(ip, vecp,
-                                       XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT);
-#endif
-                       iip->ili_format.ilf_asize = vecp->i_len;
-                       vecp++;
-                       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;
                }
                break;
-
        case XFS_DINODE_FMT_BTREE:
                iip->ili_fields &=
                        ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
@@ -392,61 +314,89 @@ xfs_inode_item_format(
                    ip->i_afp->if_broot_bytes > 0) {
                        ASSERT(ip->i_afp->if_broot != NULL);
 
-                       vecp->i_addr = ip->i_afp->if_broot;
-                       vecp->i_len = ip->i_afp->if_broot_bytes;
-                       vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT;
-                       vecp++;
-                       nvecs++;
-                       iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
+                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT,
+                                       ip->i_afp->if_broot,
+                                       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;
                }
                break;
-
        case XFS_DINODE_FMT_LOCAL:
                iip->ili_fields &=
                        ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
 
                if ((iip->ili_fields & XFS_ILOG_ADATA) &&
                    ip->i_afp->if_bytes > 0) {
-                       ASSERT(ip->i_afp->if_u1.if_data != NULL);
-
-                       vecp->i_addr = ip->i_afp->if_u1.if_data;
                        /*
                         * Round i_bytes up to a word boundary.
                         * The underlying memory is guaranteed to
                         * to be there by xfs_idata_realloc().
                         */
                        data_bytes = roundup(ip->i_afp->if_bytes, 4);
-                       ASSERT((ip->i_afp->if_real_bytes == 0) ||
-                              (ip->i_afp->if_real_bytes == data_bytes));
-                       vecp->i_len = (int)data_bytes;
-                       vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL;
-                       vecp++;
-                       nvecs++;
-                       iip->ili_format.ilf_asize = (unsigned)data_bytes;
+                       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(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
+                                       ip->i_afp->if_u1.if_data,
+                                       data_bytes);
+                       ilf->ilf_asize = (unsigned)data_bytes;
+                       ilf->ilf_size++;
                } else {
                        iip->ili_fields &= ~XFS_ILOG_ADATA;
                }
                break;
-
        default:
                ASSERT(0);
                break;
        }
-
-out:
-       /*
-        * 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;
 }
 
+/*
+ * This is called to fill in the vector of log iovecs for the given inode
+ * log item.  It fills the first item with an inode log format structure,
+ * the second with the on-disk inode structure, and a possible third and/or
+ * fourth with the inode data/extents/b-tree root and inode attributes
+ * data/extents/b-tree root.
+ */
+STATIC void
+xfs_inode_item_format(
+       struct xfs_log_item     *lip,
+       struct xfs_log_vec      *lv)
+{
+       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+       struct xfs_inode        *ip = iip->ili_inode;
+       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, ilf, lv, &vecp);
+       if (XFS_IFORK_Q(ip)) {
+               xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
+       } else {
+               iip->ili_fields &=
+                       ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
+       }
+
+       /* update the format with the exact fields we actually logged */
+       ilf->ilf_fields |= (iip->ili_fields & ~XFS_ILOG_TIMESTAMP);
+}
 
 /*
  * This is called to pin the inode associated with the inode log
@@ -563,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)
@@ -670,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;
 }
 
 /*
index dce4d656768c32888521dc0c9007c6c2961b7c4e..488d81254e28a73e26fba494fd89d21139415ac6 100644 (file)
@@ -34,11 +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;
 
 static inline int xfs_inode_clean(xfs_inode_t *ip)
index 33ad9a77791f7ebbf3f8762e0c9df1af637c5328..518aa56b8f2e46d1602bb800c03f5c3d06b9fb38 100644 (file)
@@ -112,15 +112,11 @@ xfs_find_handle(
                memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
                hsize = sizeof(xfs_fsid_t);
        } else {
-               int             lock_mode;
-
-               lock_mode = xfs_ilock_map_shared(ip);
                handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
                                        sizeof(handle.ha_fid.fid_len);
                handle.ha_fid.fid_pad = 0;
                handle.ha_fid.fid_gen = ip->i_d.di_gen;
                handle.ha_fid.fid_ino = ip->i_ino;
-               xfs_iunlock_map_shared(ip, lock_mode);
 
                hsize = XFS_HSIZE(handle);
        }
index 104455b8046c4bd9ea11855c917b7b46c4573361..0ce1d759156e48ae092d566d30e713d7e597f29c 100644 (file)
@@ -459,14 +459,12 @@ xfs_vn_getattr(
 
 static void
 xfs_setattr_mode(
-       struct xfs_trans        *tp,
        struct xfs_inode        *ip,
        struct iattr            *iattr)
 {
-       struct inode    *inode = VFS_I(ip);
-       umode_t         mode = iattr->ia_mode;
+       struct inode            *inode = VFS_I(ip);
+       umode_t                 mode = iattr->ia_mode;
 
-       ASSERT(tp);
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
        ip->i_d.di_mode &= S_IFMT;
@@ -476,6 +474,32 @@ xfs_setattr_mode(
        inode->i_mode |= mode & ~S_IFMT;
 }
 
+static void
+xfs_setattr_time(
+       struct xfs_inode        *ip,
+       struct iattr            *iattr)
+{
+       struct inode            *inode = VFS_I(ip);
+
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+       if (iattr->ia_valid & ATTR_ATIME) {
+               inode->i_atime = iattr->ia_atime;
+               ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
+               ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
+       }
+       if (iattr->ia_valid & ATTR_CTIME) {
+               inode->i_ctime = iattr->ia_ctime;
+               ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
+               ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
+       }
+       if (iattr->ia_valid & ATTR_MTIME) {
+               inode->i_mtime = iattr->ia_mtime;
+               ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
+               ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
+       }
+}
+
 int
 xfs_setattr_nonsize(
        struct xfs_inode        *ip,
@@ -630,30 +654,10 @@ xfs_setattr_nonsize(
                }
        }
 
-       /*
-        * Change file access modes.
-        */
        if (mask & ATTR_MODE)
-               xfs_setattr_mode(tp, ip, iattr);
-
-       /*
-        * Change file access or modified times.
-        */
-       if (mask & ATTR_ATIME) {
-               inode->i_atime = iattr->ia_atime;
-               ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
-               ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
-       }
-       if (mask & ATTR_CTIME) {
-               inode->i_ctime = iattr->ia_ctime;
-               ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
-               ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
-       }
-       if (mask & ATTR_MTIME) {
-               inode->i_mtime = iattr->ia_mtime;
-               ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
-               ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
-       }
+               xfs_setattr_mode(ip, iattr);
+       if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
+               xfs_setattr_time(ip, iattr);
 
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
@@ -868,22 +872,10 @@ xfs_setattr_size(
                xfs_inode_clear_eofblocks_tag(ip);
        }
 
-       /*
-        * Change file access modes.
-        */
        if (mask & ATTR_MODE)
-               xfs_setattr_mode(tp, ip, iattr);
-
-       if (mask & ATTR_CTIME) {
-               inode->i_ctime = iattr->ia_ctime;
-               ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
-               ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
-       }
-       if (mask & ATTR_MTIME) {
-               inode->i_mtime = iattr->ia_mtime;
-               ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
-               ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
-       }
+               xfs_setattr_mode(ip, iattr);
+       if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
+               xfs_setattr_time(ip, iattr);
 
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
index c237ad15d500f767b81014a428720a7351431077..f463382851524204edd37f9fd67c7e42efbcf9d9 100644 (file)
@@ -209,9 +209,8 @@ xfs_bulkstat(
        xfs_inobt_rec_incore_t  *irbuf; /* start of irec buffer */
        xfs_inobt_rec_incore_t  *irbufend; /* end of good irec buffer entries */
        xfs_ino_t               lastino; /* last inode number returned */
-       int                     nbcluster; /* # of blocks in a cluster */
-       int                     nicluster; /* # of inodes in a cluster */
-       int                     nimask; /* mask for inode clusters */
+       int                     blks_per_cluster; /* # of blocks per cluster */
+       int                     inodes_per_cluster;/* # of inodes per cluster */
        int                     nirbuf; /* size of irbuf */
        int                     rval;   /* return value error code */
        int                     tmp;    /* result value from btree calls */
@@ -243,11 +242,8 @@ xfs_bulkstat(
        *done = 0;
        fmterror = 0;
        ubufp = ubuffer;
-       nicluster = mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp) ?
-               mp->m_sb.sb_inopblock :
-               (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
-       nimask = ~(nicluster - 1);
-       nbcluster = nicluster >> mp->m_sb.sb_inopblog;
+       blks_per_cluster = xfs_icluster_size_fsb(mp);
+       inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
        irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4);
        if (!irbuf)
                return ENOMEM;
@@ -390,12 +386,12 @@ xfs_bulkstat(
                                agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino);
                                for (chunkidx = 0;
                                     chunkidx < XFS_INODES_PER_CHUNK;
-                                    chunkidx += nicluster,
-                                    agbno += nbcluster) {
-                                       if (xfs_inobt_maskn(chunkidx, nicluster)
-                                                       & ~r.ir_free)
+                                    chunkidx += inodes_per_cluster,
+                                    agbno += blks_per_cluster) {
+                                       if (xfs_inobt_maskn(chunkidx,
+                                           inodes_per_cluster) & ~r.ir_free)
                                                xfs_btree_reada_bufs(mp, agno,
-                                                       agbno, nbcluster,
+                                                       agbno, blks_per_cluster,
                                                        &xfs_inode_buf_ops);
                                }
                                blk_finish_plug(&plug);
index e148719e0a5d59dba022034cd5e988ae47552bde..b0f4ef77fa70bd698749e2509e64d79f782fa8aa 100644 (file)
@@ -30,6 +30,52 @@ struct xfs_log_vec {
 
 #define XFS_LOG_VEC_ORDERED    (-1)
 
+static inline void *
+xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
+               uint type)
+{
+       struct xfs_log_iovec *vec = *vecp;
+
+       if (vec) {
+               ASSERT(vec - lv->lv_iovecp < lv->lv_niovecs);
+               vec++;
+       } else {
+               vec = &lv->lv_iovecp[0];
+       }
+
+       vec->i_type = type;
+       vec->i_addr = lv->lv_buf + lv->lv_buf_len;
+
+       ASSERT(IS_ALIGNED((unsigned long)vec->i_addr, sizeof(uint64_t)));
+
+       *vecp = vec;
+       return vec->i_addr;
+}
+
+static inline void
+xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len)
+{
+       /*
+        * We need to make sure the next buffer is naturally aligned for the
+        * biggest basic data type we put into it.  We already accounted for
+        * this when sizing the buffer.
+        */
+       lv->lv_buf_len += round_up(len, sizeof(uint64_t));
+       vec->i_len = len;
+}
+
+static inline void *
+xlog_copy_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
+               uint type, void *data, int len)
+{
+       void *buf;
+
+       buf = xlog_prepare_iovec(lv, vecp, type);
+       memcpy(buf, data, len);
+       xlog_finish_iovec(lv, *vecp, len);
+       return buf;
+}
+
 /*
  * Structure used to pass callback function and the function's argument
  * to the log manager.
index 5eb51fc5eb844f2553e5a2d4711c9a32a74bdd18..cdebd832c3dba1fcd937869d1cedcebe09113c25 100644 (file)
@@ -82,36 +82,6 @@ xlog_cil_init_post_recovery(
                                                                log->l_curr_block);
 }
 
-STATIC int
-xlog_cil_lv_item_format(
-       struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
-{
-       int     index;
-       char    *ptr;
-
-       /* format new vectors into array */
-       lip->li_ops->iop_format(lip, lv->lv_iovecp);
-
-       /* copy data into existing array */
-       ptr = lv->lv_buf;
-       for (index = 0; index < lv->lv_niovecs; index++) {
-               struct xfs_log_iovec *vec = &lv->lv_iovecp[index];
-
-               memcpy(ptr, vec->i_addr, vec->i_len);
-               vec->i_addr = ptr;
-               ptr += vec->i_len;
-       }
-
-       /*
-        * some size calculations for log vectors over-estimate, so the caller
-        * doesn't know the amount of space actually used by the item. Return
-        * the byte count to the caller so they can check and store it
-        * appropriately.
-        */
-       return ptr - lv->lv_buf;
-}
-
 /*
  * Prepare the log item for insertion into the CIL. Calculate the difference in
  * log space and vectors it will consume, and if it is a new item pin it as
@@ -232,6 +202,13 @@ xlog_cil_insert_format_items(
                        nbytes = 0;
                }
 
+               /*
+                * We 64-bit align the length of each iovec so that the start
+                * of the next one is naturally aligned.  We'll need to
+                * account for that slack space here.
+                */
+               nbytes += niovecs * sizeof(uint64_t);
+
                /* grab the old item if it exists for reservation accounting */
                old_lv = lip->li_lv;
 
@@ -254,34 +231,27 @@ xlog_cil_insert_format_items(
                         */
                        *diff_iovecs -= lv->lv_niovecs;
                        *diff_len -= lv->lv_buf_len;
-
-                       /* Ensure the lv is set up according to ->iop_size */
-                       lv->lv_niovecs = niovecs;
-                       lv->lv_buf = (char *)lv + buf_size - nbytes;
-
-                       lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv);
-                       goto insert;
+               } else {
+                       /* allocate new data chunk */
+                       lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS);
+                       lv->lv_item = lip;
+                       lv->lv_size = buf_size;
+                       if (ordered) {
+                               /* track as an ordered logvec */
+                               ASSERT(lip->li_lv == NULL);
+                               lv->lv_buf_len = XFS_LOG_VEC_ORDERED;
+                               goto insert;
+                       }
+                       lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1];
                }
 
-               /* allocate new data chunk */
-               lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS);
-               lv->lv_item = lip;
-               lv->lv_size = buf_size;
+               /* Ensure the lv is set up according to ->iop_size */
                lv->lv_niovecs = niovecs;
-               if (ordered) {
-                       /* track as an ordered logvec */
-                       ASSERT(lip->li_lv == NULL);
-                       lv->lv_buf_len = XFS_LOG_VEC_ORDERED;
-                       goto insert;
-               }
-
-               /* The allocated iovec region lies beyond the log vector. */
-               lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1];
 
                /* The allocated data region lies beyond the iovec region */
+               lv->lv_buf_len = 0;
                lv->lv_buf = (char *)lv + buf_size - nbytes;
-
-               lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv);
+               lip->li_ops->iop_format(lip, lv);
 insert:
                ASSERT(lv->lv_buf_len <= nbytes);
                xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs);
index eae16920655b4569af25e9567682019ba301533d..bce53ac81096afc3e559a7317c149918290bab34 100644 (file)
@@ -1654,6 +1654,7 @@ xlog_recover_reorder_trans(
        int                     pass)
 {
        xlog_recover_item_t     *item, *n;
+       int                     error = 0;
        LIST_HEAD(sort_list);
        LIST_HEAD(cancel_list);
        LIST_HEAD(buffer_list);
@@ -1695,9 +1696,17 @@ xlog_recover_reorder_trans(
                                "%s: unrecognized type of log operation",
                                __func__);
                        ASSERT(0);
-                       return XFS_ERROR(EIO);
+                       /*
+                        * return the remaining items back to the transaction
+                        * item list so they can be freed in caller.
+                        */
+                       if (!list_empty(&sort_list))
+                               list_splice_init(&sort_list, &trans->r_itemq);
+                       error = XFS_ERROR(EIO);
+                       goto out;
                }
        }
+out:
        ASSERT(list_empty(&sort_list));
        if (!list_empty(&buffer_list))
                list_splice(&buffer_list, &trans->r_itemq);
@@ -1707,7 +1716,7 @@ xlog_recover_reorder_trans(
                list_splice_tail(&inode_buffer_list, &trans->r_itemq);
        if (!list_empty(&cancel_list))
                list_splice_tail(&cancel_list, &trans->r_itemq);
-       return 0;
+       return error;
 }
 
 /*
@@ -2517,19 +2526,19 @@ xlog_recover_buffer_pass2(
         *
         * Also make sure that only inode buffers with good sizes stay in
         * the buffer cache.  The kernel moves inodes in buffers of 1 block
-        * or XFS_INODE_CLUSTER_SIZE bytes, whichever is bigger.  The inode
+        * or mp->m_inode_cluster_size bytes, whichever is bigger.  The inode
         * buffers in the log can be a different size if the log was generated
         * by an older kernel using unclustered inode buffers or a newer kernel
         * running with a different inode cluster size.  Regardless, if the
-        * the inode buffer size isn't MAX(blocksize, XFS_INODE_CLUSTER_SIZE)
-        * for *our* value of XFS_INODE_CLUSTER_SIZE, then we need to keep
+        * the inode buffer size isn't MAX(blocksize, mp->m_inode_cluster_size)
+        * for *our* value of mp->m_inode_cluster_size, then we need to keep
         * the buffer out of the buffer cache so that the buffer won't
         * overlap with future reads of those inodes.
         */
        if (XFS_DINODE_MAGIC ==
            be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) &&
            (BBTOB(bp->b_io_length) != MAX(log->l_mp->m_sb.sb_blocksize,
-                       (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) {
+                       (__uint32_t)log->l_mp->m_inode_cluster_size))) {
                xfs_buf_stale(bp);
                error = xfs_bwrite(bp);
        } else {
@@ -3202,10 +3211,10 @@ xlog_recover_do_icreate_pass2(
        }
 
        /* existing allocation is fixed value */
-       ASSERT(count == XFS_IALLOC_INODES(mp));
-       ASSERT(length == XFS_IALLOC_BLOCKS(mp));
-       if (count != XFS_IALLOC_INODES(mp) ||
-            length != XFS_IALLOC_BLOCKS(mp)) {
+       ASSERT(count == mp->m_ialloc_inos);
+       ASSERT(length == mp->m_ialloc_blks);
+       if (count != mp->m_ialloc_inos ||
+            length != mp->m_ialloc_blks) {
                xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count 2");
                return EINVAL;
        }
@@ -3611,8 +3620,10 @@ xlog_recover_process_data(
                                error = XFS_ERROR(EIO);
                                break;
                        }
-                       if (error)
+                       if (error) {
+                               xlog_recover_free_trans(trans);
                                return error;
+                       }
                }
                dp += be32_to_cpu(ohead->oh_len);
                num_logops--;
index dd88f0e27bd8ce1119d2606c256117d4d2488b9c..348e4d2ed6e6e9621b82c535212e32093b51da0c 100644 (file)
@@ -1222,16 +1222,18 @@ xfs_qm_dqiterate(
        lblkno = 0;
        maxlblkcnt = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
        do {
+               uint            lock_mode;
+
                nmaps = XFS_DQITER_MAP_SIZE;
                /*
                 * We aren't changing the inode itself. Just changing
                 * some of its data. No new blocks are added here, and
                 * the inode is never added to the transaction.
                 */
-               xfs_ilock(qip, XFS_ILOCK_SHARED);
+               lock_mode = xfs_ilock_data_map_shared(qip);
                error = xfs_bmapi_read(qip, lblkno, maxlblkcnt - lblkno,
                                       map, &nmaps, 0);
-               xfs_iunlock(qip, XFS_ILOCK_SHARED);
+               xfs_iunlock(qip, lock_mode);
                if (error)
                        break;
 
index a788b66a5cb1c7e73898c877b0c3629eeb8e17a7..797fd4636273657992a1124bff8e5865fe36ba28 100644 (file)
 
 #include "xfs_dquot_item.h"
 #include "xfs_dquot.h"
-#include "xfs_quota_priv.h"
 
 struct xfs_inode;
 
 extern struct kmem_zone        *xfs_qm_dqtrxzone;
 
+/*
+ * Number of bmaps that we ask from bmapi when doing a quotacheck.
+ * We make this restriction to keep the memory usage to a minimum.
+ */
+#define XFS_DQITER_MAP_SIZE    10
+
+#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
+       !dqp->q_core.d_blk_hardlimit && \
+       !dqp->q_core.d_blk_softlimit && \
+       !dqp->q_core.d_rtb_hardlimit && \
+       !dqp->q_core.d_rtb_softlimit && \
+       !dqp->q_core.d_ino_hardlimit && \
+       !dqp->q_core.d_ino_softlimit && \
+       !dqp->q_core.d_bcount && \
+       !dqp->q_core.d_rtbcount && \
+       !dqp->q_core.d_icount)
+
 /*
  * This defines the unit of allocation of dquots.
  * Currently, it is just one file system block, and a 4K blk contains 30
index 437c9198031a49a940aecaa441dc305de0e9a145..3daf5ea1eb8d73989a4e199aaee4dd2364a98290 100644 (file)
@@ -278,7 +278,7 @@ xfs_qm_scall_trunc_qfiles(
        xfs_mount_t     *mp,
        uint            flags)
 {
-       int             error = 0, error2 = 0;
+       int             error;
 
        if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
                xfs_debug(mp, "%s: flags=%x m_qflags=%x",
@@ -286,14 +286,20 @@ xfs_qm_scall_trunc_qfiles(
                return XFS_ERROR(EINVAL);
        }
 
-       if (flags & XFS_DQ_USER)
+       if (flags & XFS_DQ_USER) {
                error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
-       if (flags & XFS_DQ_GROUP)
-               error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
+               if (error)
+                       return error;
+       }
+       if (flags & XFS_DQ_GROUP) {
+               error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
+               if (error)
+                       return error;
+       }
        if (flags & XFS_DQ_PROJ)
-               error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
+               error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
 
-       return error ? error : error2;
+       return error;
 }
 
 /*
diff --git a/fs/xfs/xfs_quota_priv.h b/fs/xfs/xfs_quota_priv.h
deleted file mode 100644 (file)
index 6d86219..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#ifndef __XFS_QUOTA_PRIV_H__
-#define __XFS_QUOTA_PRIV_H__
-
-/*
- * Number of bmaps that we ask from bmapi when doing a quotacheck.
- * We make this restriction to keep the memory usage to a minimum.
- */
-#define XFS_DQITER_MAP_SIZE    10
-
-#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
-       !dqp->q_core.d_blk_hardlimit && \
-       !dqp->q_core.d_blk_softlimit && \
-       !dqp->q_core.d_rtb_hardlimit && \
-       !dqp->q_core.d_rtb_softlimit && \
-       !dqp->q_core.d_ino_hardlimit && \
-       !dqp->q_core.d_ino_softlimit && \
-       !dqp->q_core.d_bcount && \
-       !dqp->q_core.d_rtbcount && \
-       !dqp->q_core.d_icount)
-
-#define DQFLAGTO_TYPESTR(d)    (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
-                                (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
-                                (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
-
-#endif /* __XFS_QUOTA_PRIV_H__ */
index 9b96d35e483de4cb075170aef47db2a1f06a307e..b5bc1ab3c4da0561980333e85a3b0a9aae15322f 100644 (file)
@@ -64,7 +64,7 @@ typedef struct xfs_log_item {
 
 struct xfs_item_ops {
        void (*iop_size)(xfs_log_item_t *, int *, int *);
-       void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
+       void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *);
        void (*iop_pin)(xfs_log_item_t *);
        void (*iop_unpin)(xfs_log_item_t *, int remove);
        uint (*iop_push)(struct xfs_log_item *, struct list_head *);
index cd2a10e15d3ac5520661ed2877f2e5c9cdac48d9..41172861e857bf8c487f7adf3037aad0214b1681 100644 (file)
@@ -295,8 +295,8 @@ xfs_trans_mod_dquot(
 /*
  * Given an array of dqtrx structures, lock all the dquots associated and join
  * them to the transaction, provided they have been modified.  We know that the
- * highest number of dquots of one type - usr, grp OR prj - involved in a
- * transaction is 2 so we don't need to make this very generic.
+ * highest number of dquots of one type - usr, grp and prj - involved in a
+ * transaction is 3 so we don't need to make this very generic.
  */
 STATIC void
 xfs_trans_dqlockedjoin(
index 2fd59c0dae667b58029bad83b56dfad4958e4e0c..2ffd3e331b496ae3f366b6669e3207f15becbd4f 100644 (file)
@@ -174,7 +174,7 @@ xfs_calc_itruncate_reservation(
                    xfs_calc_buf_res(5, 0) +
                    xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
                                     XFS_FSB_TO_B(mp, 1)) +
-                   xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
+                   xfs_calc_buf_res(2 + mp->m_ialloc_blks +
                                     mp->m_in_maxlevels, 0)));
 }
 
@@ -282,7 +282,7 @@ xfs_calc_create_resv_modify(
  * For create we can allocate some inodes giving:
  *    the agi and agf of the ag getting the new inodes: 2 * sectorsize
  *    the superblock for the nlink flag: sector size
- *    the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
+ *    the inode blocks allocated: mp->m_ialloc_blks * blocksize
  *    the inode btree: max depth * blocksize
  *    the allocation btrees: 2 trees * (max depth - 1) * block size
  */
@@ -292,7 +292,7 @@ xfs_calc_create_resv_alloc(
 {
        return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
                mp->m_sb.sb_sectsize +
-               xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
+               xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) +
                xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
                xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
                                 XFS_FSB_TO_B(mp, 1));
@@ -385,9 +385,9 @@ xfs_calc_ifree_reservation(
                xfs_calc_inode_res(mp, 1) +
                xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
                xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
-               max_t(uint, XFS_FSB_TO_B(mp, 1), XFS_INODE_CLUSTER_SIZE(mp)) +
+               max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size) +
                xfs_calc_buf_res(1, 0) +
-               xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
+               xfs_calc_buf_res(2 + mp->m_ialloc_blks +
                                 mp->m_in_maxlevels, 0) +
                xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
                                 XFS_FSB_TO_B(mp, 1));
index 7d2c920dfb9c01e0aac1fdc13576aa8f950bcf7a..af5dbe06cb65886482c522269107853bec4249fb 100644 (file)
@@ -47,7 +47,7 @@
 #define        XFS_DIRREMOVE_SPACE_RES(mp)     \
        XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
 #define        XFS_IALLOC_SPACE_RES(mp)        \
-       (XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1)
+       ((mp)->m_ialloc_blks + (mp)->m_in_maxlevels - 1)
 
 /*
  * Space reservation values for various transactions.
index 3e8e797c6d110ce01b0964a2e3845d8a59defd0b..e8a77383c0d5af630f4c154fa48e4d9ee345d95c 100644 (file)
@@ -34,15 +34,6 @@ struct attrlist_cursor_kern;
        { IO_ISDIRECT,  "DIRECT" }, \
        { IO_INVIS,     "INVIS"}
 
-/*
- * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
- */
-#define FI_NONE                        0       /* none */
-#define FI_REMAPF              1       /* Do a remapf prior to the operation */
-#define FI_REMAPF_LOCKED       2       /* Do a remapf prior to the operation.
-                                          Prevent VM access to the pages until
-                                          the operation completes. */
-
 /*
  * Some useful predicates.
  */