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, 
    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);
+               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

Reply via email to