]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/nfs/delegation.c
NFSv4: don't mark all open state for recovery when handling recallable state revoked flag
[linux.git] / fs / nfs / delegation.c
index 885363ca8569909d96b15f8480fd4d57be1d0119..8b78274e3e56fb0e8973e1a5121348d8dbd632a2 100644 (file)
@@ -229,6 +229,8 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation
        spin_lock(&delegation->lock);
        if (delegation->inode != NULL)
                inode = igrab(delegation->inode);
+       if (!inode)
+               set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
        spin_unlock(&delegation->lock);
        return inode;
 }
@@ -681,7 +683,7 @@ void nfs_expire_all_delegations(struct nfs_client *clp)
 
 /**
  * nfs_super_return_all_delegations - return delegations for one superblock
- * @sb: sb to process
+ * @server: pointer to nfs_server to process
  *
  */
 void nfs_server_return_all_delegations(struct nfs_server *server)
@@ -944,10 +946,11 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
                list_for_each_entry_rcu(delegation, &server->delegations,
                                                                super_list) {
-                       if (test_bit(NFS_DELEGATION_RETURNING,
-                                               &delegation->flags))
-                               continue;
-                       if (test_bit(NFS_DELEGATION_NEED_RECLAIM,
+                       if (test_bit(NFS_DELEGATION_INODE_FREEING,
+                                               &delegation->flags) ||
+                           test_bit(NFS_DELEGATION_RETURNING,
+                                               &delegation->flags) ||
+                           test_bit(NFS_DELEGATION_NEED_RECLAIM,
                                                &delegation->flags) == 0)
                                continue;
                        if (!nfs_sb_active(server->super))
@@ -1030,6 +1033,18 @@ void nfs_mark_test_expired_all_delegations(struct nfs_client *clp)
        rcu_read_unlock();
 }
 
+/**
+ * nfs_test_expired_all_delegations - test all delegations for a client
+ * @clp: nfs_client to process
+ *
+ * Helper for handling "recallable state revoked" status from server.
+ */
+void nfs_test_expired_all_delegations(struct nfs_client *clp)
+{
+       nfs_mark_test_expired_all_delegations(clp);
+       nfs4_schedule_state_manager(clp);
+}
+
 /**
  * nfs_reap_expired_delegations - reap expired delegations
  * @clp: nfs_client to process
@@ -1053,10 +1068,11 @@ void nfs_reap_expired_delegations(struct nfs_client *clp)
        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
                list_for_each_entry_rcu(delegation, &server->delegations,
                                                                super_list) {
-                       if (test_bit(NFS_DELEGATION_RETURNING,
-                                               &delegation->flags))
-                               continue;
-                       if (test_bit(NFS_DELEGATION_TEST_EXPIRED,
+                       if (test_bit(NFS_DELEGATION_INODE_FREEING,
+                                               &delegation->flags) ||
+                           test_bit(NFS_DELEGATION_RETURNING,
+                                               &delegation->flags) ||
+                           test_bit(NFS_DELEGATION_TEST_EXPIRED,
                                                &delegation->flags) == 0)
                                continue;
                        if (!nfs_sb_active(server->super))