]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFS: remove revoked delegation from server's delegation list
authorDai Ngo <dai.ngo@oracle.com>
Tue, 8 Oct 2024 22:58:07 +0000 (15:58 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Nov 2024 15:25:53 +0000 (16:25 +0100)
[ Upstream commit 7ef60108069b7e3cc66432304e1dd197d5c0a9b5 ]

After the delegation is returned to the NFS server remove it
from the server's delegations list to reduce the time it takes
to scan this list.

Network trace captured while running the below script shows the
time taken to service the CB_RECALL increases gradually due to
the overhead of traversing the delegation list in
nfs_delegation_find_inode_server.

The NFS server in this test is a Solaris server which issues
CB_RECALL when receiving the all-zero stateid in the SETATTR.

mount=/mnt/data
for i in $(seq 1 20)
do
   echo $i
   mkdir $mount/testtarfile$i
   time  tar -C $mount/testtarfile$i -xf 5000_files.tar
done

Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
Reviewed-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/delegation.c

index 8124d4f8b29a6f673d18c36eab6583ec5dac5883..ac79ef0d43a73e96d94e58272dab5b53076eb088 100644 (file)
@@ -981,6 +981,11 @@ void nfs_delegation_mark_returned(struct inode *inode,
        }
 
        nfs_mark_delegation_revoked(delegation);
+       clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+       spin_unlock(&delegation->lock);
+       if (nfs_detach_delegation(NFS_I(inode), delegation, NFS_SERVER(inode)))
+               nfs_put_delegation(delegation);
+       goto out_rcu_unlock;
 
 out_clear_returning:
        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);