Commit b6669305 authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields
Browse files

nfsd: Reduce the number of calls to nfsd_file_gc()



Don't call nfsd_file_gc() on every put of the reference in nfsd_file_put().
Instead, do it only when we're expecting the refcount to go to 1.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 55f84cc4
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -282,27 +282,32 @@ nfsd_file_unhash_and_release_locked(struct nfsd_file *nf, struct list_head *disp
	return true;
}

static int
static void
nfsd_file_put_noref(struct nfsd_file *nf)
{
	int count;
	trace_nfsd_file_put(nf);

	count = atomic_dec_return(&nf->nf_ref);
	if (!count) {
	if (atomic_dec_and_test(&nf->nf_ref)) {
		WARN_ON(test_bit(NFSD_FILE_HASHED, &nf->nf_flags));
		nfsd_file_free(nf);
	}
	return count;
}

void
nfsd_file_put(struct nfsd_file *nf)
{
	bool is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
	bool is_hashed;

	set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
	if (nfsd_file_put_noref(nf) == 1 && is_hashed)
	if (atomic_read(&nf->nf_ref) > 2 || !nf->nf_file) {
		nfsd_file_put_noref(nf);
		return;
	}

	filemap_flush(nf->nf_file->f_mapping);
	is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
	nfsd_file_put_noref(nf);
	if (is_hashed)
		nfsd_file_schedule_laundrette();
	if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
		nfsd_file_gc();