summaryrefslogtreecommitdiff
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-05-31 10:14:17 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 14:52:53 +0200
commit265be2d09853d425ad14a61cda0ca63345613d0c (patch)
treecc2f419d8aaa41fd088f3d24ca134c4d7f51aa64 /drivers/block/drbd/drbd_nl.c
parent905cd7d8ac9b18e1f122b90dbebe1246b1c364fd (diff)
downloadlwn-265be2d09853d425ad14a61cda0ca63345613d0c.tar.gz
lwn-265be2d09853d425ad14a61cda0ca63345613d0c.zip
drbd: Finished the "on-no-data-accessible suspend-io;" functionality
When no data is accessible (no connection to the peer, nor a local disk) allow the user to select to freeze all IO operations instead of getting IO errors. 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')
-rw-r--r--drivers/block/drbd/drbd_nl.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 73131c5ae339..563a6ade0179 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -33,6 +33,7 @@
#include <linux/blkpg.h>
#include <linux/cpumask.h>
#include "drbd_int.h"
+#include "drbd_req.h"
#include "drbd_wrappers.h"
#include <asm/unaligned.h>
#include <linux/drbd_tag_magic.h>
@@ -494,6 +495,8 @@ char *ppsize(char *buf, unsigned long long size)
void drbd_suspend_io(struct drbd_conf *mdev)
{
set_bit(SUSPEND_IO, &mdev->flags);
+ if (mdev->state.susp)
+ return;
wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
}
@@ -1557,6 +1560,7 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n
sc.rate = DRBD_RATE_DEF;
sc.after = DRBD_AFTER_DEF;
sc.al_extents = DRBD_AL_EXTENTS_DEF;
+ sc.on_no_data = DRBD_ON_NO_DATA_DEF;
} else
memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf));
@@ -1765,7 +1769,16 @@ static int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
struct drbd_nl_cfg_reply *reply)
{
+ drbd_suspend_io(mdev);
reply->ret_code = drbd_request_state(mdev, NS(susp, 0));
+ if (reply->ret_code == SS_SUCCESS) {
+ if (mdev->state.conn < C_CONNECTED)
+ tl_clear(mdev);
+ if (mdev->state.disk == D_DISKLESS || mdev->state.disk == D_FAILED)
+ tl_restart(mdev, fail_frozen_disk_io);
+ }
+ drbd_resume_io(mdev);
+
return 0;
}