[pnfs] [PATCH 1/1] nfsd41: Fix callback probe reference count bug
J. Bruce Fields
bfields at fieldses.org
Tue Jan 15 11:56:53 EST 2008
On Mon, Jan 14, 2008 at 04:36:05PM -0800, Ricardo Labiaga wrote:
> The server hits a BUG_ON() condition trying to free the nfs4_client
> structure during the callback probe. It is releasing a reference
> to the structure with put_nfs4_client() without having first
> acquired a reference to it.
>
> Fix by holding a reference in nfsd4*_probe_callback() before
> calling rpc_call_async(). In the vanilla NFSv4 callback probe,
> a reference is indeed acquired and a new kthread executes a
> synchronous RPC call. This is equivalent to what we now do by
> holding a reference and scheduling an async RPC. The reference
> is released after the async thread is done processing.
I believe these sorts of races should be gone in the nfs-server-stable
branch
git://linux-nfs.org/~bfields/linux.git
If you have a good test case and got a chance to test with that kernel,
that could be helpful....
--b.
>
> Signed-off-by: Ricardo Labiaga <ricardo.labiaga at netapp.com>
> ---
> fs/nfsd/nfs4callback.c | 14 ++++++++++++++
> 1 files changed, 14 insertions(+), 0 deletions(-)
>
> diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
> index 7fb7786..22c4ca0 100644
> --- a/fs/nfsd/nfs4callback.c
> +++ b/fs/nfsd/nfs4callback.c
> @@ -563,6 +563,12 @@ nfsd4_probe_callback(struct nfs4_client *clp)
> goto out_err;
> }
>
> + /*
> + * The task holds a reference to the nfs4_client struct.
> + * It is released in the callback function upon success.
> + */
> + atomic_inc(&clp->cl_count);
> +
> status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC,
> &nfs4_cb_null_ops, NULL);
>
> @@ -573,6 +579,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
> return;
>
> out_release_clp:
> + atomic_dec(&clp->cl_count);
> rpc_shutdown_client(cb->cb_client);
> out_err:
> cb->cb_client = NULL;
> @@ -645,6 +652,12 @@ nfsd41_probe_callback(struct nfs4_client *clp)
> dprintk("NFSD: %s: clp %p cb_client %p\n", __FUNCTION__,
> clp, clp->cl_callback.cb_client);
>
> + /*
> + * The task holds a reference to the nfs4_client struct.
> + * It is released in the callback function upon success.
> + */
> + atomic_inc(&clp->cl_count);
> +
> status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC,
> &nfs4_cb_null_ops, NULL);
>
> @@ -655,6 +668,7 @@ nfsd41_probe_callback(struct nfs4_client *clp)
> return;
>
> out_release_clp:
> + atomic_dec(&clp->cl_count);
> rpc_shutdown_client(cb->cb_client);
> out_err:
> cb->cb_client = NULL;
> --
> 1.5.3.3
> _______________________________________________
> pNFS mailing list
> pNFS at linux-nfs.org
> http://linux-nfs.org/cgi-bin/mailman/listinfo/pnfs
More information about the pNFS
mailing list