[NETNS][DCCPV6]: Move the dccp_v6_ctl_sk on the struct net.
[safe/jmp/linux-2.6] / net / sunrpc / clnt.c
index 22092b9..13a3718 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/smp_lock.h>
 #include <linux/utsname.h>
 #include <linux/workqueue.h>
+#include <linux/in6.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
@@ -42,7 +43,7 @@
 
 #define dprint_status(t)                                       \
        dprintk("RPC: %5u %s (status %d)\n", t->tk_pid,         \
-                       __FUNCTION__, t->tk_status)
+                       __func__, t->tk_status)
 
 /*
  * All RPC clients are linked into this list
@@ -121,8 +122,9 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
        }
 }
 
-static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, struct rpc_program *program, u32 vers, rpc_authflavor_t flavor)
+static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
 {
+       struct rpc_program      *program = args->program;
        struct rpc_version      *version;
        struct rpc_clnt         *clnt = NULL;
        struct rpc_auth         *auth;
@@ -131,13 +133,13 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
 
        /* sanity check the name before trying to print it */
        err = -EINVAL;
-       len = strlen(servname);
+       len = strlen(args->servername);
        if (len > RPC_MAXNETNAMELEN)
                goto out_no_rpciod;
        len++;
 
        dprintk("RPC:       creating %s client for %s (xprt %p)\n",
-                       program->name, servname, xprt);
+                       program->name, args->servername, xprt);
 
        err = rpciod_up();
        if (err)
@@ -145,7 +147,11 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
        err = -EINVAL;
        if (!xprt)
                goto out_no_xprt;
-       if (vers >= program->nrvers || !(version = program->version[vers]))
+
+       if (args->version >= program->nrvers)
+               goto out_err;
+       version = program->version[args->version];
+       if (version == NULL)
                goto out_err;
 
        err = -ENOMEM;
@@ -157,12 +163,12 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
        clnt->cl_server = clnt->cl_inline_name;
        if (len > sizeof(clnt->cl_inline_name)) {
                char *buf = kmalloc(len, GFP_KERNEL);
-               if (buf != 0)
+               if (buf != NULL)
                        clnt->cl_server = buf;
                else
                        len = sizeof(clnt->cl_inline_name);
        }
-       strlcpy(clnt->cl_server, servname, len);
+       strlcpy(clnt->cl_server, args->servername, len);
 
        clnt->cl_xprt     = xprt;
        clnt->cl_procinfo = version->procs;
@@ -182,8 +188,15 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
        if (!xprt_bound(clnt->cl_xprt))
                clnt->cl_autobind = 1;
 
+       clnt->cl_timeout = xprt->timeout;
+       if (args->timeout != NULL) {
+               memcpy(&clnt->cl_timeout_default, args->timeout,
+                               sizeof(clnt->cl_timeout_default));
+               clnt->cl_timeout = &clnt->cl_timeout_default;
+       }
+
        clnt->cl_rtt = &clnt->cl_rtt_default;
-       rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval);
+       rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
 
        kref_init(&clnt->cl_kref);
 
@@ -191,10 +204,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
        if (err < 0)
                goto out_no_path;
 
-       auth = rpcauth_create(flavor, clnt);
+       auth = rpcauth_create(args->authflavor, clnt);
        if (IS_ERR(auth)) {
                printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
-                               flavor);
+                               args->authflavor);
                err = PTR_ERR(auth);
                goto out_no_auth;
        }
@@ -245,9 +258,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
                .srcaddr = args->saddress,
                .dstaddr = args->address,
                .addrlen = args->addrsize,
-               .timeout = args->timeout
        };
-       char servername[20];
+       char servername[48];
 
        xprt = xprt_create_transport(&xprtargs);
        if (IS_ERR(xprt))
@@ -258,13 +270,34 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
         * up a string representation of the passed-in address.
         */
        if (args->servername == NULL) {
-               struct sockaddr_in *addr =
-                                       (struct sockaddr_in *) args->address;
-               snprintf(servername, sizeof(servername), NIPQUAD_FMT,
-                       NIPQUAD(addr->sin_addr.s_addr));
+               servername[0] = '\0';
+               switch (args->address->sa_family) {
+               case AF_INET: {
+                       struct sockaddr_in *sin =
+                                       (struct sockaddr_in *)args->address;
+                       snprintf(servername, sizeof(servername), NIPQUAD_FMT,
+                                NIPQUAD(sin->sin_addr.s_addr));
+                       break;
+               }
+               case AF_INET6: {
+                       struct sockaddr_in6 *sin =
+                                       (struct sockaddr_in6 *)args->address;
+                       snprintf(servername, sizeof(servername), NIP6_FMT,
+                                NIP6(sin->sin6_addr));
+                       break;
+               }
+               default:
+                       /* caller wants default server name, but
+                        * address family isn't recognized. */
+                       return ERR_PTR(-EINVAL);
+               }
                args->servername = servername;
        }
 
+       xprt = xprt_create_transport(&xprtargs);
+       if (IS_ERR(xprt))
+               return (struct rpc_clnt *)xprt;
+
        /*
         * By default, kernel RPC client connects from a reserved port.
         * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters,
@@ -275,13 +308,12 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
        if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
                xprt->resvport = 0;
 
-       clnt = rpc_new_client(xprt, args->servername, args->program,
-                               args->version, args->authflavor);
+       clnt = rpc_new_client(args, xprt);
        if (IS_ERR(clnt))
                return clnt;
 
        if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
-               int err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
+               int err = rpc_ping(clnt, RPC_TASK_SOFT);
                if (err != 0) {
                        rpc_shutdown_client(clnt);
                        return ERR_PTR(err);
@@ -292,8 +324,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
        if (args->flags & RPC_CLNT_CREATE_HARDRTRY)
                clnt->cl_softrtry = 0;
 
-       if (args->flags & RPC_CLNT_CREATE_INTR)
-               clnt->cl_intr = 1;
        if (args->flags & RPC_CLNT_CREATE_AUTOBIND)
                clnt->cl_autobind = 1;
        if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
@@ -322,7 +352,7 @@ rpc_clone_client(struct rpc_clnt *clnt)
        new->cl_autobind = 0;
        INIT_LIST_HEAD(&new->cl_tasks);
        spin_lock_init(&new->cl_lock);
-       rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
+       rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval);
        new->cl_metrics = rpc_alloc_iostats(clnt);
        if (new->cl_metrics == NULL)
                goto out_no_stats;
@@ -342,7 +372,7 @@ out_no_path:
 out_no_stats:
        kfree(new);
 out_no_clnt:
-       dprintk("RPC:       %s: returned error %d\n", __FUNCTION__, err);
+       dprintk("RPC:       %s: returned error %d\n", __func__, err);
        return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(rpc_clone_client);
@@ -434,9 +464,9 @@ rpc_release_client(struct rpc_clnt *clnt)
 
 /**
  * rpc_bind_new_program - bind a new RPC program to an existing client
- * @old - old rpc_client
- * @program - rpc program to set
- * @vers - rpc program version
+ * @old: old rpc_client
+ * @program: rpc program to set
+ * @vers: rpc program version
  *
  * Clones the rpc client and sets up a new RPC program. This is mainly
  * of use for enabling different RPC programs to share the same transport.
@@ -461,7 +491,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
        clnt->cl_prog     = program->number;
        clnt->cl_vers     = version->number;
        clnt->cl_stats    = program->stats;
-       err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
+       err = rpc_ping(clnt, RPC_TASK_SOFT);
        if (err != 0) {
                rpc_shutdown_client(clnt);
                clnt = ERR_PTR(err);
@@ -483,79 +513,34 @@ static const struct rpc_call_ops rpc_default_ops = {
        .rpc_call_done = rpc_default_callback,
 };
 
-/*
- *     Export the signal mask handling for synchronous code that
- *     sleeps on RPC calls
+/**
+ * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
+ * @task_setup_data: pointer to task initialisation data
  */
-#define RPC_INTR_SIGNALS (sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTERM))
-
-static void rpc_save_sigmask(sigset_t *oldset, int intr)
-{
-       unsigned long   sigallow = sigmask(SIGKILL);
-       sigset_t sigmask;
-
-       /* Block all signals except those listed in sigallow */
-       if (intr)
-               sigallow |= RPC_INTR_SIGNALS;
-       siginitsetinv(&sigmask, sigallow);
-       sigprocmask(SIG_BLOCK, &sigmask, oldset);
-}
-
-static inline void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset)
-{
-       rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task));
-}
-
-static inline void rpc_restore_sigmask(sigset_t *oldset)
-{
-       sigprocmask(SIG_SETMASK, oldset, NULL);
-}
-
-void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset)
-{
-       rpc_save_sigmask(oldset, clnt->cl_intr);
-}
-EXPORT_SYMBOL_GPL(rpc_clnt_sigmask);
-
-void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
-{
-       rpc_restore_sigmask(oldset);
-}
-EXPORT_SYMBOL_GPL(rpc_clnt_sigunmask);
-
-static
-struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt,
-               struct rpc_message *msg,
-               int flags,
-               const struct rpc_call_ops *ops,
-               void *data)
+struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
 {
        struct rpc_task *task, *ret;
-       sigset_t oldset;
 
-       task = rpc_new_task(clnt, flags, ops, data);
+       task = rpc_new_task(task_setup_data);
        if (task == NULL) {
-               rpc_release_calldata(ops, data);
-               return ERR_PTR(-ENOMEM);
+               rpc_release_calldata(task_setup_data->callback_ops,
+                               task_setup_data->callback_data);
+               ret = ERR_PTR(-ENOMEM);
+               goto out;
        }
 
-       /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */
-       rpc_task_sigmask(task, &oldset);
-       if (msg != NULL) {
-               rpc_call_setup(task, msg, 0);
-               if (task->tk_status != 0) {
-                       ret = ERR_PTR(task->tk_status);
-                       rpc_put_task(task);
-                       goto out;
-               }
+       if (task->tk_status != 0) {
+               ret = ERR_PTR(task->tk_status);
+               rpc_put_task(task);
+               goto out;
        }
        atomic_inc(&task->tk_count);
        rpc_execute(task);
        ret = task;
 out:
-       rpc_restore_sigmask(&oldset);
        return ret;
 }
+EXPORT_SYMBOL_GPL(rpc_run_task);
 
 /**
  * rpc_call_sync - Perform a synchronous RPC call
@@ -566,11 +551,17 @@ out:
 int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
 {
        struct rpc_task *task;
+       struct rpc_task_setup task_setup_data = {
+               .rpc_client = clnt,
+               .rpc_message = msg,
+               .callback_ops = &rpc_default_ops,
+               .flags = flags,
+       };
        int status;
 
        BUG_ON(flags & RPC_TASK_ASYNC);
 
-       task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL);
+       task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task))
                return PTR_ERR(task);
        status = task->tk_status;
@@ -584,7 +575,7 @@ EXPORT_SYMBOL_GPL(rpc_call_sync);
  * @clnt: pointer to RPC client
  * @msg: RPC call parameters
  * @flags: RPC call flags
- * @ops: RPC call ops
+ * @tk_ops: RPC call ops
  * @data: user call data
  */
 int
@@ -592,8 +583,15 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
               const struct rpc_call_ops *tk_ops, void *data)
 {
        struct rpc_task *task;
+       struct rpc_task_setup task_setup_data = {
+               .rpc_client = clnt,
+               .rpc_message = msg,
+               .callback_ops = tk_ops,
+               .callback_data = data,
+               .flags = flags|RPC_TASK_ASYNC,
+       };
 
-       task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data);
+       task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task))
                return PTR_ERR(task);
        rpc_put_task(task);
@@ -601,44 +599,18 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
 }
 EXPORT_SYMBOL_GPL(rpc_call_async);
 
-/**
- * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
- * @clnt: pointer to RPC client
- * @flags: RPC flags
- * @ops: RPC call ops
- * @data: user call data
- */
-struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
-                                       const struct rpc_call_ops *tk_ops,
-                                       void *data)
-{
-       return rpc_do_run_task(clnt, NULL, flags, tk_ops, data);
-}
-EXPORT_SYMBOL_GPL(rpc_run_task);
-
 void
-rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
+rpc_call_start(struct rpc_task *task)
 {
-       task->tk_msg   = *msg;
-       task->tk_flags |= flags;
-       /* Bind the user cred */
-       if (task->tk_msg.rpc_cred != NULL)
-               rpcauth_holdcred(task);
-       else
-               rpcauth_bindcred(task);
-
-       if (task->tk_status == 0)
-               task->tk_action = call_start;
-       else
-               task->tk_action = rpc_exit_task;
+       task->tk_action = call_start;
 }
-EXPORT_SYMBOL_GPL(rpc_call_setup);
+EXPORT_SYMBOL_GPL(rpc_call_start);
 
 /**
  * rpc_peeraddr - extract remote peer address from clnt's xprt
  * @clnt: RPC client structure
  * @buf: target buffer
- * @size: length of target buffer
+ * @bufsize: length of target buffer
  *
  * Returns the number of bytes that are actually in the stored address.
  */
@@ -661,7 +633,8 @@ EXPORT_SYMBOL_GPL(rpc_peeraddr);
  * @format: address format
  *
  */
-char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format)
+const char *rpc_peeraddr2str(struct rpc_clnt *clnt,
+                            enum rpc_display_format_t format)
 {
        struct rpc_xprt *xprt = clnt->cl_xprt;
 
@@ -783,7 +756,7 @@ call_reserveresult(struct rpc_task *task)
                }
 
                printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n",
-                               __FUNCTION__, status);
+                               __func__, status);
                rpc_exit(task, -EIO);
                return;
        }
@@ -794,7 +767,7 @@ call_reserveresult(struct rpc_task *task)
         */
        if (task->tk_rqstp) {
                printk(KERN_ERR "%s: status=%d, request allocated anyway\n",
-                               __FUNCTION__, status);
+                               __func__, status);
                xprt_release(task);
        }
 
@@ -806,7 +779,7 @@ call_reserveresult(struct rpc_task *task)
                break;
        default:
                printk(KERN_ERR "%s: unrecognized error %d, exiting\n",
-                               __FUNCTION__, status);
+                               __func__, status);
                break;
        }
        rpc_exit(task, status);
@@ -1354,7 +1327,7 @@ call_verify(struct rpc_task *task)
                 *   undefined results
                 */
                dprintk("RPC: %5u %s: XDR representation not a multiple of"
-                      " 4 bytes: 0x%x\n", task->tk_pid, __FUNCTION__,
+                      " 4 bytes: 0x%x\n", task->tk_pid, __func__,
                       task->tk_rqstp->rq_rcv_buf.len);
                goto out_eio;
        }
@@ -1364,7 +1337,7 @@ call_verify(struct rpc_task *task)
 
        if ((n = ntohl(*p++)) != RPC_REPLY) {
                dprintk("RPC: %5u %s: not an RPC reply: %x\n",
-                               task->tk_pid, __FUNCTION__, n);
+                               task->tk_pid, __func__, n);
                goto out_garbage;
        }
        if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
@@ -1376,13 +1349,13 @@ call_verify(struct rpc_task *task)
                        case RPC_MISMATCH:
                                dprintk("RPC: %5u %s: RPC call version "
                                                "mismatch!\n",
-                                               task->tk_pid, __FUNCTION__);
+                                               task->tk_pid, __func__);
                                error = -EPROTONOSUPPORT;
                                goto out_err;
                        default:
                                dprintk("RPC: %5u %s: RPC call rejected, "
                                                "unknown error: %x\n",
-                                               task->tk_pid, __FUNCTION__, n);
+                                               task->tk_pid, __func__, n);
                                goto out_eio;
                }
                if (--len < 0)
@@ -1396,7 +1369,7 @@ call_verify(struct rpc_task *task)
                                break;
                        task->tk_cred_retry--;
                        dprintk("RPC: %5u %s: retry stale creds\n",
-                                       task->tk_pid, __FUNCTION__);
+                                       task->tk_pid, __func__);
                        rpcauth_invalcred(task);
                        /* Ensure we obtain a new XID! */
                        xprt_release(task);
@@ -1409,7 +1382,7 @@ call_verify(struct rpc_task *task)
                                break;
                        task->tk_garb_retry--;
                        dprintk("RPC: %5u %s: retry garbled creds\n",
-                                       task->tk_pid, __FUNCTION__);
+                                       task->tk_pid, __func__);
                        task->tk_action = call_bind;
                        goto out_retry;
                case RPC_AUTH_TOOWEAK:
@@ -1418,16 +1391,16 @@ call_verify(struct rpc_task *task)
                        break;
                default:
                        dprintk("RPC: %5u %s: unknown auth error: %x\n",
-                                       task->tk_pid, __FUNCTION__, n);
+                                       task->tk_pid, __func__, n);
                        error = -EIO;
                }
                dprintk("RPC: %5u %s: call rejected %d\n",
-                               task->tk_pid, __FUNCTION__, n);
+                               task->tk_pid, __func__, n);
                goto out_err;
        }
        if (!(p = rpcauth_checkverf(task, p))) {
                dprintk("RPC: %5u %s: auth check failed\n",
-                               task->tk_pid, __FUNCTION__);
+                               task->tk_pid, __func__);
                goto out_garbage;               /* bad verifier, retry */
        }
        len = p - (__be32 *)iov->iov_base - 1;
@@ -1438,14 +1411,14 @@ call_verify(struct rpc_task *task)
                return p;
        case RPC_PROG_UNAVAIL:
                dprintk("RPC: %5u %s: program %u is unsupported by server %s\n",
-                               task->tk_pid, __FUNCTION__,
+                               task->tk_pid, __func__,
                                (unsigned int)task->tk_client->cl_prog,
                                task->tk_client->cl_server);
                error = -EPFNOSUPPORT;
                goto out_err;
        case RPC_PROG_MISMATCH:
                dprintk("RPC: %5u %s: program %u, version %u unsupported by "
-                               "server %s\n", task->tk_pid, __FUNCTION__,
+                               "server %s\n", task->tk_pid, __func__,
                                (unsigned int)task->tk_client->cl_prog,
                                (unsigned int)task->tk_client->cl_vers,
                                task->tk_client->cl_server);
@@ -1454,7 +1427,7 @@ call_verify(struct rpc_task *task)
        case RPC_PROC_UNAVAIL:
                dprintk("RPC: %5u %s: proc %p unsupported by program %u, "
                                "version %u on server %s\n",
-                               task->tk_pid, __FUNCTION__,
+                               task->tk_pid, __func__,
                                task->tk_msg.rpc_proc,
                                task->tk_client->cl_prog,
                                task->tk_client->cl_vers,
@@ -1463,11 +1436,11 @@ call_verify(struct rpc_task *task)
                goto out_err;
        case RPC_GARBAGE_ARGS:
                dprintk("RPC: %5u %s: server saw garbage\n",
-                               task->tk_pid, __FUNCTION__);
+                               task->tk_pid, __func__);
                break;                  /* retry */
        default:
                dprintk("RPC: %5u %s: server accept status: %x\n",
-                               task->tk_pid, __FUNCTION__, n);
+                               task->tk_pid, __func__, n);
                /* Also retry */
        }
 
@@ -1476,7 +1449,7 @@ out_garbage:
        if (task->tk_garb_retry) {
                task->tk_garb_retry--;
                dprintk("RPC: %5u %s: retrying\n",
-                               task->tk_pid, __FUNCTION__);
+                               task->tk_pid, __func__);
                task->tk_action = call_bind;
 out_retry:
                return ERR_PTR(-EAGAIN);
@@ -1486,11 +1459,11 @@ out_eio:
 out_err:
        rpc_exit(task, error);
        dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,
-                       __FUNCTION__, error);
+                       __func__, error);
        return ERR_PTR(error);
 out_overflow:
        dprintk("RPC: %5u %s: server reply was truncated.\n", task->tk_pid,
-                       __FUNCTION__);
+                       __func__);
        goto out_garbage;
 }
 
@@ -1527,7 +1500,13 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
                .rpc_proc = &rpcproc_null,
                .rpc_cred = cred,
        };
-       return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL);
+       struct rpc_task_setup task_setup_data = {
+               .rpc_client = clnt,
+               .rpc_message = &msg,
+               .callback_ops = &rpc_default_ops,
+               .flags = flags,
+       };
+       return rpc_run_task(&task_setup_data);
 }
 EXPORT_SYMBOL_GPL(rpc_call_null);