[HARDY 2/2] SRU: Bug:#253004 nfsd: move callback rpc_client creation into separate thread

Stefan Bader stefan.bader at canonical.com
Tue Jun 2 18:45:40 UTC 2009


Manoj Iyer wrote:
> SRU JUSTIFICATION:
> 
> IMPACT: Oops in sunrpc:rpc_shutdown_client
> Fix: likely related to: #212485 kernel bug rpc nfs client. Backported
> patch to Hardy.
> TEST: Test kernel in http://people.ubuntu.com/~manjo/lp253004-hardy/ was
> tested by community and reported to work.
> 
> 
> The following changes since commit
> 7758896776e7991a8fe5dc62d83fae68648fdd7d:
>    Brad Figg (1):
>          UBUNTU: [Hardy SRU][SAUCE]Add information to recognize Toshiba
> Satellite Pro M10 Alps Touchpad
> 
> are available in the git repository at:
> 
>    git://kernel.ubuntu.com/manjo/ubuntu-hardy.git lp253004
> 
> J. Bruce Fields (2):
>        nfsd: move callback rpc_client creation into separate thread
>        nfsd4: probe callback channel only once
> 
>   fs/nfsd/nfs4callback.c |   80
> ++++++++++++++++++++++++-----------------------
>   fs/nfsd/nfs4state.c    |    3 +-
>   2 files changed, 42 insertions(+), 41 deletions(-)
> 
> From 2147d9683c53aaa9c43263a1d5e6d377a5d01278 Mon Sep 17 00:00:00 2001
> From: J. Bruce Fields <bfields at citi.umich.edu>
> Date: Thu, 25 Oct 2007 19:00:26 -0400
> Subject: [PATCH] nfsd: move callback rpc_client creation into separate thread
> 
> Bug: #253004
> BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/253004
> 
> The whole reason to move this callback-channel probe into a separate
> thread was because (for now) we don't have an easy way to create the
> rpc_client asynchronously.  But I forgot to move the rpc_create() to the
> spawned thread.  Doh!  Fix that.
> 
> Signed-off-by: J. Bruce Fields <bfields at citi.umich.edu>
> ---
>   fs/nfsd/nfs4callback.c |   76 ++++++++++++++++++++++++-----------------------
>   1 files changed, 39 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
> index 9d536a8..698376b 100644
> --- a/fs/nfsd/nfs4callback.c
> +++ b/fs/nfsd/nfs4callback.c
> @@ -350,30 +350,6 @@ static struct rpc_version *	nfs_cb_version[] = {
>   static int do_probe_callback(void *data)
>   {
>   	struct nfs4_client *clp = data;
> -	struct nfs4_callback *cb = &clp->cl_callback;
> -	struct rpc_message msg = {
> -		.rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
> -		.rpc_argp       = clp,
> -	};
> -	int status;
> -
> -	status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT);
> -
> -	if (status) {
> -		rpc_shutdown_client(cb->cb_client);
> -		cb->cb_client = NULL;
> -	} else
> -		atomic_set(&cb->cb_set, 1);
> -	put_nfs4_client(clp);
> -	return 0;
> -}
> -
> -/*
> - * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
> - */
> -void
> -nfsd4_probe_callback(struct nfs4_client *clp)
> -{
>   	struct sockaddr_in	addr;
>   	struct nfs4_callback    *cb = &clp->cl_callback;
>   	struct rpc_timeout	timeparms = {
> @@ -390,13 +366,18 @@ nfsd4_probe_callback(struct nfs4_client *clp)
>   		.timeout	= &timeparms,
>   		.program	= program,
>   		.version	= nfs_cb_version[1]->number,
> -		.authflavor	= RPC_AUTH_UNIX,	/* XXX: need AUTH_GSS... */
> +		.authflavor	= RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
>   		.flags		= (RPC_CLNT_CREATE_NOPING),
>   	};
> -	struct task_struct *t;
> 
>   	if (atomic_read(&cb->cb_set))
>   		return;
> +	struct rpc_message msg = {
> +		.rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
> +		.rpc_argp       = clp,
> +	};
> +	struct rpc_clnt *client;
> +	int status;
> 
>   	/* Initialize address */
>   	memset(&addr, 0, sizeof(addr));
> @@ -416,29 +397,50 @@ nfsd4_probe_callback(struct nfs4_client *clp)
>   	program->stats->program = program;
> 
>   	/* Create RPC client */
> -	cb->cb_client = rpc_create(&args);
> -	if (IS_ERR(cb->cb_client)) {
> +	client = rpc_create(&args);
> +	if (IS_ERR(client)) {
>   		dprintk("NFSD: couldn't create callback client\n");
> +		status = PTR_ERR(client);
>   		goto out_err;
>   	}
> 
> +	status = rpc_call_sync(client, &msg, RPC_TASK_SOFT);
> +
> +	if (status)
> +		goto out_release_client;
> +
> +	cb->cb_client = client;
> +	atomic_set(&cb->cb_set, 1);
> +	put_nfs4_client(clp);
> +	return 0;
> +out_release_client:
> +	rpc_shutdown_client(client);
> +out_err:
> +	put_nfs4_client(clp);
> +	dprintk("NFSD: warning: no callback path to client %.*s\n",
> +		(int)clp->cl_name.len, clp->cl_name.data);
> +	return status;
> +}
> +
> +/*
> + * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
> + */
> +void
> +nfsd4_probe_callback(struct nfs4_client *clp)
> +{
> +	struct task_struct *t;
> +
> +	BUG_ON(atomic_read(&clp->cl_callback.cb_set));
> +
>   	/* the task holds a reference to the nfs4_client struct */
>   	atomic_inc(&clp->cl_count);
> 
>   	t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe");
> 
>   	if (IS_ERR(t))
> -		goto out_release_clp;
> +		atomic_dec(&clp->cl_count);
> 
>   	return;
> -
> -out_release_clp:
> -	atomic_dec(&clp->cl_count);
> -	rpc_shutdown_client(cb->cb_client);
> -out_err:
> -	cb->cb_client = NULL;
> -	dprintk("NFSD: warning: no callback path to client %.*s\n",
> -		(int)clp->cl_name.len, clp->cl_name.data);
>   }
> 
>   /*
ACK and applied

-- 

When all other means of communication fail, try words!






More information about the kernel-team mailing list