summaryrefslogtreecommitdiff
path: root/fs/gfs2
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2017-03-03 12:37:14 -0500
committerBob Peterson <rpeterso@redhat.com>2017-03-16 08:18:35 -0400
commit0d1c7ae9d849bdd3146e322f1e46fd3300e66d5f (patch)
treeedf72c572f1b7d42fcf817f5e6e1d93f8c93037b /fs/gfs2
parent69eea5a4ab9c705496e912b55a9d312325de19e6 (diff)
GFS2: Prevent BUG from occurring when normal Withdraws occur
When the GFS2 file system withdraws due to metadata corruption, it often has outstanding transactions in the journal and delayed work queued for its glocks. This patch adds some new checks for a withdrawn file system before proceeding with operations that would obviously cause a BUG() to be triggered. That allows GFS2 to be safely unmounted rather than cause the system to go down. Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glock.c2
-rw-r--r--fs/gfs2/super.c3
2 files changed, 4 insertions, 1 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index ec0848fcca02..694167b4e512 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -449,6 +449,8 @@ __acquires(&gl->gl_lockref.lock)
unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0);
int ret;
+ if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+ return;
lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
LM_FLAG_PRIORITY);
GLOCK_BUG_ON(gl, gl->gl_state == target);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 361796a84fce..2a9a830fb3d6 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -793,7 +793,8 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
if (!(flags & (I_DIRTY_DATASYNC|I_DIRTY_SYNC)))
return;
-
+ if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+ return;
if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
if (ret) {