|
@@ -193,7 +193,11 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
|
|
{
|
|
{
|
|
int res = 0;
|
|
int res = 0;
|
|
|
|
|
|
- res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
|
|
|
|
|
|
+ if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
|
|
|
|
+ res = nfs4_proc_delegreturn(inode,
|
|
|
|
+ delegation->cred,
|
|
|
|
+ &delegation->stateid,
|
|
|
|
+ issync);
|
|
nfs_free_delegation(delegation);
|
|
nfs_free_delegation(delegation);
|
|
return res;
|
|
return res;
|
|
}
|
|
}
|
|
@@ -380,11 +384,13 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
|
|
{
|
|
{
|
|
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
|
|
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
|
|
struct nfs_inode *nfsi = NFS_I(inode);
|
|
struct nfs_inode *nfsi = NFS_I(inode);
|
|
- int err;
|
|
|
|
|
|
+ int err = 0;
|
|
|
|
|
|
if (delegation == NULL)
|
|
if (delegation == NULL)
|
|
return 0;
|
|
return 0;
|
|
do {
|
|
do {
|
|
|
|
+ if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
|
|
|
|
+ break;
|
|
err = nfs_delegation_claim_opens(inode, &delegation->stateid);
|
|
err = nfs_delegation_claim_opens(inode, &delegation->stateid);
|
|
if (!issync || err != -EAGAIN)
|
|
if (!issync || err != -EAGAIN)
|
|
break;
|
|
break;
|
|
@@ -605,10 +611,23 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void nfs_revoke_delegation(struct inode *inode)
|
|
|
|
+{
|
|
|
|
+ struct nfs_delegation *delegation;
|
|
|
|
+ rcu_read_lock();
|
|
|
|
+ delegation = rcu_dereference(NFS_I(inode)->delegation);
|
|
|
|
+ if (delegation != NULL) {
|
|
|
|
+ set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
|
|
|
|
+ nfs_mark_return_delegation(NFS_SERVER(inode), delegation);
|
|
|
|
+ }
|
|
|
|
+ rcu_read_unlock();
|
|
|
|
+}
|
|
|
|
+
|
|
void nfs_remove_bad_delegation(struct inode *inode)
|
|
void nfs_remove_bad_delegation(struct inode *inode)
|
|
{
|
|
{
|
|
struct nfs_delegation *delegation;
|
|
struct nfs_delegation *delegation;
|
|
|
|
|
|
|
|
+ nfs_revoke_delegation(inode);
|
|
delegation = nfs_inode_detach_delegation(inode);
|
|
delegation = nfs_inode_detach_delegation(inode);
|
|
if (delegation) {
|
|
if (delegation) {
|
|
nfs_inode_find_state_and_recover(inode, &delegation->stateid);
|
|
nfs_inode_find_state_and_recover(inode, &delegation->stateid);
|