Commit 52b1cdcb authored by Bob Peterson's avatar Bob Peterson Committed by Andreas Gruenbacher

gfs2: Abort gfs2_freeze if io error is seen

Before this patch, an io error, such as -EIO writing to the journal
would cause function gfs2_freeze to go into an infinite loop,
continuously retrying the freeze operation. But nothing ever clears
the -EIO except unmount after withdraw, which is impossible if the
freeze operation never ends (fails). Instead you get:

[ 6499.767994] gfs2: fsid=dm-32.0: error freezing FS: -5
[ 6499.773058] gfs2: fsid=dm-32.0: retrying...
[ 6500.791957] gfs2: fsid=dm-32.0: error freezing FS: -5
[ 6500.797015] gfs2: fsid=dm-32.0: retrying...

This patch adds a check for -EIO in gfs2_freeze, and if seen, it
dequeues the freeze glock, aborts the loop and returns the error.
Also, there's no need to pass the freeze holder to function
gfs2_lock_fs_check_clean since it's only called in one place and
it's a well-known superblock pointer, so this simplifies that.
Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent 60528afa
...@@ -399,8 +399,7 @@ struct lfcc { ...@@ -399,8 +399,7 @@ struct lfcc {
* Returns: errno * Returns: errno
*/ */
static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
struct gfs2_holder *freeze_gh)
{ {
struct gfs2_inode *ip; struct gfs2_inode *ip;
struct gfs2_jdesc *jd; struct gfs2_jdesc *jd;
...@@ -425,7 +424,9 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, ...@@ -425,7 +424,9 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
} }
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE, error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE,
GL_NOCACHE, freeze_gh); GL_NOCACHE, &sdp->sd_freeze_gh);
if (error)
goto out;
list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
error = gfs2_jdesc_check(jd); error = gfs2_jdesc_check(jd);
...@@ -441,7 +442,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, ...@@ -441,7 +442,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
} }
if (error) if (error)
gfs2_glock_dq_uninit(freeze_gh); gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
out: out:
while (!list_empty(&list)) { while (!list_empty(&list)) {
...@@ -767,15 +768,19 @@ static int gfs2_freeze(struct super_block *sb) ...@@ -767,15 +768,19 @@ static int gfs2_freeze(struct super_block *sb)
goto out; goto out;
} }
error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); error = gfs2_lock_fs_check_clean(sdp);
if (!error) if (!error)
break; break;
if (error == -EBUSY) if (error == -EBUSY)
fs_err(sdp, "waiting for recovery before freeze\n"); fs_err(sdp, "waiting for recovery before freeze\n");
else else if (error == -EIO) {
fs_err(sdp, "Fatal IO error: cannot freeze gfs2 due "
"to recovery error.\n");
goto out;
} else {
fs_err(sdp, "error freezing FS: %d\n", error); fs_err(sdp, "error freezing FS: %d\n", error);
}
fs_err(sdp, "retrying...\n"); fs_err(sdp, "retrying...\n");
msleep(1000); msleep(1000);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment