aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2016-09-23 14:23:26 -0400
committerDavid Teigland <teigland@redhat.com>2016-10-19 12:00:03 -0400
commit3735b4b9f1c102dcaf70241225339bdea4447dc8 (patch)
tree0491950ff3867a194f0c7eba9de96e3c98af9e27 /fs/dlm
parent7963b8a59845eabafa0e8ff330a2e0884f0279a9 (diff)
dlm: don't save callbacks after accept
When DLM calls accept() on a socket, the comm code copies the sk after we've saved its callbacks. Afterward, it calls add_sock which saves the callbacks a second time. Since the error reporting function lowcomms_error_report calls the previous callback too, this results in a recursive call to itself. This patch adds a new parameter to function add_sock to tell whether to save the callbacks. Function tcp_accept_from_sock (and its sctp counterpart) then calls it with false to avoid the recursion. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/lowcomms.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 609998de533e..485494e5a28e 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -541,7 +541,7 @@ static void restore_callbacks(struct connection *con, struct sock *sk)
541} 541}
542 542
543/* Make a socket active */ 543/* Make a socket active */
544static void add_sock(struct socket *sock, struct connection *con) 544static void add_sock(struct socket *sock, struct connection *con, bool save_cb)
545{ 545{
546 struct sock *sk = sock->sk; 546 struct sock *sk = sock->sk;
547 547
@@ -549,7 +549,7 @@ static void add_sock(struct socket *sock, struct connection *con)
549 con->sock = sock; 549 con->sock = sock;
550 550
551 sk->sk_user_data = con; 551 sk->sk_user_data = con;
552 if (!test_bit(CF_IS_OTHERCON, &con->flags)) 552 if (save_cb)
553 save_callbacks(con, sk); 553 save_callbacks(con, sk);
554 /* Install a data_ready callback */ 554 /* Install a data_ready callback */
555 sk->sk_data_ready = lowcomms_data_ready; 555 sk->sk_data_ready = lowcomms_data_ready;
@@ -806,7 +806,7 @@ static int tcp_accept_from_sock(struct connection *con)
806 newcon->othercon = othercon; 806 newcon->othercon = othercon;
807 othercon->sock = newsock; 807 othercon->sock = newsock;
808 newsock->sk->sk_user_data = othercon; 808 newsock->sk->sk_user_data = othercon;
809 add_sock(newsock, othercon); 809 add_sock(newsock, othercon, false);
810 addcon = othercon; 810 addcon = othercon;
811 } 811 }
812 else { 812 else {
@@ -819,7 +819,10 @@ static int tcp_accept_from_sock(struct connection *con)
819 else { 819 else {
820 newsock->sk->sk_user_data = newcon; 820 newsock->sk->sk_user_data = newcon;
821 newcon->rx_action = receive_from_sock; 821 newcon->rx_action = receive_from_sock;
822 add_sock(newsock, newcon); 822 /* accept copies the sk after we've saved the callbacks, so we
823 don't want to save them a second time or comm errors will
824 result in calling sk_error_report recursively. */
825 add_sock(newsock, newcon, false);
823 addcon = newcon; 826 addcon = newcon;
824 } 827 }
825 828
@@ -919,7 +922,7 @@ static int sctp_accept_from_sock(struct connection *con)
919 newcon->othercon = othercon; 922 newcon->othercon = othercon;
920 othercon->sock = newsock; 923 othercon->sock = newsock;
921 newsock->sk->sk_user_data = othercon; 924 newsock->sk->sk_user_data = othercon;
922 add_sock(newsock, othercon); 925 add_sock(newsock, othercon, false);
923 addcon = othercon; 926 addcon = othercon;
924 } else { 927 } else {
925 printk("Extra connection from node %d attempted\n", nodeid); 928 printk("Extra connection from node %d attempted\n", nodeid);
@@ -930,7 +933,7 @@ static int sctp_accept_from_sock(struct connection *con)
930 } else { 933 } else {
931 newsock->sk->sk_user_data = newcon; 934 newsock->sk->sk_user_data = newcon;
932 newcon->rx_action = receive_from_sock; 935 newcon->rx_action = receive_from_sock;
933 add_sock(newsock, newcon); 936 add_sock(newsock, newcon, false);
934 addcon = newcon; 937 addcon = newcon;
935 } 938 }
936 939
@@ -1058,7 +1061,7 @@ static void sctp_connect_to_sock(struct connection *con)
1058 sock->sk->sk_user_data = con; 1061 sock->sk->sk_user_data = con;
1059 con->rx_action = receive_from_sock; 1062 con->rx_action = receive_from_sock;
1060 con->connect_action = sctp_connect_to_sock; 1063 con->connect_action = sctp_connect_to_sock;
1061 add_sock(sock, con); 1064 add_sock(sock, con, true);
1062 1065
1063 /* Bind to all addresses. */ 1066 /* Bind to all addresses. */
1064 if (sctp_bind_addrs(con, 0)) 1067 if (sctp_bind_addrs(con, 0))
@@ -1146,7 +1149,7 @@ static void tcp_connect_to_sock(struct connection *con)
1146 sock->sk->sk_user_data = con; 1149 sock->sk->sk_user_data = con;
1147 con->rx_action = receive_from_sock; 1150 con->rx_action = receive_from_sock;
1148 con->connect_action = tcp_connect_to_sock; 1151 con->connect_action = tcp_connect_to_sock;
1149 add_sock(sock, con); 1152 add_sock(sock, con, true);
1150 1153
1151 /* Bind to our cluster-known address connecting to avoid 1154 /* Bind to our cluster-known address connecting to avoid
1152 routing problems */ 1155 routing problems */
@@ -1366,7 +1369,7 @@ static int tcp_listen_for_all(void)
1366 1369
1367 sock = tcp_create_listen_sock(con, dlm_local_addr[0]); 1370 sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
1368 if (sock) { 1371 if (sock) {
1369 add_sock(sock, con); 1372 add_sock(sock, con, true);
1370 result = 0; 1373 result = 0;
1371 } 1374 }
1372 else { 1375 else {