xfs
[Top] [All Lists]

[PATCH 070/102] xfs: reduce ilock hold times in xfs_setattr_size

To: xfs@xxxxxxxxxxx
Subject: [PATCH 070/102] xfs: reduce ilock hold times in xfs_setattr_size
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Thu, 23 Aug 2012 15:02:28 +1000
In-reply-to: <1345698180-13612-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1345698180-13612-1-git-send-email-david@xxxxxxxxxxxxx>
From: Christoph Hellwig <hch@xxxxxxxxxxxxx>

Upstream commit: f38996f5768713fb60e1d2de66c097367d54bb6a

We do not need the ilock for most checks done in the beginning of
xfs_setattr_size.  Replace the long critical section before starting the
transaction with a smaller one around xfs_zero_eof and an optional one
inside xfs_qm_dqattach that isn't entered unless using quotas.  While
this isn't a big optimization for xfs_setattr_size itself it will allow
pushing the ilock into xfs_zero_eof itself later.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 fs/xfs/xfs_vnodeops.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0e94d59..b156e46 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -61,7 +61,7 @@ xfs_setattr(
        int                     mask = iattr->ia_valid;
        xfs_trans_t             *tp;
        int                     code;
-       uint                    lock_flags;
+       uint                    lock_flags = 0;
        uint                    commit_flags=0;
        uid_t                   uid=0, iuid=0;
        gid_t                   gid=0, igid=0;
@@ -126,7 +126,7 @@ xfs_setattr(
         */
        tp = NULL;
 restart:
-       lock_flags = XFS_ILOCK_EXCL;
+       lock_flags = 0;
        if (flags & XFS_ATTR_NOLOCK)
                need_iolock = 0;
        if (!(mask & ATTR_SIZE)) {
@@ -139,6 +139,7 @@ restart:
                        lock_flags = 0;
                        goto error_return;
                }
+               lock_flags = XFS_ILOCK_EXCL;
        } else {
                if (need_iolock)
                        lock_flags |= XFS_IOLOCK_EXCL;
@@ -186,8 +187,6 @@ restart:
                /* Short circuit the truncate case for zero length files */
                if (iattr->ia_size == 0 &&
                    old_size == 0 && ip->i_d.di_nextents == 0) {
-                       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-                       lock_flags &= ~XFS_ILOCK_EXCL;
                        if (mask & ATTR_CTIME) {
                                /* need to log timestamp changes */
                                iattr->ia_ctime = iattr->ia_mtime =
@@ -213,7 +212,7 @@ restart:
                /*
                 * Make sure that the dquots are attached to the inode.
                 */
-               code = xfs_qm_dqattach_locked(ip, 0);
+               code = xfs_qm_dqattach(ip, 0);
                if (code)
                        goto error_return;
 
@@ -232,12 +231,12 @@ restart:
                         * need to do this before the inode is joined to the
                         * transaction to modify the i_size.
                         */
+                       xfs_ilock(ip, XFS_ILOCK_EXCL);
                        code = xfs_zero_eof(ip, iattr->ia_size, old_size);
+                       xfs_iunlock(ip, XFS_ILOCK_EXCL);
                        if (code)
                                goto error_return;
                }
-               xfs_iunlock(ip, XFS_ILOCK_EXCL);
-               lock_flags &= ~XFS_ILOCK_EXCL;
 
                /*
                 * We are going to log the inode size change in this
-- 
1.7.10

<Prev in Thread] Current Thread [Next in Thread>