aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTariq Saeed <tariq.x.saeed@oracle.com>2014-06-10 18:18:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-10 18:34:46 -0400
commit79deb3c148e0ed0ac3dab9e953777b096d58b443 (patch)
tree566a713482b2537015b88fe3ef76f295fcac4b24
parent1d21b1bf53f81256002f93387ec80ca13e3c5a8f (diff)
ocfs2/o2net: incorrect to terminate accepting connections loop upon rejecting an invalid one
When o2net-accept-one() rejects an illegal connection, it terminates the loop picking up the remaining queued connections. This fix will continue accepting connections till the queue is emtpy. Addresses Orabug 17489469. Signed-off-by: Tariq Saseed <tariq.x.saeed@oracle.com> Signed-off-by: Srinivas Eeda <srinivas.eeda@oracle.com> Reviewed-by: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ocfs2/cluster/tcp.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index a68e07a9bd46..681691bc233a 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -1799,7 +1799,7 @@ int o2net_register_hb_callbacks(void)
1799 1799
1800/* ------------------------------------------------------------ */ 1800/* ------------------------------------------------------------ */
1801 1801
1802static int o2net_accept_one(struct socket *sock) 1802static int o2net_accept_one(struct socket *sock, int *more)
1803{ 1803{
1804 int ret, slen; 1804 int ret, slen;
1805 struct sockaddr_in sin; 1805 struct sockaddr_in sin;
@@ -1810,6 +1810,7 @@ static int o2net_accept_one(struct socket *sock)
1810 struct o2net_node *nn; 1810 struct o2net_node *nn;
1811 1811
1812 BUG_ON(sock == NULL); 1812 BUG_ON(sock == NULL);
1813 *more = 0;
1813 ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type, 1814 ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
1814 sock->sk->sk_protocol, &new_sock); 1815 sock->sk->sk_protocol, &new_sock);
1815 if (ret) 1816 if (ret)
@@ -1821,6 +1822,7 @@ static int o2net_accept_one(struct socket *sock)
1821 if (ret < 0) 1822 if (ret < 0)
1822 goto out; 1823 goto out;
1823 1824
1825 *more = 1;
1824 new_sock->sk->sk_allocation = GFP_ATOMIC; 1826 new_sock->sk->sk_allocation = GFP_ATOMIC;
1825 1827
1826 ret = o2net_set_nodelay(new_sock); 1828 ret = o2net_set_nodelay(new_sock);
@@ -1919,11 +1921,36 @@ out:
1919 return ret; 1921 return ret;
1920} 1922}
1921 1923
1924/*
1925 * This function is invoked in response to one or more
1926 * pending accepts at softIRQ level. We must drain the
1927 * entire que before returning.
1928 */
1929
1922static void o2net_accept_many(struct work_struct *work) 1930static void o2net_accept_many(struct work_struct *work)
1923{ 1931{
1924 struct socket *sock = o2net_listen_sock; 1932 struct socket *sock = o2net_listen_sock;
1925 while (o2net_accept_one(sock) == 0) 1933 int more;
1934 int err;
1935
1936 /*
1937 * It is critical to note that due to interrupt moderation
1938 * at the network driver level, we can't assume to get a
1939 * softIRQ for every single conn since tcp SYN packets
1940 * can arrive back-to-back, and therefore many pending
1941 * accepts may result in just 1 softIRQ. If we terminate
1942 * the o2net_accept_one() loop upon seeing an err, what happens
1943 * to the rest of the conns in the queue? If no new SYN
1944 * arrives for hours, no softIRQ will be delivered,
1945 * and the connections will just sit in the queue.
1946 */
1947
1948 for (;;) {
1949 err = o2net_accept_one(sock, &more);
1950 if (!more)
1951 break;
1926 cond_resched(); 1952 cond_resched();
1953 }
1927} 1954}
1928 1955
1929static void o2net_listen_data_ready(struct sock *sk) 1956static void o2net_listen_data_ready(struct sock *sk)