diff options
-rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 1 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 24 | ||||
-rw-r--r-- | fs/gfs2/util.c | 3 |
4 files changed, 28 insertions, 1 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 1533cf8b4269..e2601ba38ef5 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -642,6 +642,7 @@ struct gfs2_sbd { | |||
642 | wait_queue_head_t sd_glock_wait; | 642 | wait_queue_head_t sd_glock_wait; |
643 | atomic_t sd_glock_disposal; | 643 | atomic_t sd_glock_disposal; |
644 | struct completion sd_locking_init; | 644 | struct completion sd_locking_init; |
645 | struct completion sd_wdack; | ||
645 | struct delayed_work sd_control_work; | 646 | struct delayed_work sd_control_work; |
646 | 647 | ||
647 | /* Inode Stuff */ | 648 | /* Inode Stuff */ |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index e063f22d9e4c..1b612be4b873 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -81,6 +81,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
81 | init_waitqueue_head(&sdp->sd_glock_wait); | 81 | init_waitqueue_head(&sdp->sd_glock_wait); |
82 | atomic_set(&sdp->sd_glock_disposal, 0); | 82 | atomic_set(&sdp->sd_glock_disposal, 0); |
83 | init_completion(&sdp->sd_locking_init); | 83 | init_completion(&sdp->sd_locking_init); |
84 | init_completion(&sdp->sd_wdack); | ||
84 | spin_lock_init(&sdp->sd_statfs_spin); | 85 | spin_lock_init(&sdp->sd_statfs_spin); |
85 | 86 | ||
86 | spin_lock_init(&sdp->sd_rindex_spin); | 87 | spin_lock_init(&sdp->sd_rindex_spin); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 462e84142759..4fb9ad80d260 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -330,6 +330,28 @@ static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | |||
330 | return ret; | 330 | return ret; |
331 | } | 331 | } |
332 | 332 | ||
333 | static ssize_t wdack_show(struct gfs2_sbd *sdp, char *buf) | ||
334 | { | ||
335 | int val = completion_done(&sdp->sd_wdack) ? 1 : 0; | ||
336 | |||
337 | return sprintf(buf, "%d\n", val); | ||
338 | } | ||
339 | |||
340 | static ssize_t wdack_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | ||
341 | { | ||
342 | ssize_t ret = len; | ||
343 | int val; | ||
344 | |||
345 | val = simple_strtol(buf, NULL, 0); | ||
346 | |||
347 | if ((val == 1) && | ||
348 | !strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm")) | ||
349 | complete(&sdp->sd_wdack); | ||
350 | else | ||
351 | ret = -EINVAL; | ||
352 | return ret; | ||
353 | } | ||
354 | |||
333 | static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf) | 355 | static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf) |
334 | { | 356 | { |
335 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 357 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
@@ -461,7 +483,7 @@ static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) | |||
461 | 483 | ||
462 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); | 484 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); |
463 | GDLM_ATTR(block, 0644, block_show, block_store); | 485 | GDLM_ATTR(block, 0644, block_show, block_store); |
464 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); | 486 | GDLM_ATTR(withdraw, 0644, wdack_show, wdack_store); |
465 | GDLM_ATTR(jid, 0644, jid_show, jid_store); | 487 | GDLM_ATTR(jid, 0644, jid_show, jid_store); |
466 | GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store); | 488 | GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store); |
467 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); | 489 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); |
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index f00d7c5744f6..6402fb69d71b 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -54,6 +54,9 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...) | |||
54 | 54 | ||
55 | kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE); | 55 | kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE); |
56 | 56 | ||
57 | if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm")) | ||
58 | wait_for_completion(&sdp->sd_wdack); | ||
59 | |||
57 | if (lm->lm_unmount) { | 60 | if (lm->lm_unmount) { |
58 | fs_err(sdp, "telling LM to unmount\n"); | 61 | fs_err(sdp, "telling LM to unmount\n"); |
59 | lm->lm_unmount(sdp); | 62 | lm->lm_unmount(sdp); |