mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 21:53:44 +00:00
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: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
60528afa78
commit
52b1cdcb7a
@ -399,8 +399,7 @@ struct lfcc {
|
||||
* Returns: errno
|
||||
*/
|
||||
|
||||
static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
|
||||
struct gfs2_holder *freeze_gh)
|
||||
static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
|
||||
{
|
||||
struct gfs2_inode *ip;
|
||||
struct gfs2_jdesc *jd;
|
||||
@ -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,
|
||||
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) {
|
||||
error = gfs2_jdesc_check(jd);
|
||||
@ -441,7 +442,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
|
||||
}
|
||||
|
||||
if (error)
|
||||
gfs2_glock_dq_uninit(freeze_gh);
|
||||
gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
|
||||
|
||||
out:
|
||||
while (!list_empty(&list)) {
|
||||
@ -767,15 +768,19 @@ static int gfs2_freeze(struct super_block *sb)
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh);
|
||||
error = gfs2_lock_fs_check_clean(sdp);
|
||||
if (!error)
|
||||
break;
|
||||
|
||||
if (error == -EBUSY)
|
||||
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, "retrying...\n");
|
||||
msleep(1000);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user