diff options
Diffstat (limited to 'net/ceph')
-rw-r--r-- | net/ceph/messenger.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index ad5b70801f37..d11f91b05452 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -143,16 +143,22 @@ static void ceph_write_space(struct sock *sk) | |||
143 | struct ceph_connection *con = | 143 | struct ceph_connection *con = |
144 | (struct ceph_connection *)sk->sk_user_data; | 144 | (struct ceph_connection *)sk->sk_user_data; |
145 | 145 | ||
146 | /* only queue to workqueue if there is data we want to write. */ | 146 | /* only queue to workqueue if there is data we want to write, |
147 | * and there is sufficient space in the socket buffer to accept | ||
148 | * more data. clear SOCK_NOSPACE so that ceph_write_space() | ||
149 | * doesn't get called again until try_write() fills the socket | ||
150 | * buffer. See net/ipv4/tcp_input.c:tcp_check_space() | ||
151 | * and net/core/stream.c:sk_stream_write_space(). | ||
152 | */ | ||
147 | if (test_bit(WRITE_PENDING, &con->state)) { | 153 | if (test_bit(WRITE_PENDING, &con->state)) { |
148 | dout("ceph_write_space %p queueing write work\n", con); | 154 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) { |
149 | queue_con(con); | 155 | dout("ceph_write_space %p queueing write work\n", con); |
156 | clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | ||
157 | queue_con(con); | ||
158 | } | ||
150 | } else { | 159 | } else { |
151 | dout("ceph_write_space %p nothing to write\n", con); | 160 | dout("ceph_write_space %p nothing to write\n", con); |
152 | } | 161 | } |
153 | |||
154 | /* since we have our own write_space, clear the SOCK_NOSPACE flag */ | ||
155 | clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | ||
156 | } | 162 | } |
157 | 163 | ||
158 | /* socket's state has changed */ | 164 | /* socket's state has changed */ |