Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
[linux-drm-fsl-dcu.git] / net / sunrpc / pmap_clnt.c
index c04609d3476a986e630097998a6eeecb76551870..f4e1357bc186e63796592244e497b80a80b25ef3 100644 (file)
@@ -101,11 +101,13 @@ void rpc_getport(struct rpc_task *task)
        /* Autobind on cloned rpc clients is discouraged */
        BUG_ON(clnt->cl_parent != clnt);
 
-       if (xprt_test_and_set_binding(xprt)) {
-               task->tk_status = -EACCES;      /* tell caller to check again */
-               rpc_sleep_on(&xprt->binding, task, NULL, NULL);
-               return;
-       }
+       status = -EACCES;               /* tell caller to check again */
+       if (xprt_test_and_set_binding(xprt))
+               goto bailout_nowake;
+
+       /* Put self on queue before sending rpcbind request, in case
+        * pmap_getport_done completes before we return from rpc_run_task */
+       rpc_sleep_on(&xprt->binding, task, NULL, NULL);
 
        /* Someone else may have bound if we slept */
        status = 0;
@@ -132,9 +134,7 @@ void rpc_getport(struct rpc_task *task)
        child = rpc_run_task(pmap_clnt, RPC_TASK_ASYNC, &pmap_getport_ops, map);
        if (IS_ERR(child))
                goto bailout;
-       rpc_release_task(child);
-
-       rpc_sleep_on(&xprt->binding, task, NULL, NULL);
+       rpc_put_task(child);
 
        task->tk_xprt->stat.bind_count++;
        return;
@@ -143,8 +143,9 @@ bailout:
        pmap_map_free(map);
        xprt_put(xprt);
 bailout_nofree:
-       task->tk_status = status;
        pmap_wake_portmap_waiters(xprt, status);
+bailout_nowake:
+       task->tk_status = status;
 }
 
 #ifdef CONFIG_ROOT_NFS
@@ -300,7 +301,7 @@ static struct rpc_clnt *pmap_create(char *hostname, struct sockaddr_in *srvaddr,
 /*
  * XDR encode/decode functions for PMAP
  */
-static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args *map)
+static int xdr_encode_mapping(struct rpc_rqst *req, __be32 *p, struct portmap_args *map)
 {
        dprintk("RPC: xdr_encode_mapping(%u, %u, %u, %u)\n",
                map->pm_prog, map->pm_vers, map->pm_prot, map->pm_port);
@@ -313,13 +314,13 @@ static int xdr_encode_mapping(struct rpc_rqst *req, u32 *p, struct portmap_args
        return 0;
 }
 
-static int xdr_decode_port(struct rpc_rqst *req, u32 *p, unsigned short *portp)
+static int xdr_decode_port(struct rpc_rqst *req, __be32 *p, unsigned short *portp)
 {
        *portp = (unsigned short) ntohl(*p++);
        return 0;
 }
 
-static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
+static int xdr_decode_bool(struct rpc_rqst *req, __be32 *p, unsigned int *boolp)
 {
        *boolp = (unsigned int) ntohl(*p++);
        return 0;
@@ -328,7 +329,7 @@ static int xdr_decode_bool(struct rpc_rqst *req, u32 *p, unsigned int *boolp)
 static struct rpc_procinfo     pmap_procedures[] = {
 [PMAP_SET] = {
          .p_proc               = PMAP_SET,
-         .p_encode             = (kxdrproc_t) xdr_encode_mapping,      
+         .p_encode             = (kxdrproc_t) xdr_encode_mapping,
          .p_decode             = (kxdrproc_t) xdr_decode_bool,
          .p_bufsiz             = 4,
          .p_count              = 1,
@@ -337,7 +338,7 @@ static struct rpc_procinfo  pmap_procedures[] = {
        },
 [PMAP_UNSET] = {
          .p_proc               = PMAP_UNSET,
-         .p_encode             = (kxdrproc_t) xdr_encode_mapping,      
+         .p_encode             = (kxdrproc_t) xdr_encode_mapping,
          .p_decode             = (kxdrproc_t) xdr_decode_bool,
          .p_bufsiz             = 4,
          .p_count              = 1,