[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