Commit dc107402 authored by J. Bruce Fields's avatar J. Bruce Fields

SUNRPC: make AF_LOCAL connect synchronous

It doesn't appear that anyone actually needs to connect asynchronously.

Also, using a workqueue for the connect means we lose the namespace
information from the original process.  This is a problem since there's
no way to explicitly pass in a filesystem namespace for resolution of an
AF_LOCAL address.
Acked-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 56edc86b
...@@ -1866,13 +1866,9 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, ...@@ -1866,13 +1866,9 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
* @xprt: RPC transport to connect * @xprt: RPC transport to connect
* @transport: socket transport to connect * @transport: socket transport to connect
* @create_sock: function to create a socket of the correct type * @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 rpc_xprt *xprt = &transport->xprt;
struct socket *sock; struct socket *sock;
int status = -EIO; int status = -EIO;
...@@ -1917,6 +1913,31 @@ static void xs_local_setup_socket(struct work_struct *work) ...@@ -1917,6 +1913,31 @@ static void xs_local_setup_socket(struct work_struct *work)
xprt_clear_connecting(xprt); xprt_clear_connecting(xprt);
xprt_wake_pending_tasks(xprt, status); xprt_wake_pending_tasks(xprt, status);
current->flags &= ~PF_FSTRANS; 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 #ifdef CONFIG_SUNRPC_SWAP
...@@ -2454,7 +2475,7 @@ static struct rpc_xprt_ops xs_local_ops = { ...@@ -2454,7 +2475,7 @@ static struct rpc_xprt_ops xs_local_ops = {
.alloc_slot = xprt_alloc_slot, .alloc_slot = xprt_alloc_slot,
.rpcbind = xs_local_rpcbind, .rpcbind = xs_local_rpcbind,
.set_port = xs_local_set_port, .set_port = xs_local_set_port,
.connect = xs_connect, .connect = xs_local_connect,
.buf_alloc = rpc_malloc, .buf_alloc = rpc_malloc,
.buf_free = rpc_free, .buf_free = rpc_free,
.send_request = xs_local_send_request, .send_request = xs_local_send_request,
...@@ -2627,8 +2648,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args) ...@@ -2627,8 +2648,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
goto out_err; goto out_err;
} }
xprt_set_bound(xprt); xprt_set_bound(xprt);
INIT_DELAYED_WORK(&transport->connect_worker,
xs_local_setup_socket);
xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment