Commit d2269ea1 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

NFSv4: Add accounting for the number of active delegations held

In order to better manage our delegation caching, add a counter
to track the number of active delegations.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent b7b7dac6
...@@ -25,13 +25,29 @@ ...@@ -25,13 +25,29 @@
#include "internal.h" #include "internal.h"
#include "nfs4trace.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); put_cred(delegation->cred);
delegation->cred = NULL; delegation->cred = NULL;
kfree_rcu(delegation, rcu); 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 * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
* @delegation: delegation to process * @delegation: delegation to process
...@@ -343,7 +359,8 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation, ...@@ -343,7 +359,8 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation,
delegation->stateid.seqid = update->stateid.seqid; delegation->stateid.seqid = update->stateid.seqid;
smp_wmb(); smp_wmb();
delegation->type = update->type; 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);
} }
} }
...@@ -423,6 +440,8 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, ...@@ -423,6 +440,8 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
rcu_assign_pointer(nfsi->delegation, delegation); rcu_assign_pointer(nfsi->delegation, delegation);
delegation = NULL; delegation = NULL;
atomic_long_inc(&nfs_active_delegations);
trace_nfs4_set_delegation(inode, type); trace_nfs4_set_delegation(inode, type);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
...@@ -432,7 +451,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, ...@@ -432,7 +451,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
out: out:
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
if (delegation != NULL) if (delegation != NULL)
nfs_free_delegation(delegation); __nfs_free_delegation(delegation);
if (freeme != NULL) { if (freeme != NULL) {
nfs_do_return_delegation(inode, freeme, 0); nfs_do_return_delegation(inode, freeme, 0);
nfs_free_delegation(freeme); nfs_free_delegation(freeme);
...@@ -796,13 +815,6 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl ...@@ -796,13 +815,6 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
rcu_read_unlock(); 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, static void nfs_revoke_delegation(struct inode *inode,
const nfs4_stateid *stateid) const nfs4_stateid *stateid)
{ {
...@@ -830,7 +842,7 @@ static void nfs_revoke_delegation(struct inode *inode, ...@@ -830,7 +842,7 @@ static void nfs_revoke_delegation(struct inode *inode,
} }
spin_unlock(&delegation->lock); spin_unlock(&delegation->lock);
} }
nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation); nfs_mark_delegation_revoked(delegation);
ret = true; ret = true;
out: out:
rcu_read_unlock(); rcu_read_unlock();
...@@ -869,7 +881,7 @@ void nfs_delegation_mark_returned(struct inode *inode, ...@@ -869,7 +881,7 @@ void nfs_delegation_mark_returned(struct inode *inode,
delegation->stateid.seqid = stateid->seqid; delegation->stateid.seqid = stateid->seqid;
} }
nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation); nfs_mark_delegation_revoked(delegation);
out_clear_returning: out_clear_returning:
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags); clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
......
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