Skip to content

Commit 2dc6b11

Browse files
Alexander Aringteigland
authored andcommitted
fs: dlm: introduce generic listen
This patch combines each transport layer listen functionality into one listen function. Per transport layer differences are provided by additional callbacks in dlm_proto_ops. This patch drops silently sock_set_keepalive() for listen tcp sockets only. This socket option is not set at connecting sockets, I also don't see the sense of set keepalive for sockets which are created by accept() only. Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
1 parent a66c008 commit 2dc6b11

1 file changed

Lines changed: 113 additions & 115 deletions

File tree

fs/dlm/lowcomms.c

Lines changed: 113 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ struct dlm_node_addr {
143143
};
144144

145145
struct dlm_proto_ops {
146+
const char *name;
147+
int proto;
148+
149+
int (*listen_validate)(void);
150+
void (*listen_sockopts)(struct socket *sock);
151+
int (*listen_bind)(struct socket *sock);
152+
146153
/* What to do to connect */
147154
void (*connect_action)(struct connection *con);
148155
/* What to do to shutdown */
@@ -1327,59 +1334,6 @@ static void tcp_connect_to_sock(struct connection *con)
13271334
return;
13281335
}
13291336

1330-
/* On error caller must run dlm_close_sock() for the
1331-
* listen connection socket.
1332-
*/
1333-
static int tcp_create_listen_sock(struct listen_connection *con,
1334-
struct sockaddr_storage *saddr)
1335-
{
1336-
struct socket *sock = NULL;
1337-
int result = 0;
1338-
int addr_len;
1339-
1340-
if (dlm_local_addr[0]->ss_family == AF_INET)
1341-
addr_len = sizeof(struct sockaddr_in);
1342-
else
1343-
addr_len = sizeof(struct sockaddr_in6);
1344-
1345-
/* Create a socket to communicate with */
1346-
result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
1347-
SOCK_STREAM, IPPROTO_TCP, &sock);
1348-
if (result < 0) {
1349-
log_print("Can't create listening comms socket");
1350-
goto create_out;
1351-
}
1352-
1353-
sock_set_mark(sock->sk, dlm_config.ci_mark);
1354-
1355-
/* Turn off Nagle's algorithm */
1356-
tcp_sock_set_nodelay(sock->sk);
1357-
1358-
sock_set_reuseaddr(sock->sk);
1359-
1360-
add_listen_sock(sock, con);
1361-
1362-
/* Bind to our port */
1363-
make_sockaddr(saddr, dlm_config.ci_tcp_port, &addr_len);
1364-
result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len);
1365-
if (result < 0) {
1366-
log_print("Can't bind to port %d", dlm_config.ci_tcp_port);
1367-
goto create_out;
1368-
}
1369-
sock_set_keepalive(sock->sk);
1370-
1371-
result = sock->ops->listen(sock, 5);
1372-
if (result < 0) {
1373-
log_print("Can't listen on port %d", dlm_config.ci_tcp_port);
1374-
goto create_out;
1375-
}
1376-
1377-
return 0;
1378-
1379-
create_out:
1380-
return result;
1381-
}
1382-
13831337
/* Get local addresses */
13841338
static void init_local(void)
13851339
{
@@ -1406,63 +1360,6 @@ static void deinit_local(void)
14061360
kfree(dlm_local_addr[i]);
14071361
}
14081362

1409-
/* Initialise SCTP socket and bind to all interfaces
1410-
* On error caller must run dlm_close_sock() for the
1411-
* listen connection socket.
1412-
*/
1413-
static int sctp_listen_for_all(struct listen_connection *con)
1414-
{
1415-
struct socket *sock = NULL;
1416-
int result = -EINVAL;
1417-
1418-
log_print("Using SCTP for communications");
1419-
1420-
result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
1421-
SOCK_STREAM, IPPROTO_SCTP, &sock);
1422-
if (result < 0) {
1423-
log_print("Can't create comms socket, check SCTP is loaded");
1424-
goto out;
1425-
}
1426-
1427-
sock_set_rcvbuf(sock->sk, NEEDED_RMEM);
1428-
sock_set_mark(sock->sk, dlm_config.ci_mark);
1429-
sctp_sock_set_nodelay(sock->sk);
1430-
1431-
add_listen_sock(sock, con);
1432-
1433-
/* Bind to all addresses. */
1434-
result = sctp_bind_addrs(con->sock, dlm_config.ci_tcp_port);
1435-
if (result < 0)
1436-
goto out;
1437-
1438-
result = sock->ops->listen(sock, 5);
1439-
if (result < 0) {
1440-
log_print("Can't set socket listening");
1441-
goto out;
1442-
}
1443-
1444-
return 0;
1445-
1446-
out:
1447-
return result;
1448-
}
1449-
1450-
static int tcp_listen_for_all(void)
1451-
{
1452-
/* We don't support multi-homed hosts */
1453-
if (dlm_local_count > 1) {
1454-
log_print("TCP protocol can't handle multi-homed hosts, "
1455-
"try SCTP");
1456-
return -EINVAL;
1457-
}
1458-
1459-
log_print("Using TCP for communications");
1460-
1461-
return tcp_create_listen_sock(&listen_con, dlm_local_addr[0]);
1462-
}
1463-
1464-
1465-
14661363
static struct writequeue_entry *new_writequeue_entry(struct connection *con,
14671364
gfp_t allocation)
14681365
{
@@ -1959,13 +1856,112 @@ void dlm_lowcomms_stop(void)
19591856
dlm_proto_ops = NULL;
19601857
}
19611858

1859+
static int dlm_listen_for_all(void)
1860+
{
1861+
struct socket *sock;
1862+
int result;
1863+
1864+
log_print("Using %s for communications",
1865+
dlm_proto_ops->name);
1866+
1867+
if (dlm_proto_ops->listen_validate) {
1868+
result = dlm_proto_ops->listen_validate();
1869+
if (result < 0)
1870+
return result;
1871+
}
1872+
1873+
result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family,
1874+
SOCK_STREAM, dlm_proto_ops->proto, &sock);
1875+
if (result < 0) {
1876+
log_print("Can't create comms socket, check SCTP is loaded");
1877+
goto out;
1878+
}
1879+
1880+
sock_set_mark(sock->sk, dlm_config.ci_mark);
1881+
dlm_proto_ops->listen_sockopts(sock);
1882+
1883+
result = dlm_proto_ops->listen_bind(sock);
1884+
if (result < 0)
1885+
goto out;
1886+
1887+
save_listen_callbacks(sock);
1888+
add_listen_sock(sock, &listen_con);
1889+
1890+
INIT_WORK(&listen_con.rwork, process_listen_recv_socket);
1891+
result = sock->ops->listen(sock, 5);
1892+
if (result < 0) {
1893+
dlm_close_sock(&listen_con.sock);
1894+
goto out;
1895+
}
1896+
1897+
return 0;
1898+
1899+
out:
1900+
sock_release(sock);
1901+
return result;
1902+
}
1903+
1904+
static int dlm_tcp_listen_validate(void)
1905+
{
1906+
/* We don't support multi-homed hosts */
1907+
if (dlm_local_count > 1) {
1908+
log_print("TCP protocol can't handle multi-homed hosts, try SCTP");
1909+
return -EINVAL;
1910+
}
1911+
1912+
return 0;
1913+
}
1914+
1915+
static void dlm_tcp_sockopts(struct socket *sock)
1916+
{
1917+
/* Turn off Nagle's algorithm */
1918+
tcp_sock_set_nodelay(sock->sk);
1919+
}
1920+
1921+
static void dlm_tcp_listen_sockopts(struct socket *sock)
1922+
{
1923+
dlm_tcp_sockopts(sock);
1924+
sock_set_reuseaddr(sock->sk);
1925+
}
1926+
1927+
static int dlm_tcp_listen_bind(struct socket *sock)
1928+
{
1929+
int addr_len;
1930+
1931+
/* Bind to our port */
1932+
make_sockaddr(dlm_local_addr[0], dlm_config.ci_tcp_port, &addr_len);
1933+
return sock->ops->bind(sock, (struct sockaddr *)dlm_local_addr[0],
1934+
addr_len);
1935+
}
1936+
19621937
static const struct dlm_proto_ops dlm_tcp_ops = {
1938+
.name = "TCP",
1939+
.proto = IPPROTO_TCP,
1940+
.listen_validate = dlm_tcp_listen_validate,
1941+
.listen_sockopts = dlm_tcp_listen_sockopts,
1942+
.listen_bind = dlm_tcp_listen_bind,
19631943
.connect_action = tcp_connect_to_sock,
19641944
.shutdown_action = dlm_tcp_shutdown,
19651945
.eof_condition = tcp_eof_condition,
19661946
};
19671947

1948+
static int dlm_sctp_bind_listen(struct socket *sock)
1949+
{
1950+
return sctp_bind_addrs(sock, dlm_config.ci_tcp_port);
1951+
}
1952+
1953+
static void dlm_sctp_sockopts(struct socket *sock)
1954+
{
1955+
/* Turn off Nagle's algorithm */
1956+
sctp_sock_set_nodelay(sock->sk);
1957+
sock_set_rcvbuf(sock->sk, NEEDED_RMEM);
1958+
}
1959+
19681960
static const struct dlm_proto_ops dlm_sctp_ops = {
1961+
.name = "SCTP",
1962+
.proto = IPPROTO_SCTP,
1963+
.listen_sockopts = dlm_sctp_sockopts,
1964+
.listen_bind = dlm_sctp_bind_listen,
19691965
.connect_action = sctp_connect_to_sock,
19701966
};
19711967

@@ -1996,24 +1992,26 @@ int dlm_lowcomms_start(void)
19961992
switch (dlm_config.ci_protocol) {
19971993
case DLM_PROTO_TCP:
19981994
dlm_proto_ops = &dlm_tcp_ops;
1999-
error = tcp_listen_for_all();
20001995
break;
20011996
case DLM_PROTO_SCTP:
20021997
dlm_proto_ops = &dlm_sctp_ops;
2003-
error = sctp_listen_for_all(&listen_con);
20041998
break;
20051999
default:
20062000
log_print("Invalid protocol identifier %d set",
20072001
dlm_config.ci_protocol);
20082002
error = -EINVAL;
2009-
break;
2003+
goto fail_proto_ops;
20102004
}
2005+
2006+
error = dlm_listen_for_all();
20112007
if (error)
2012-
goto fail_unlisten;
2008+
goto fail_listen;
20132009

20142010
return 0;
20152011

2016-
fail_unlisten:
2012+
fail_listen:
2013+
dlm_proto_ops = NULL;
2014+
fail_proto_ops:
20172015
dlm_allow_conn = 0;
20182016
dlm_close_sock(&listen_con.sock);
20192017
work_stop();

0 commit comments

Comments
 (0)