diff options
Diffstat (limited to 'fs/ocfs2/cluster/tcp.c')
-rw-r--r-- | fs/ocfs2/cluster/tcp.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index ae4ff4a6636b..1718215fc018 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -556,6 +556,8 @@ static void o2net_register_callbacks(struct sock *sk, | |||
556 | sk->sk_data_ready = o2net_data_ready; | 556 | sk->sk_data_ready = o2net_data_ready; |
557 | sk->sk_state_change = o2net_state_change; | 557 | sk->sk_state_change = o2net_state_change; |
558 | 558 | ||
559 | mutex_init(&sc->sc_send_lock); | ||
560 | |||
559 | write_unlock_bh(&sk->sk_callback_lock); | 561 | write_unlock_bh(&sk->sk_callback_lock); |
560 | } | 562 | } |
561 | 563 | ||
@@ -688,6 +690,7 @@ static void o2net_handler_put(struct o2net_msg_handler *nmh) | |||
688 | * be given to the handler if their payload is longer than the max. */ | 690 | * be given to the handler if their payload is longer than the max. */ |
689 | int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, | 691 | int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, |
690 | o2net_msg_handler_func *func, void *data, | 692 | o2net_msg_handler_func *func, void *data, |
693 | o2net_post_msg_handler_func *post_func, | ||
691 | struct list_head *unreg_list) | 694 | struct list_head *unreg_list) |
692 | { | 695 | { |
693 | struct o2net_msg_handler *nmh = NULL; | 696 | struct o2net_msg_handler *nmh = NULL; |
@@ -722,6 +725,7 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, | |||
722 | 725 | ||
723 | nmh->nh_func = func; | 726 | nmh->nh_func = func; |
724 | nmh->nh_func_data = data; | 727 | nmh->nh_func_data = data; |
728 | nmh->nh_post_func = post_func; | ||
725 | nmh->nh_msg_type = msg_type; | 729 | nmh->nh_msg_type = msg_type; |
726 | nmh->nh_max_len = max_len; | 730 | nmh->nh_max_len = max_len; |
727 | nmh->nh_key = key; | 731 | nmh->nh_key = key; |
@@ -856,10 +860,12 @@ static void o2net_sendpage(struct o2net_sock_container *sc, | |||
856 | ssize_t ret; | 860 | ssize_t ret; |
857 | 861 | ||
858 | 862 | ||
863 | mutex_lock(&sc->sc_send_lock); | ||
859 | ret = sc->sc_sock->ops->sendpage(sc->sc_sock, | 864 | ret = sc->sc_sock->ops->sendpage(sc->sc_sock, |
860 | virt_to_page(kmalloced_virt), | 865 | virt_to_page(kmalloced_virt), |
861 | (long)kmalloced_virt & ~PAGE_MASK, | 866 | (long)kmalloced_virt & ~PAGE_MASK, |
862 | size, MSG_DONTWAIT); | 867 | size, MSG_DONTWAIT); |
868 | mutex_unlock(&sc->sc_send_lock); | ||
863 | if (ret != size) { | 869 | if (ret != size) { |
864 | mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT | 870 | mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT |
865 | " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); | 871 | " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); |
@@ -974,8 +980,10 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, | |||
974 | 980 | ||
975 | /* finally, convert the message header to network byte-order | 981 | /* finally, convert the message header to network byte-order |
976 | * and send */ | 982 | * and send */ |
983 | mutex_lock(&sc->sc_send_lock); | ||
977 | ret = o2net_send_tcp_msg(sc->sc_sock, vec, veclen, | 984 | ret = o2net_send_tcp_msg(sc->sc_sock, vec, veclen, |
978 | sizeof(struct o2net_msg) + caller_bytes); | 985 | sizeof(struct o2net_msg) + caller_bytes); |
986 | mutex_unlock(&sc->sc_send_lock); | ||
979 | msglog(msg, "sending returned %d\n", ret); | 987 | msglog(msg, "sending returned %d\n", ret); |
980 | if (ret < 0) { | 988 | if (ret < 0) { |
981 | mlog(0, "error returned from o2net_send_tcp_msg=%d\n", ret); | 989 | mlog(0, "error returned from o2net_send_tcp_msg=%d\n", ret); |
@@ -1049,6 +1057,7 @@ static int o2net_process_message(struct o2net_sock_container *sc, | |||
1049 | int ret = 0, handler_status; | 1057 | int ret = 0, handler_status; |
1050 | enum o2net_system_error syserr; | 1058 | enum o2net_system_error syserr; |
1051 | struct o2net_msg_handler *nmh = NULL; | 1059 | struct o2net_msg_handler *nmh = NULL; |
1060 | void *ret_data = NULL; | ||
1052 | 1061 | ||
1053 | msglog(hdr, "processing message\n"); | 1062 | msglog(hdr, "processing message\n"); |
1054 | 1063 | ||
@@ -1101,17 +1110,26 @@ static int o2net_process_message(struct o2net_sock_container *sc, | |||
1101 | sc->sc_msg_type = be16_to_cpu(hdr->msg_type); | 1110 | sc->sc_msg_type = be16_to_cpu(hdr->msg_type); |
1102 | handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) + | 1111 | handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) + |
1103 | be16_to_cpu(hdr->data_len), | 1112 | be16_to_cpu(hdr->data_len), |
1104 | nmh->nh_func_data); | 1113 | nmh->nh_func_data, &ret_data); |
1105 | do_gettimeofday(&sc->sc_tv_func_stop); | 1114 | do_gettimeofday(&sc->sc_tv_func_stop); |
1106 | 1115 | ||
1107 | out_respond: | 1116 | out_respond: |
1108 | /* this destroys the hdr, so don't use it after this */ | 1117 | /* this destroys the hdr, so don't use it after this */ |
1118 | mutex_lock(&sc->sc_send_lock); | ||
1109 | ret = o2net_send_status_magic(sc->sc_sock, hdr, syserr, | 1119 | ret = o2net_send_status_magic(sc->sc_sock, hdr, syserr, |
1110 | handler_status); | 1120 | handler_status); |
1121 | mutex_unlock(&sc->sc_send_lock); | ||
1111 | hdr = NULL; | 1122 | hdr = NULL; |
1112 | mlog(0, "sending handler status %d, syserr %d returned %d\n", | 1123 | mlog(0, "sending handler status %d, syserr %d returned %d\n", |
1113 | handler_status, syserr, ret); | 1124 | handler_status, syserr, ret); |
1114 | 1125 | ||
1126 | if (nmh) { | ||
1127 | BUG_ON(ret_data != NULL && nmh->nh_post_func == NULL); | ||
1128 | if (nmh->nh_post_func) | ||
1129 | (nmh->nh_post_func)(handler_status, nmh->nh_func_data, | ||
1130 | ret_data); | ||
1131 | } | ||
1132 | |||
1115 | out: | 1133 | out: |
1116 | if (nmh) | 1134 | if (nmh) |
1117 | o2net_handler_put(nmh); | 1135 | o2net_handler_put(nmh); |
@@ -1795,13 +1813,13 @@ out: | |||
1795 | ready(sk, bytes); | 1813 | ready(sk, bytes); |
1796 | } | 1814 | } |
1797 | 1815 | ||
1798 | static int o2net_open_listening_sock(__be16 port) | 1816 | static int o2net_open_listening_sock(__be32 addr, __be16 port) |
1799 | { | 1817 | { |
1800 | struct socket *sock = NULL; | 1818 | struct socket *sock = NULL; |
1801 | int ret; | 1819 | int ret; |
1802 | struct sockaddr_in sin = { | 1820 | struct sockaddr_in sin = { |
1803 | .sin_family = PF_INET, | 1821 | .sin_family = PF_INET, |
1804 | .sin_addr = { .s_addr = (__force u32)htonl(INADDR_ANY) }, | 1822 | .sin_addr = { .s_addr = (__force u32)addr }, |
1805 | .sin_port = (__force u16)port, | 1823 | .sin_port = (__force u16)port, |
1806 | }; | 1824 | }; |
1807 | 1825 | ||
@@ -1824,15 +1842,15 @@ static int o2net_open_listening_sock(__be16 port) | |||
1824 | sock->sk->sk_reuse = 1; | 1842 | sock->sk->sk_reuse = 1; |
1825 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); | 1843 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); |
1826 | if (ret < 0) { | 1844 | if (ret < 0) { |
1827 | mlog(ML_ERROR, "unable to bind socket to port %d, ret=%d\n", | 1845 | mlog(ML_ERROR, "unable to bind socket at %u.%u.%u.%u:%u, " |
1828 | ntohs(port), ret); | 1846 | "ret=%d\n", NIPQUAD(addr), ntohs(port), ret); |
1829 | goto out; | 1847 | goto out; |
1830 | } | 1848 | } |
1831 | 1849 | ||
1832 | ret = sock->ops->listen(sock, 64); | 1850 | ret = sock->ops->listen(sock, 64); |
1833 | if (ret < 0) { | 1851 | if (ret < 0) { |
1834 | mlog(ML_ERROR, "unable to listen on port %d, ret=%d\n", | 1852 | mlog(ML_ERROR, "unable to listen on %u.%u.%u.%u:%u, ret=%d\n", |
1835 | ntohs(port), ret); | 1853 | NIPQUAD(addr), ntohs(port), ret); |
1836 | } | 1854 | } |
1837 | 1855 | ||
1838 | out: | 1856 | out: |
@@ -1865,7 +1883,8 @@ int o2net_start_listening(struct o2nm_node *node) | |||
1865 | return -ENOMEM; /* ? */ | 1883 | return -ENOMEM; /* ? */ |
1866 | } | 1884 | } |
1867 | 1885 | ||
1868 | ret = o2net_open_listening_sock(node->nd_ipv4_port); | 1886 | ret = o2net_open_listening_sock(node->nd_ipv4_address, |
1887 | node->nd_ipv4_port); | ||
1869 | if (ret) { | 1888 | if (ret) { |
1870 | destroy_workqueue(o2net_wq); | 1889 | destroy_workqueue(o2net_wq); |
1871 | o2net_wq = NULL; | 1890 | o2net_wq = NULL; |