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

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
Loading
Loading
Loading
Loading
+24 −12
Original line number Original line Diff line number Diff line
@@ -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,
		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 @@ add_new:
	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 @@ add_new:
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
	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,
		}
		}
		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,
			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);