Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=28c494c5c8d425e15b7b82571e4df6d6bc34594d
Commit:     28c494c5c8d425e15b7b82571e4df6d6bc34594d
Parent:     464ad6b1ade186b53a1dae863361853326b85694
Author:     Chuck Lever <[EMAIL PROTECTED]>
AuthorDate: Fri Oct 26 13:32:13 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 02:05:45 2008 -0500

    NFS: Prevent nfs_getattr() hang during heavy write workloads
    
    POSIX requires that ctime and mtime, as reported by the stat(2) call,
    reflect the activity of the most recent write(2).  To that end, 
nfs_getattr()
    flushes pending dirty writes to a file before doing a GETATTR to allow the
    NFS server to set the file's size, ctime, and mtime properly.
    
    However, nfs_getattr() can be starved when a constant stream of application
    writes to a file prevents nfs_wb_nocommit() from completing.  This usually
    results in hangs of programs doing a stat against an NFS file that is being
    written.  "ls -l" is a common victim of this behavior.
    
    To prevent starvation, hold the file's i_mutex in nfs_getattr() to
    freeze applications writes temporarily so the client can more quickly obtain
    clean values for a file's size, mtime, and ctime.
    
    Signed-off-by: Chuck Lever <[EMAIL PROTECTED]>
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/inode.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index cd0e57f..cc3a09d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -461,9 +461,18 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry 
*dentry, struct kstat *stat)
        int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
        int err;
 
-       /* Flush out writes to the server in order to update c/mtime */
-       if (S_ISREG(inode->i_mode))
+       /*
+        * Flush out writes to the server in order to update c/mtime.
+        *
+        * Hold the i_mutex to suspend application writes temporarily;
+        * this prevents long-running writing applications from blocking
+        * nfs_wb_nocommit.
+        */
+       if (S_ISREG(inode->i_mode)) {
+               mutex_lock(&inode->i_mutex);
                nfs_wb_nocommit(inode);
+               mutex_unlock(&inode->i_mutex);
+       }
 
        /*
         * We may force a getattr if the user cares about atime.
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to