Skip to content

Commit

Permalink
dlm: use the tcp version of accept_from_sock for sctp as well
Browse files Browse the repository at this point in the history
The only difference between a few missing fixes applied to the SCTP
one is that TCP uses ->getpeername to get the remote address, while
SCTP uses kernel_getsockopt(.. SCTP_PRIMARY_ADDR).  But given that
getpeername is defined to return the primary address for sctp, there
doesn't seem to be any reason for the different way of quering the
peername, or all the code duplication.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Christoph Hellwig authored and David S. Miller committed May 27, 2020
1 parent 50ce4c0 commit 0774dc7
Showing 1 changed file with 3 additions and 120 deletions.
123 changes: 3 additions & 120 deletions fs/dlm/lowcomms.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ static int receive_from_sock(struct connection *con)
}

/* Listening socket is busy, accept a connection */
static int tcp_accept_from_sock(struct connection *con)
static int accept_from_sock(struct connection *con)
{
int result;
struct sockaddr_storage peeraddr;
Expand Down Expand Up @@ -852,123 +852,6 @@ static int tcp_accept_from_sock(struct connection *con)
return result;
}

static int sctp_accept_from_sock(struct connection *con)
{
/* Check that the new node is in the lockspace */
struct sctp_prim prim;
int nodeid;
int prim_len, ret;
int addr_len;
struct connection *newcon;
struct connection *addcon;
struct socket *newsock;

mutex_lock(&connections_lock);
if (!dlm_allow_conn) {
mutex_unlock(&connections_lock);
return -1;
}
mutex_unlock(&connections_lock);

mutex_lock_nested(&con->sock_mutex, 0);

ret = kernel_accept(con->sock, &newsock, O_NONBLOCK);
if (ret < 0)
goto accept_err;

memset(&prim, 0, sizeof(struct sctp_prim));
prim_len = sizeof(struct sctp_prim);

ret = kernel_getsockopt(newsock, IPPROTO_SCTP, SCTP_PRIMARY_ADDR,
(char *)&prim, &prim_len);
if (ret < 0) {
log_print("getsockopt/sctp_primary_addr failed: %d", ret);
goto accept_err;
}

make_sockaddr(&prim.ssp_addr, 0, &addr_len);
ret = addr_to_nodeid(&prim.ssp_addr, &nodeid);
if (ret) {
unsigned char *b = (unsigned char *)&prim.ssp_addr;

log_print("reject connect from unknown addr");
print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE,
b, sizeof(struct sockaddr_storage));
goto accept_err;
}

newcon = nodeid2con(nodeid, GFP_NOFS);
if (!newcon) {
ret = -ENOMEM;
goto accept_err;
}

mutex_lock_nested(&newcon->sock_mutex, 1);

if (newcon->sock) {
struct connection *othercon = newcon->othercon;

if (!othercon) {
othercon = kmem_cache_zalloc(con_cache, GFP_NOFS);
if (!othercon) {
log_print("failed to allocate incoming socket");
mutex_unlock(&newcon->sock_mutex);
ret = -ENOMEM;
goto accept_err;
}
othercon->nodeid = nodeid;
othercon->rx_action = receive_from_sock;
mutex_init(&othercon->sock_mutex);
INIT_LIST_HEAD(&othercon->writequeue);
spin_lock_init(&othercon->writequeue_lock);
INIT_WORK(&othercon->swork, process_send_sockets);
INIT_WORK(&othercon->rwork, process_recv_sockets);
set_bit(CF_IS_OTHERCON, &othercon->flags);
}
mutex_lock_nested(&othercon->sock_mutex, 2);
if (!othercon->sock) {
newcon->othercon = othercon;
add_sock(newsock, othercon);
addcon = othercon;
mutex_unlock(&othercon->sock_mutex);
} else {
printk("Extra connection from node %d attempted\n", nodeid);
ret = -EAGAIN;
mutex_unlock(&othercon->sock_mutex);
mutex_unlock(&newcon->sock_mutex);
goto accept_err;
}
} else {
newcon->rx_action = receive_from_sock;
add_sock(newsock, newcon);
addcon = newcon;
}

log_print("connected to %d", nodeid);

mutex_unlock(&newcon->sock_mutex);

/*
* Add it to the active queue in case we got data
* between processing the accept adding the socket
* to the read_sockets list
*/
if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags))
queue_work(recv_workqueue, &addcon->rwork);
mutex_unlock(&con->sock_mutex);

return 0;

accept_err:
mutex_unlock(&con->sock_mutex);
if (newsock)
sock_release(newsock);
if (ret != -EAGAIN)
log_print("error accepting connection from node: %d", ret);

return ret;
}

static void free_entry(struct writequeue_entry *e)
{
__free_page(e->page);
Expand Down Expand Up @@ -1253,7 +1136,7 @@ static struct socket *tcp_create_listen_sock(struct connection *con,
write_lock_bh(&sock->sk->sk_callback_lock);
sock->sk->sk_user_data = con;
save_listen_callbacks(sock);
con->rx_action = tcp_accept_from_sock;
con->rx_action = accept_from_sock;
con->connect_action = tcp_connect_to_sock;
write_unlock_bh(&sock->sk->sk_callback_lock);

Expand Down Expand Up @@ -1340,7 +1223,7 @@ static int sctp_listen_for_all(void)
save_listen_callbacks(sock);
con->sock = sock;
con->sock->sk->sk_data_ready = lowcomms_data_ready;
con->rx_action = sctp_accept_from_sock;
con->rx_action = accept_from_sock;
con->connect_action = sctp_connect_to_sock;

write_unlock_bh(&sock->sk->sk_callback_lock);
Expand Down

0 comments on commit 0774dc7

Please sign in to comment.