diff options
| -rw-r--r-- | net/sunrpc/xprtsock.c | 35 | 
1 files changed, 27 insertions, 8 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index bbc09154df8..4dc8eb24ac2 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1866,13 +1866,9 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,   * @xprt: RPC transport to connect   * @transport: socket transport to connect   * @create_sock: function to create a socket of the correct type - * - * Invoked by a work queue tasklet.   */ -static void xs_local_setup_socket(struct work_struct *work) +static int xs_local_setup_socket(struct sock_xprt *transport)  { -	struct sock_xprt *transport = -		container_of(work, struct sock_xprt, connect_worker.work);  	struct rpc_xprt *xprt = &transport->xprt;  	struct socket *sock;  	int status = -EIO; @@ -1917,6 +1913,31 @@ out:  	xprt_clear_connecting(xprt);  	xprt_wake_pending_tasks(xprt, status);  	current->flags &= ~PF_FSTRANS; +	return status; +} + +static void xs_local_connect(struct rpc_task *task) +{ +	struct rpc_xprt *xprt = task->tk_xprt; +	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); +	int ret; + +	 if (RPC_IS_ASYNC(task)) { +		/* +		 * We want the AF_LOCAL connect to be resolved in the +		 * filesystem namespace of the process making the rpc +		 * call.  Thus we connect synchronously. +		 * +		 * If we want to support asynchronous AF_LOCAL calls, +		 * we'll need to figure out how to pass a namespace to +		 * connect. +		 */ +		rpc_exit(task, -ENOTCONN); +		return; +	} +	ret = xs_local_setup_socket(transport); +	if (ret && !RPC_IS_SOFTCONN(task)) +		msleep_interruptible(15000);  }  #ifdef CONFIG_SUNRPC_SWAP @@ -2454,7 +2475,7 @@ static struct rpc_xprt_ops xs_local_ops = {  	.alloc_slot		= xprt_alloc_slot,  	.rpcbind		= xs_local_rpcbind,  	.set_port		= xs_local_set_port, -	.connect		= xs_connect, +	.connect		= xs_local_connect,  	.buf_alloc		= rpc_malloc,  	.buf_free		= rpc_free,  	.send_request		= xs_local_send_request, @@ -2627,8 +2648,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)  			goto out_err;  		}  		xprt_set_bound(xprt); -		INIT_DELAYED_WORK(&transport->connect_worker, -					xs_local_setup_socket);  		xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);  		break;  	default:  |