diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 4 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 14 |
2 files changed, 15 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 8aa10391115b..a74d3ee04ba8 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -2157,6 +2157,10 @@ static inline int get_net_conf(struct drbd_conf *mdev) | |||
2157 | static inline void put_ldev(struct drbd_conf *mdev) | 2157 | static inline void put_ldev(struct drbd_conf *mdev) |
2158 | { | 2158 | { |
2159 | int i = atomic_dec_return(&mdev->local_cnt); | 2159 | int i = atomic_dec_return(&mdev->local_cnt); |
2160 | |||
2161 | /* This may be called from some endio handler, | ||
2162 | * so we must not sleep here. */ | ||
2163 | |||
2160 | __release(local); | 2164 | __release(local); |
2161 | D_ASSERT(i >= 0); | 2165 | D_ASSERT(i >= 0); |
2162 | if (i == 0) { | 2166 | if (i == 0) { |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 7c64ec042124..13569635b922 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -1334,11 +1334,19 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1334 | static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, | 1334 | static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, |
1335 | struct drbd_nl_cfg_reply *reply) | 1335 | struct drbd_nl_cfg_reply *reply) |
1336 | { | 1336 | { |
1337 | enum drbd_ret_code retcode; | ||
1338 | int ret; | ||
1337 | drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ | 1339 | drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ |
1338 | reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS)); | 1340 | retcode = drbd_request_state(mdev, NS(disk, D_FAILED)); |
1339 | if (mdev->state.disk == D_DISKLESS) | 1341 | /* D_FAILED will transition to DISKLESS. */ |
1340 | wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); | 1342 | ret = wait_event_interruptible(mdev->misc_wait, |
1343 | mdev->state.disk != D_FAILED); | ||
1341 | drbd_resume_io(mdev); | 1344 | drbd_resume_io(mdev); |
1345 | if (retcode == SS_IS_DISKLESS) | ||
1346 | retcode = SS_NOTHING_TO_DO; | ||
1347 | if (ret) | ||
1348 | retcode = ERR_INTR; | ||
1349 | reply->ret_code = retcode; | ||
1342 | return 0; | 1350 | return 0; |
1343 | } | 1351 | } |
1344 | 1352 | ||