aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2013-02-20 17:52:19 -0500
committerJ. Bruce Fields <bfields@redhat.com>2013-02-28 12:47:17 -0500
commitdc107402ae06286a9ed33c32daf3f35514a7cb8d (patch)
tree771882a1a62e2c56ae2c262764690417cecd776a
parent56edc86b5a72bdbc86358e57fb09165136baf0b8 (diff)
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: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--net/sunrpc/xprtsock.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index bbc09154df8d..4dc8eb24ac2c 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,
1866 * @xprt: RPC transport to connect 1866 * @xprt: RPC transport to connect
1867 * @transport: socket transport to connect 1867 * @transport: socket transport to connect
1868 * @create_sock: function to create a socket of the correct type 1868 * @create_sock: function to create a socket of the correct type
1869 *
1870 * Invoked by a work queue tasklet.
1871 */ 1869 */
1872static void xs_local_setup_socket(struct work_struct *work) 1870static int xs_local_setup_socket(struct sock_xprt *transport)
1873{ 1871{
1874 struct sock_xprt *transport =
1875 container_of(work, struct sock_xprt, connect_worker.work);
1876 struct rpc_xprt *xprt = &transport->xprt; 1872 struct rpc_xprt *xprt = &transport->xprt;
1877 struct socket *sock; 1873 struct socket *sock;
1878 int status = -EIO; 1874 int status = -EIO;
@@ -1917,6 +1913,31 @@ out:
1917 xprt_clear_connecting(xprt); 1913 xprt_clear_connecting(xprt);
1918 xprt_wake_pending_tasks(xprt, status); 1914 xprt_wake_pending_tasks(xprt, status);
1919 current->flags &= ~PF_FSTRANS; 1915 current->flags &= ~PF_FSTRANS;
1916 return status;
1917}
1918
1919static void xs_local_connect(struct rpc_task *task)
1920{
1921 struct rpc_xprt *xprt = task->tk_xprt;
1922 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1923 int ret;
1924
1925 if (RPC_IS_ASYNC(task)) {
1926 /*
1927 * We want the AF_LOCAL connect to be resolved in the
1928 * filesystem namespace of the process making the rpc
1929 * call. Thus we connect synchronously.
1930 *
1931 * If we want to support asynchronous AF_LOCAL calls,
1932 * we'll need to figure out how to pass a namespace to
1933 * connect.
1934 */
1935 rpc_exit(task, -ENOTCONN);
1936 return;
1937 }
1938 ret = xs_local_setup_socket(transport);
1939 if (ret && !RPC_IS_SOFTCONN(task))
1940 msleep_interruptible(15000);
1920} 1941}
1921 1942
1922#ifdef CONFIG_SUNRPC_SWAP 1943#ifdef CONFIG_SUNRPC_SWAP
@@ -2454,7 +2475,7 @@ static struct rpc_xprt_ops xs_local_ops = {
2454 .alloc_slot = xprt_alloc_slot, 2475 .alloc_slot = xprt_alloc_slot,
2455 .rpcbind = xs_local_rpcbind, 2476 .rpcbind = xs_local_rpcbind,
2456 .set_port = xs_local_set_port, 2477 .set_port = xs_local_set_port,
2457 .connect = xs_connect, 2478 .connect = xs_local_connect,
2458 .buf_alloc = rpc_malloc, 2479 .buf_alloc = rpc_malloc,
2459 .buf_free = rpc_free, 2480 .buf_free = rpc_free,
2460 .send_request = xs_local_send_request, 2481 .send_request = xs_local_send_request,
@@ -2627,8 +2648,6 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
2627 goto out_err; 2648 goto out_err;
2628 } 2649 }
2629 xprt_set_bound(xprt); 2650 xprt_set_bound(xprt);
2630 INIT_DELAYED_WORK(&transport->connect_worker,
2631 xs_local_setup_socket);
2632 xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); 2651 xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
2633 break; 2652 break;
2634 default: 2653 default: