Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16be2d20 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

SUNRPC: Refactor a part of socket connect logic into a helper function



Finishing a socket connect is the same for IPv4 and IPv6, so split it out
into a helper.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 90058d37
Loading
Loading
Loading
Loading
+72 −59
Original line number Diff line number Diff line
@@ -1323,6 +1323,35 @@ static inline void xs_reclassify_socket(struct socket *sock)
}
#endif

static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
{
	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);

	if (!transport->inet) {
		struct sock *sk = sock->sk;

		write_lock_bh(&sk->sk_callback_lock);

		sk->sk_user_data = xprt;
		transport->old_data_ready = sk->sk_data_ready;
		transport->old_state_change = sk->sk_state_change;
		transport->old_write_space = sk->sk_write_space;
		sk->sk_data_ready = xs_udp_data_ready;
		sk->sk_write_space = xs_udp_write_space;
		sk->sk_no_check = UDP_CSUM_NORCV;
		sk->sk_allocation = GFP_ATOMIC;

		xprt_set_connected(xprt);

		/* Reset to new socket */
		transport->sock = sock;
		transport->inet = sk;

		write_unlock_bh(&sk->sk_callback_lock);
	}
	xs_udp_do_set_buffer_size(xprt);
}

/**
 * xs_udp_connect_worker - set up a UDP socket
 * @work: RPC transport to connect
@@ -1357,29 +1386,7 @@ static void xs_udp_connect_worker(struct work_struct *work)
	dprintk("RPC:       worker connecting xprt %p to address: %s\n",
			xprt, xprt->address_strings[RPC_DISPLAY_ALL]);

	if (!transport->inet) {
		struct sock *sk = sock->sk;

		write_lock_bh(&sk->sk_callback_lock);

		sk->sk_user_data = xprt;
		transport->old_data_ready = sk->sk_data_ready;
		transport->old_state_change = sk->sk_state_change;
		transport->old_write_space = sk->sk_write_space;
		sk->sk_data_ready = xs_udp_data_ready;
		sk->sk_write_space = xs_udp_write_space;
		sk->sk_no_check = UDP_CSUM_NORCV;
		sk->sk_allocation = GFP_ATOMIC;

		xprt_set_connected(xprt);

		/* Reset to new socket */
		transport->sock = sock;
		transport->inet = sk;

		write_unlock_bh(&sk->sk_callback_lock);
	}
	xs_udp_do_set_buffer_size(xprt);
	xs_udp_finish_connecting(xprt, sock);
	status = 0;
out:
	xprt_wake_pending_tasks(xprt, status);
@@ -1410,42 +1417,9 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
				result);
}

/**
 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
 * @work: RPC transport to connect
 *
 * Invoked by a work queue tasklet.
 */
static void xs_tcp_connect_worker(struct work_struct *work)
static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
{
	struct sock_xprt *transport =
		container_of(work, struct sock_xprt, connect_worker.work);
	struct rpc_xprt *xprt = &transport->xprt;
	struct socket *sock = transport->sock;
	int err, status = -EIO;

	if (xprt->shutdown || !xprt_bound(xprt))
		goto out;

	if (!sock) {
		/* start from scratch */
		if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
			dprintk("RPC:       can't create TCP transport "
					"socket (%d).\n", -err);
			goto out;
		}
		xs_reclassify_socket(sock);

		if (xs_bind4(transport, sock)) {
			sock_release(sock);
			goto out;
		}
	} else
		/* "close" the socket, preserving the local port */
		xs_tcp_reuse_connection(xprt);

	dprintk("RPC:       worker connecting xprt %p to address: %s\n",
			xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);

	if (!transport->inet) {
		struct sock *sk = sock->sk;
@@ -1479,8 +1453,47 @@ static void xs_tcp_connect_worker(struct work_struct *work)
	/* Tell the socket layer to start connecting... */
	xprt->stat.connect_count++;
	xprt->stat.connect_start = jiffies;
	status = kernel_connect(sock, (struct sockaddr *) &xprt->addr,
	return kernel_connect(sock, (struct sockaddr *) &xprt->addr,
			xprt->addrlen, O_NONBLOCK);
}

/**
 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
 * @work: RPC transport to connect
 *
 * Invoked by a work queue tasklet.
 */
static void xs_tcp_connect_worker(struct work_struct *work)
{
	struct sock_xprt *transport =
		container_of(work, struct sock_xprt, connect_worker.work);
	struct rpc_xprt *xprt = &transport->xprt;
	struct socket *sock = transport->sock;
	int err, status = -EIO;

	if (xprt->shutdown || !xprt_bound(xprt))
		goto out;

	if (!sock) {
		/* start from scratch */
		if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
			dprintk("RPC:       can't create TCP transport socket (%d).\n", -err);
			goto out;
		}
		xs_reclassify_socket(sock);

		if (xs_bind4(transport, sock) < 0) {
			sock_release(sock);
			goto out;
		}
	} else
		/* "close" the socket, preserving the local port */
		xs_tcp_reuse_connection(xprt);

	dprintk("RPC:       worker connecting xprt %p to address: %s\n",
			xprt, xprt->address_strings[RPC_DISPLAY_ALL]);

	status = xs_tcp_finish_connecting(xprt, sock);
	dprintk("RPC:       %p connect status %d connected %d sock state %d\n",
			xprt, -status, xprt_connected(xprt),
			sock->sk->sk_state);