aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dlm/lowcomms.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 37a34c2c622a..77720f89c879 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -108,6 +108,7 @@ struct connection {
108#define CF_INIT_PENDING 4 108#define CF_INIT_PENDING 4
109#define CF_IS_OTHERCON 5 109#define CF_IS_OTHERCON 5
110#define CF_CLOSE 6 110#define CF_CLOSE 6
111#define CF_APP_LIMITED 7
111 struct list_head writequeue; /* List of outgoing writequeue_entries */ 112 struct list_head writequeue; /* List of outgoing writequeue_entries */
112 spinlock_t writequeue_lock; 113 spinlock_t writequeue_lock;
113 int (*rx_action) (struct connection *); /* What to do when active */ 114 int (*rx_action) (struct connection *); /* What to do when active */
@@ -295,7 +296,17 @@ static void lowcomms_write_space(struct sock *sk)
295{ 296{
296 struct connection *con = sock2con(sk); 297 struct connection *con = sock2con(sk);
297 298
298 if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags)) 299 if (!con)
300 return;
301
302 clear_bit(SOCK_NOSPACE, &con->sock->flags);
303
304 if (test_and_clear_bit(CF_APP_LIMITED, &con->flags)) {
305 con->sock->sk->sk_write_pending--;
306 clear_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags);
307 }
308
309 if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags))
299 queue_work(send_workqueue, &con->swork); 310 queue_work(send_workqueue, &con->swork);
300} 311}
301 312
@@ -1319,6 +1330,15 @@ static void send_to_sock(struct connection *con)
1319 ret = kernel_sendpage(con->sock, e->page, offset, len, 1330 ret = kernel_sendpage(con->sock, e->page, offset, len,
1320 msg_flags); 1331 msg_flags);
1321 if (ret == -EAGAIN || ret == 0) { 1332 if (ret == -EAGAIN || ret == 0) {
1333 if (ret == -EAGAIN &&
1334 test_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags) &&
1335 !test_and_set_bit(CF_APP_LIMITED, &con->flags)) {
1336 /* Notify TCP that we're limited by the
1337 * application window size.
1338 */
1339 set_bit(SOCK_NOSPACE, &con->sock->flags);
1340 con->sock->sk->sk_write_pending++;
1341 }
1322 cond_resched(); 1342 cond_resched();
1323 goto out; 1343 goto out;
1324 } 1344 }