Commit 9048cf05 authored by Olga Kornievskaia's avatar Olga Kornievskaia Committed by Chuck Lever
Browse files

NFSD: fix management of pending async copies



Currently the pending_async_copies count is decremented just
before a struct nfsd4_copy is destroyed. After commit aa0ebd21
("NFSD: Add nfsd4_copy time-to-live") nfsd4_copy structures sticks
around for 10 lease periods after the COPY itself has completed,
the pending_async_copies count stays high for a long time. This
causes NFSD to avoid the use of background copy even though the
actual background copy workload might no longer be running.

In this patch, decrement pending_async_copies once async copy thread
is done processing the copy work.

Fixes: aa0ebd21 ("NFSD: Add nfsd4_copy time-to-live")
Signed-off-by: default avatarOlga Kornievskaia <okorniev@redhat.com>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 69d803c4
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -1347,7 +1347,6 @@ static void nfs4_put_copy(struct nfsd4_copy *copy)
{
	if (!refcount_dec_and_test(&copy->refcount))
		return;
	atomic_dec(&copy->cp_nn->pending_async_copies);
	kfree(copy->cp_src);
	kfree(copy);
}
@@ -1870,6 +1869,7 @@ static int nfsd4_do_async_copy(void *data)
	set_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags);
	trace_nfsd_copy_async_done(copy);
	nfsd4_send_cb_offload(copy);
	atomic_dec(&copy->cp_nn->pending_async_copies);
	return 0;
}

@@ -1927,19 +1927,19 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		/* Arbitrary cap on number of pending async copy operations */
		if (atomic_inc_return(&nn->pending_async_copies) >
				(int)rqstp->rq_pool->sp_nrthreads)
			goto out_err;
			goto out_dec_async_copy_err;
		async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL);
		if (!async_copy->cp_src)
			goto out_err;
			goto out_dec_async_copy_err;
		if (!nfs4_init_copy_state(nn, copy))
			goto out_err;
			goto out_dec_async_copy_err;
		memcpy(&result->cb_stateid, &copy->cp_stateid.cs_stid,
			sizeof(result->cb_stateid));
		dup_copy_fields(copy, async_copy);
		async_copy->copy_task = kthread_create(nfsd4_do_async_copy,
				async_copy, "%s", "copy thread");
		if (IS_ERR(async_copy->copy_task))
			goto out_err;
			goto out_dec_async_copy_err;
		spin_lock(&async_copy->cp_clp->async_lock);
		list_add(&async_copy->copies,
				&async_copy->cp_clp->async_copies);
@@ -1954,6 +1954,9 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	trace_nfsd_copy_done(copy, status);
	release_copy_files(copy);
	return status;
out_dec_async_copy_err:
	if (async_copy)
		atomic_dec(&nn->pending_async_copies);
out_err:
	if (nfsd4_ssc_is_inter(copy)) {
		/*