summaryrefslogtreecommitdiff
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2018-09-02 15:57:01 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-09-30 15:35:17 -0400
commit0de43976fbe716379084f954b1e370c35aa87bf0 (patch)
tree64a6ea935fc8015c7369b9ece308771585cd3053 /fs/nfs/delegation.c
parent6ba0c4e5bb08cc929662588aa2015e0ee7ee9376 (diff)
downloadlwn-0de43976fbe716379084f954b1e370c35aa87bf0.tar.gz
lwn-0de43976fbe716379084f954b1e370c35aa87bf0.zip
NFS: Convert lookups of the open context to RCU
Reduce contention on the inode->i_lock by ensuring that we use RCU when looking up the NFS open context. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index f033f3a69a3b..76d205d1c7bc 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -136,8 +136,8 @@ static int nfs_delegation_claim_opens(struct inode *inode,
int err;
again:
- spin_lock(&inode->i_lock);
- list_for_each_entry(ctx, &nfsi->open_files, list) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
state = ctx->state;
if (state == NULL)
continue;
@@ -147,8 +147,9 @@ again:
continue;
if (!nfs4_stateid_match(&state->stateid, stateid))
continue;
- get_nfs_open_context(ctx);
- spin_unlock(&inode->i_lock);
+ if (!get_nfs_open_context(ctx))
+ continue;
+ rcu_read_unlock();
sp = state->owner;
/* Block nfs4_proc_unlck */
mutex_lock(&sp->so_delegreturn_mutex);
@@ -164,7 +165,7 @@ again:
return err;
goto again;
}
- spin_unlock(&inode->i_lock);
+ rcu_read_unlock();
return 0;
}