Commit dda4b225 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

NFS: Introduce nfs_detach_delegations()

Clean up:  Refactor code that takes clp->cl_lock and calls
nfs_detach_delegations_locked() into its own function.

While we're changing the call sites, get rid of the second parameter
and the logic in nfs_detach_delegations_locked() that uses it, since
callers always set that parameter of nfs_detach_delegations_locked()
to NULL.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 24d292b8
...@@ -175,9 +175,9 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation ...@@ -175,9 +175,9 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation
return inode; return inode;
} }
static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, static struct nfs_delegation *
const nfs4_stateid *stateid, nfs_detach_delegation_locked(struct nfs_inode *nfsi,
struct nfs_client *clp) struct nfs_client *clp)
{ {
struct nfs_delegation *delegation = struct nfs_delegation *delegation =
rcu_dereference_protected(nfsi->delegation, rcu_dereference_protected(nfsi->delegation,
...@@ -185,22 +185,29 @@ static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfs ...@@ -185,22 +185,29 @@ static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfs
if (delegation == NULL) if (delegation == NULL)
goto nomatch; goto nomatch;
spin_lock(&delegation->lock); 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); list_del_rcu(&delegation->super_list);
delegation->inode = NULL; delegation->inode = NULL;
nfsi->delegation_state = 0; nfsi->delegation_state = 0;
rcu_assign_pointer(nfsi->delegation, NULL); rcu_assign_pointer(nfsi->delegation, NULL);
spin_unlock(&delegation->lock); spin_unlock(&delegation->lock);
return delegation; return delegation;
nomatch_unlock:
spin_unlock(&delegation->lock);
nomatch: nomatch:
return NULL; 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 * Set up a delegation on an inode
*/ */
...@@ -246,7 +253,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct ...@@ -246,7 +253,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
delegation = NULL; delegation = NULL;
goto out; 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); list_add_rcu(&delegation->super_list, &clp->cl_delegations);
nfsi->delegation_state = delegation->type; nfsi->delegation_state = delegation->type;
...@@ -307,9 +314,7 @@ int nfs_client_return_marked_delegations(struct nfs_client *clp) ...@@ -307,9 +314,7 @@ int nfs_client_return_marked_delegations(struct nfs_client *clp)
inode = nfs_delegation_grab_inode(delegation); inode = nfs_delegation_grab_inode(delegation);
if (inode == NULL) if (inode == NULL)
continue; continue;
spin_lock(&clp->cl_lock); delegation = nfs_detach_delegation(NFS_I(inode), clp);
delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
spin_unlock(&clp->cl_lock);
rcu_read_unlock(); rcu_read_unlock();
if (delegation != NULL) { if (delegation != NULL) {
filemap_flush(inode->i_mapping); filemap_flush(inode->i_mapping);
...@@ -338,9 +343,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode) ...@@ -338,9 +343,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode)
struct nfs_delegation *delegation; struct nfs_delegation *delegation;
if (rcu_access_pointer(nfsi->delegation) != NULL) { if (rcu_access_pointer(nfsi->delegation) != NULL) {
spin_lock(&clp->cl_lock); delegation = nfs_detach_delegation(nfsi, clp);
delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
spin_unlock(&clp->cl_lock);
if (delegation != NULL) if (delegation != NULL)
nfs_do_return_delegation(inode, delegation, 0); nfs_do_return_delegation(inode, delegation, 0);
} }
...@@ -354,9 +357,7 @@ int nfs_inode_return_delegation(struct inode *inode) ...@@ -354,9 +357,7 @@ int nfs_inode_return_delegation(struct inode *inode)
int err = 0; int err = 0;
if (rcu_access_pointer(nfsi->delegation) != NULL) { if (rcu_access_pointer(nfsi->delegation) != NULL) {
spin_lock(&clp->cl_lock); delegation = nfs_detach_delegation(nfsi, clp);
delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
spin_unlock(&clp->cl_lock);
if (delegation != NULL) { if (delegation != NULL) {
nfs_wb_all(inode); nfs_wb_all(inode);
err = __nfs_inode_return_delegation(inode, delegation, 1); err = __nfs_inode_return_delegation(inode, delegation, 1);
...@@ -530,9 +531,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp) ...@@ -530,9 +531,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
inode = nfs_delegation_grab_inode(delegation); inode = nfs_delegation_grab_inode(delegation);
if (inode == NULL) if (inode == NULL)
continue; continue;
spin_lock(&clp->cl_lock); delegation = nfs_detach_delegation(NFS_I(inode), clp);
delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
spin_unlock(&clp->cl_lock);
rcu_read_unlock(); rcu_read_unlock();
if (delegation != NULL) if (delegation != NULL)
nfs_free_delegation(delegation); nfs_free_delegation(delegation);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment