]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
NFSv4: Add accounting for the number of active delegations held
authorTrond Myklebust <trondmy@gmail.com>
Mon, 27 Jan 2020 14:58:18 +0000 (09:58 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Feb 2020 18:54:13 +0000 (19:54 +0100)
[ Upstream commit d2269ea14ebd2a73f291d6b3a7a7d320ec00270c ]

In order to better manage our delegation caching, add a counter
to track the number of active delegations.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/delegation.c

index 5f02d922f2173b4b4b5a7a98306f9fb7ee926b58..8e322bacde699f7341003b91b29a9a98da5cb903 100644 (file)
 #include "internal.h"
 #include "nfs4trace.h"
 
-static void nfs_free_delegation(struct nfs_delegation *delegation)
+static atomic_long_t nfs_active_delegations;
+
+static void __nfs_free_delegation(struct nfs_delegation *delegation)
 {
        put_cred(delegation->cred);
        delegation->cred = NULL;
        kfree_rcu(delegation, rcu);
 }
 
+static void nfs_mark_delegation_revoked(struct nfs_delegation *delegation)
+{
+       if (!test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
+               delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
+               atomic_long_dec(&nfs_active_delegations);
+       }
+}
+
+static void nfs_free_delegation(struct nfs_delegation *delegation)
+{
+       nfs_mark_delegation_revoked(delegation);
+       __nfs_free_delegation(delegation);
+}
+
 /**
  * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
  * @delegation: delegation to process
@@ -348,7 +364,8 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation,
                delegation->stateid.seqid = update->stateid.seqid;
                smp_wmb();
                delegation->type = update->type;
-               clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
+               if (test_and_clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+                       atomic_long_inc(&nfs_active_delegations);
        }
 }
 
@@ -428,6 +445,8 @@ add_new:
        rcu_assign_pointer(nfsi->delegation, delegation);
        delegation = NULL;
 
+       atomic_long_inc(&nfs_active_delegations);
+
        trace_nfs4_set_delegation(inode, type);
 
        spin_lock(&inode->i_lock);
@@ -437,7 +456,7 @@ add_new:
 out:
        spin_unlock(&clp->cl_lock);
        if (delegation != NULL)
-               nfs_free_delegation(delegation);
+               __nfs_free_delegation(delegation);
        if (freeme != NULL) {
                nfs_do_return_delegation(inode, freeme, 0);
                nfs_free_delegation(freeme);
@@ -765,13 +784,6 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
        rcu_read_unlock();
 }
 
-static void nfs_mark_delegation_revoked(struct nfs_server *server,
-               struct nfs_delegation *delegation)
-{
-       set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
-       delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
-}
-
 static void nfs_revoke_delegation(struct inode *inode,
                const nfs4_stateid *stateid)
 {
@@ -799,7 +811,7 @@ static void nfs_revoke_delegation(struct inode *inode,
                }
                spin_unlock(&delegation->lock);
        }
-       nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
+       nfs_mark_delegation_revoked(delegation);
        ret = true;
 out:
        rcu_read_unlock();
@@ -838,7 +850,7 @@ void nfs_delegation_mark_returned(struct inode *inode,
                        delegation->stateid.seqid = stateid->seqid;
        }
 
-       nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
+       nfs_mark_delegation_revoked(delegation);
 
 out_clear_returning:
        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);