path: root/drivers/block/drbd/drbd_nl.c
diff options
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-07-30 09:07:28 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 16:58:39 +0100
commit0c849666016cbf541c1030eec55f5f8dd1fba513 (patch)
tree35a49ef17d65375947404bd81759fc815bf09d5d /drivers/block/drbd/drbd_nl.c
parentbf709c8552bcbbbc66ecc11555a781e814a037d8 (diff)
drbd: differentiate between normal and forced detach
Aborting local requests (not waiting for completion from the lower level disk) is dangerous: if the master bio has been completed to upper layers, data pages may be re-used for other things already. If local IO is still pending and later completes, this may cause crashes or corrupt unrelated data. Only abort local IO if explicitly requested. Intended use case is a lower level device that turned into a tarpit, not completing io requests, not even doing error completion. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_nl.c')
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 323293e8887..d4c05e26a13 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1299,6 +1299,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
* to realize a "hot spare" feature (not that I'd recommend that) */
wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
+ /* make sure there is no leftover from previous force-detach attempts */
+ clear_bit(FORCE_DETACH, &mdev->flags);
/* allocation not in the IO path, drbdsetup context */
nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL);
if (!nbc) {
@@ -1683,6 +1686,7 @@ static int adm_detach(struct drbd_conf *mdev, int force)
int ret;
if (force) {
+ set_bit(FORCE_DETACH, &mdev->flags);
drbd_force_state(mdev, NS(disk, D_FAILED));
retcode = SS_SUCCESS;
goto out;