NFS: Reduce time spent holding the i_mutex during fallocate()
authorAnna Schumaker <Anna.Schumaker@netapp.com>
Mon, 16 Mar 2015 18:06:24 +0000 (14:06 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 23 Apr 2015 18:36:28 +0000 (14:36 -0400)
At the very least, we should not be taking the i_mutex until after
checking if the server even supports ALLOCATE or DEALLOCATE, allowing
v4.0 or v4.1 to exit without potentially waiting on a lock.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/nfs42proc.c
fs/nfs/nfs4file.c

index b9aa6bbcc8ed57c77ce5c784d7c156ab12268eb3..3a9e75235f30e60e5a4ae974864c63fb003b969d 100644 (file)
@@ -96,9 +96,13 @@ int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
        if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
                return -EOPNOTSUPP;
 
+       mutex_lock(&inode->i_mutex);
+
        err = nfs42_proc_fallocate(&msg, filep, offset, len);
        if (err == -EOPNOTSUPP)
                NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
+
+       mutex_unlock(&inode->i_mutex);
        return err;
 }
 
@@ -114,11 +118,15 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
                return -EOPNOTSUPP;
 
        nfs_wb_all(inode);
+       mutex_lock(&inode->i_mutex);
+
        err = nfs42_proc_fallocate(&msg, filep, offset, len);
        if (err == 0)
                truncate_pagecache_range(inode, offset, (offset + len) -1);
        if (err == -EOPNOTSUPP)
                NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
+
+       mutex_unlock(&inode->i_mutex);
        return err;
 }
 
index 151ddff624d4e051d0e1da5b2bb04e76ebc0817c..cb3c7879e59fbfac80b4bd36376af933eafa663a 100644 (file)
@@ -158,14 +158,9 @@ static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t
        if (ret < 0)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
        if (mode & FALLOC_FL_PUNCH_HOLE)
-               ret = nfs42_proc_deallocate(filep, offset, len);
-       else
-               ret = nfs42_proc_allocate(filep, offset, len);
-       mutex_unlock(&inode->i_mutex);
-
-       return ret;
+               return nfs42_proc_deallocate(filep, offset, len);
+       return nfs42_proc_allocate(filep, offset, len);
 }
 #endif /* CONFIG_NFS_V4_2 */