diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2012-07-12 05:08:34 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:58:31 -0500 |
commit | 1f3e509b761d6d8f91acbf7da39624d086e1f2eb (patch) | |
tree | 6bdf8d7a07d7fa4d97de1620223635f94b85a8e0 /drivers/block/drbd | |
parent | 9a51ab1c1b3c1e21f076cdd571bbe6ca7d1b504c (diff) |
drbd: pull prepare_listen_socket() out of drbd_wait_for_connect()
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 96ab2ffc2a41..46c55793dd8d 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -666,12 +666,11 @@ out: | |||
666 | return sock; | 666 | return sock; |
667 | } | 667 | } |
668 | 668 | ||
669 | static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn) | 669 | static struct socket *prepare_listen_socket(struct drbd_tconn *tconn) |
670 | { | 670 | { |
671 | int timeo, err, my_addr_len; | 671 | int err, sndbuf_size, rcvbuf_size, my_addr_len; |
672 | int sndbuf_size, rcvbuf_size, connect_int; | ||
673 | struct socket *s_estab = NULL, *s_listen; | ||
674 | struct sockaddr_in6 my_addr; | 672 | struct sockaddr_in6 my_addr; |
673 | struct socket *s_listen; | ||
675 | struct net_conf *nc; | 674 | struct net_conf *nc; |
676 | const char *what; | 675 | const char *what; |
677 | 676 | ||
@@ -683,7 +682,6 @@ static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn) | |||
683 | } | 682 | } |
684 | sndbuf_size = nc->sndbuf_size; | 683 | sndbuf_size = nc->sndbuf_size; |
685 | rcvbuf_size = nc->rcvbuf_size; | 684 | rcvbuf_size = nc->rcvbuf_size; |
686 | connect_int = nc->connect_int; | ||
687 | rcu_read_unlock(); | 685 | rcu_read_unlock(); |
688 | 686 | ||
689 | my_addr_len = min_t(int, tconn->my_addr_len, sizeof(struct sockaddr_in6)); | 687 | my_addr_len = min_t(int, tconn->my_addr_len, sizeof(struct sockaddr_in6)); |
@@ -691,18 +689,13 @@ static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn) | |||
691 | 689 | ||
692 | what = "sock_create_kern"; | 690 | what = "sock_create_kern"; |
693 | err = sock_create_kern(((struct sockaddr *)&my_addr)->sa_family, | 691 | err = sock_create_kern(((struct sockaddr *)&my_addr)->sa_family, |
694 | SOCK_STREAM, IPPROTO_TCP, &s_listen); | 692 | SOCK_STREAM, IPPROTO_TCP, &s_listen); |
695 | if (err) { | 693 | if (err) { |
696 | s_listen = NULL; | 694 | s_listen = NULL; |
697 | goto out; | 695 | goto out; |
698 | } | 696 | } |
699 | 697 | ||
700 | timeo = connect_int * HZ; | 698 | s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */ |
701 | timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */ | ||
702 | |||
703 | s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */ | ||
704 | s_listen->sk->sk_rcvtimeo = timeo; | ||
705 | s_listen->sk->sk_sndtimeo = timeo; | ||
706 | drbd_setbufsize(s_listen, sndbuf_size, rcvbuf_size); | 699 | drbd_setbufsize(s_listen, sndbuf_size, rcvbuf_size); |
707 | 700 | ||
708 | what = "bind before listen"; | 701 | what = "bind before listen"; |
@@ -715,7 +708,46 @@ static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn) | |||
715 | if (err < 0) | 708 | if (err < 0) |
716 | goto out; | 709 | goto out; |
717 | 710 | ||
718 | what = "accept"; | 711 | return s_listen; |
712 | out: | ||
713 | if (s_listen) | ||
714 | sock_release(s_listen); | ||
715 | if (err < 0) { | ||
716 | if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) { | ||
717 | conn_err(tconn, "%s failed, err = %d\n", what, err); | ||
718 | conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD); | ||
719 | } | ||
720 | } | ||
721 | |||
722 | return NULL; | ||
723 | } | ||
724 | |||
725 | static struct socket *drbd_wait_for_connect(struct drbd_tconn *tconn) | ||
726 | { | ||
727 | int timeo, connect_int, err = 0; | ||
728 | struct socket *s_estab = NULL; | ||
729 | struct socket *s_listen; | ||
730 | struct net_conf *nc; | ||
731 | |||
732 | rcu_read_lock(); | ||
733 | nc = rcu_dereference(tconn->net_conf); | ||
734 | if (!nc) { | ||
735 | rcu_read_unlock(); | ||
736 | return NULL; | ||
737 | } | ||
738 | connect_int = nc->connect_int; | ||
739 | rcu_read_unlock(); | ||
740 | |||
741 | timeo = connect_int * HZ; | ||
742 | timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */ | ||
743 | |||
744 | s_listen = prepare_listen_socket(tconn); | ||
745 | if (!s_listen) | ||
746 | goto out; | ||
747 | |||
748 | s_listen->sk->sk_rcvtimeo = timeo; | ||
749 | s_listen->sk->sk_sndtimeo = timeo; | ||
750 | |||
719 | err = kernel_accept(s_listen, &s_estab, 0); | 751 | err = kernel_accept(s_listen, &s_estab, 0); |
720 | 752 | ||
721 | out: | 753 | out: |
@@ -723,7 +755,7 @@ out: | |||
723 | sock_release(s_listen); | 755 | sock_release(s_listen); |
724 | if (err < 0) { | 756 | if (err < 0) { |
725 | if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) { | 757 | if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) { |
726 | conn_err(tconn, "%s failed, err = %d\n", what, err); | 758 | conn_err(tconn, "accept failed, err = %d\n", err); |
727 | conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD); | 759 | conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD); |
728 | } | 760 | } |
729 | } | 761 | } |