|
@@ -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,
|
|
|
|
- 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 =
|
|
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
|
|
|
|
|
|
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
|
|
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 @@ restart:
|
|
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_locked(NFS_I(inode), NULL, clp);
|
|
|
|
- spin_unlock(&clp->cl_lock);
|
|
|
|
|
|
+ delegation = nfs_detach_delegation(NFS_I(inode), clp);
|
|
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)
|
|
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_locked(nfsi, NULL, clp);
|
|
|
|
- spin_unlock(&clp->cl_lock);
|
|
|
|
|
|
+ delegation = nfs_detach_delegation(nfsi, clp);
|
|
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)
|
|
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_locked(nfsi, NULL, clp);
|
|
|
|
- spin_unlock(&clp->cl_lock);
|
|
|
|
|
|
+ delegation = nfs_detach_delegation(nfsi, clp);
|
|
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 @@ restart:
|
|
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_locked(NFS_I(inode), NULL, clp);
|
|
|
|
- spin_unlock(&clp->cl_lock);
|
|
|
|
|
|
+ delegation = nfs_detach_delegation(NFS_I(inode), clp);
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
if (delegation != NULL)
|
|
if (delegation != NULL)
|
|
nfs_free_delegation(delegation);
|
|
nfs_free_delegation(delegation);
|