diff options
-rw-r--r-- | fs/nfs/delegation.c | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 1fd62fc..521d71b 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -175,9 +175,9 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation return inode; } -static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, - const nfs4_stateid *stateid, - struct nfs_client *clp) +static struct nfs_delegation * +nfs_detach_delegation_locked(struct nfs_inode *nfsi, + struct nfs_client *clp) { struct nfs_delegation *delegation = rcu_dereference_protected(nfsi->delegation, @@ -185,22 +185,29 @@ static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfs if (delegation == NULL) goto nomatch; + spin_lock(&delegation->lock); - if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data, - sizeof(delegation->stateid.data)) != 0) - goto nomatch_unlock; list_del_rcu(&delegation->super_list); delegation->inode = NULL; nfsi->delegation_state = 0; rcu_assign_pointer(nfsi->delegation, NULL); spin_unlock(&delegation->lock); return delegation; -nomatch_unlock: - spin_unlock(&delegation->lock); nomatch: return NULL; } +static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi, + struct nfs_client *clp) +{ + struct nfs_delegation *delegation; + + spin_lock(&clp->cl_lock); + delegation = nfs_detach_delegation_locked(nfsi, clp); + spin_unlock(&clp->cl_lock); + return delegation; +} + /* * Set up a delegation on an inode */ @@ -246,7 +253,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct delegation = NULL; goto out; } - freeme = nfs_detach_delegation_locked(nfsi, NULL, clp); + freeme = nfs_detach_delegation_locked(nfsi, clp); } list_add_rcu(&delegation->super_list, &clp->cl_delegations); nfsi->delegation_state = delegation->type; @@ -307,9 +314,7 @@ restart: inode = nfs_delegation_grab_inode(delegation); if (inode == NULL) continue; - spin_lock(&clp->cl_lock); - delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp); - spin_unlock(&clp->cl_lock); + delegation = nfs_detach_delegation(NFS_I(inode), clp); rcu_read_unlock(); if (delegation != NULL) { filemap_flush(inode->i_mapping); @@ -338,9 +343,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode) struct nfs_delegation *delegation; if (rcu_access_pointer(nfsi->delegation) != NULL) { - spin_lock(&clp->cl_lock); - delegation = nfs_detach_delegation_locked(nfsi, NULL, clp); - spin_unlock(&clp->cl_lock); + delegation = nfs_detach_delegation(nfsi, clp); if (delegation != NULL) nfs_do_return_delegation(inode, delegation, 0); } @@ -354,9 +357,7 @@ int nfs_inode_return_delegation(struct inode *inode) int err = 0; if (rcu_access_pointer(nfsi->delegation) != NULL) { - spin_lock(&clp->cl_lock); - delegation = nfs_detach_delegation_locked(nfsi, NULL, clp); - spin_unlock(&clp->cl_lock); + delegation = nfs_detach_delegation(nfsi, clp); if (delegation != NULL) { nfs_wb_all(inode); err = __nfs_inode_return_delegation(inode, delegation, 1); @@ -530,9 +531,7 @@ restart: inode = nfs_delegation_grab_inode(delegation); if (inode == NULL) continue; - spin_lock(&clp->cl_lock); - delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp); - spin_unlock(&clp->cl_lock); + delegation = nfs_detach_delegation(NFS_I(inode), clp); rcu_read_unlock(); if (delegation != NULL) nfs_free_delegation(delegation); |