summaryrefslogtreecommitdiff
path: root/fs/gfs2/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/util.c')
-rw-r--r--fs/gfs2/util.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index b8ce04338b24..02603200846d 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -117,35 +117,30 @@ void gfs2_freeze_unlock(struct gfs2_sbd *sdp)
static void do_withdraw(struct gfs2_sbd *sdp)
{
+ down_write(&sdp->sd_log_flush_lock);
+ if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
+ up_write(&sdp->sd_log_flush_lock);
+ return;
+ }
+ clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
+ up_write(&sdp->sd_log_flush_lock);
+
gfs2_ail_drain(sdp); /* frees all transactions */
- /*
- * Don't tell dlm we're bailing until we have no more buffers in the
- * wind. If journal had an IO error, the log code should just purge
- * the outstanding buffers rather than submitting new IO.
- *
- * During a normal unmount, gfs2_make_fs_ro calls gfs2_log_shutdown
- * which clears SDF_JOURNAL_LIVE. In a withdraw, we must not write
- * any UNMOUNT log header, so we can't call gfs2_log_shutdown, and
- * therefore we need to clear SDF_JOURNAL_LIVE manually.
- */
- clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
- if (!sb_rdonly(sdp->sd_vfs)) {
- wake_up(&sdp->sd_logd_waitq);
- wake_up(&sdp->sd_quota_wait);
+ wake_up(&sdp->sd_logd_waitq);
+ wake_up(&sdp->sd_quota_wait);
- wait_event_timeout(sdp->sd_log_waitq,
- gfs2_log_is_empty(sdp),
- HZ * 5);
+ wait_event_timeout(sdp->sd_log_waitq,
+ gfs2_log_is_empty(sdp),
+ HZ * 5);
- sdp->sd_vfs->s_flags |= SB_RDONLY;
+ sdp->sd_vfs->s_flags |= SB_RDONLY;
- /*
- * Dequeue any pending non-system glock holders that can no
- * longer be granted because the file system is withdrawn.
- */
- gfs2_withdraw_glocks(sdp);
- }
+ /*
+ * Dequeue any pending non-system glock holders that can no
+ * longer be granted because the file system is withdrawn.
+ */
+ gfs2_withdraw_glocks(sdp);
}
void gfs2_lm(struct gfs2_sbd *sdp, const char *fmt, ...)