From 3f381e2b952e26302bd0fd229ad630b3ad8bd1a3 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Fri, 17 Aug 2012 14:50:22 +0200 Subject: [PATCH] --- yaml --- r: 345689 b: refs/heads/master c: 599377acb7cf3e1bdec13285096adac7ebaaaac5 h: refs/heads/master i: 345687: f858a56ad879631589e656a464db5234d5c4148c v: v3 --- [refs] | 2 +- trunk/drivers/block/drbd/drbd_int.h | 1 + trunk/drivers/block/drbd/drbd_main.c | 3 +++ trunk/drivers/block/drbd/drbd_receiver.c | 21 ++++++++++++++++++++- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 1cbd2d170980..78947677925a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c12a3d8c84a5e9913a97ca5e6513c913a7e5b288 +refs/heads/master: 599377acb7cf3e1bdec13285096adac7ebaaaac5 diff --git a/trunk/drivers/block/drbd/drbd_int.h b/trunk/drivers/block/drbd/drbd_int.h index 3cce7357402b..3b378124bac8 100644 --- a/trunk/drivers/block/drbd/drbd_int.h +++ b/trunk/drivers/block/drbd/drbd_int.h @@ -857,6 +857,7 @@ enum { * so shrink_page_list() would not recurse into, * and potentially deadlock on, this drbd worker. */ + DISCONNECT_SENT, /* Currently the last bit in this 32bit word */ }; struct drbd_bitmap; /* opaque for drbd_conf */ diff --git a/trunk/drivers/block/drbd/drbd_main.c b/trunk/drivers/block/drbd/drbd_main.c index df9965d820c9..7b48653d1c8f 100644 --- a/trunk/drivers/block/drbd/drbd_main.c +++ b/trunk/drivers/block/drbd/drbd_main.c @@ -659,6 +659,9 @@ drbd_req_state(struct drbd_conf *mdev, union drbd_state mask, goto abort; } + if (mask.conn == C_MASK && val.conn == C_DISCONNECTING) + set_bit(DISCONNECT_SENT, &mdev->flags); + wait_event(mdev->state_wait, (rv = _req_st_cond(mdev, mask, val))); diff --git a/trunk/drivers/block/drbd/drbd_receiver.c b/trunk/drivers/block/drbd/drbd_receiver.c index 55c359a1a052..64e6a619241d 100644 --- a/trunk/drivers/block/drbd/drbd_receiver.c +++ b/trunk/drivers/block/drbd/drbd_receiver.c @@ -534,7 +534,6 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size) dev_err(DEV, "sock_recvmsg returned %d\n", rv); break; } else if (rv == 0) { - dev_info(DEV, "sock was shut down by peer\n"); break; } else { /* signal came in, or peer/link went down, @@ -547,9 +546,21 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size) set_fs(oldfs); + if (rv == 0) { + if (test_bit(DISCONNECT_SENT, &mdev->flags)) { + long t; /* time_left */ + t = wait_event_timeout(mdev->state_wait, mdev->state.conn < C_CONNECTED, + mdev->net_conf->ping_timeo * HZ/10); + if (t) + goto out; + } + dev_info(DEV, "sock was shut down by peer\n"); + } + if (rv != size) drbd_force_state(mdev, NS(conn, C_BROKEN_PIPE)); +out: return rv; } @@ -760,6 +771,7 @@ static int drbd_connect(struct drbd_conf *mdev) D_ASSERT(!mdev->data.socket); + clear_bit(DISCONNECT_SENT, &mdev->flags); if (drbd_request_state(mdev, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS) return -2; @@ -4680,6 +4692,13 @@ int drbd_asender(struct drbd_thread *thi) received += rv; buf += rv; } else if (rv == 0) { + if (test_bit(DISCONNECT_SENT, &mdev->flags)) { + long t; /* time_left */ + t = wait_event_timeout(mdev->state_wait, mdev->state.conn < C_CONNECTED, + mdev->net_conf->ping_timeo * HZ/10); + if (t) + break; + } dev_err(DEV, "meta connection shut down by peer.\n"); goto reconnect; } else if (rv == -EAGAIN) {