Skip to content

Commit e345b87

Browse files
author
Andreas Gruenbacher
committed
gfs2: Fix freeze consistency check in log_write_header
Functions gfs2_freeze_super() and gfs2_thaw_super() are using the SDF_FROZEN flag to indicate when the filesystem is frozen, synchronized by sd_freeze_mutex. However, this doesn't prevent writes from happening between the point of calling thaw_super() and the point where the SDF_FROZEN flag is cleared, so the following assert can trigger in log_write_header(): gfs2_assert_withdraw(sdp, !test_bit(SDF_FROZEN, &sdp->sd_flags)); Fix that by checking for sb->s_writers.frozen != SB_FREEZE_COMPLETE in log_write_header() instead. To make sure that the filesystem-specific part of freezing happens before sb->s_writers.frozen is set to SB_FREEZE_COMPLETE, move that code from gfs2_freeze_locally() into gfs2_freeze_fs() and hook that up to the .freeze_fs operation. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1 parent 4e58543 commit e345b87

2 files changed

Lines changed: 18 additions & 25 deletions

File tree

fs/gfs2/log.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,8 +913,9 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
913913
static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
914914
{
915915
blk_opf_t op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC;
916+
struct super_block *sb = sdp->sd_vfs;
916917

917-
gfs2_assert_withdraw(sdp, !test_bit(SDF_FROZEN, &sdp->sd_flags));
918+
gfs2_assert_withdraw(sdp, sb->s_writers.frozen != SB_FREEZE_COMPLETE);
918919

919920
if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) {
920921
gfs2_ordered_wait(sdp);

fs/gfs2/super.c

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -673,28 +673,6 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
673673
return sdp->sd_log_error;
674674
}
675675

676-
static int gfs2_freeze_locally(struct gfs2_sbd *sdp)
677-
{
678-
struct super_block *sb = sdp->sd_vfs;
679-
int error;
680-
681-
error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
682-
if (error)
683-
return error;
684-
685-
if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
686-
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
687-
GFS2_LFC_FREEZE_GO_SYNC);
688-
if (gfs2_withdrawing_or_withdrawn(sdp)) {
689-
error = thaw_super(sb, FREEZE_HOLDER_USERSPACE);
690-
if (error)
691-
return error;
692-
return -EIO;
693-
}
694-
}
695-
return 0;
696-
}
697-
698676
static int gfs2_do_thaw(struct gfs2_sbd *sdp)
699677
{
700678
struct super_block *sb = sdp->sd_vfs;
@@ -724,7 +702,7 @@ void gfs2_freeze_func(struct work_struct *work)
724702
if (test_bit(SDF_FROZEN, &sdp->sd_flags))
725703
goto freeze_failed;
726704

727-
error = gfs2_freeze_locally(sdp);
705+
error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
728706
if (error)
729707
goto freeze_failed;
730708

@@ -765,7 +743,7 @@ static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who)
765743
}
766744

767745
for (;;) {
768-
error = gfs2_freeze_locally(sdp);
746+
error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
769747
if (error) {
770748
fs_info(sdp, "GFS2: couldn't freeze filesystem: %d\n",
771749
error);
@@ -801,6 +779,19 @@ static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who)
801779
return error;
802780
}
803781

782+
static int gfs2_freeze_fs(struct super_block *sb)
783+
{
784+
struct gfs2_sbd *sdp = sb->s_fs_info;
785+
786+
if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
787+
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
788+
GFS2_LFC_FREEZE_GO_SYNC);
789+
if (gfs2_withdrawing_or_withdrawn(sdp))
790+
return -EIO;
791+
}
792+
return 0;
793+
}
794+
804795
/**
805796
* gfs2_thaw_super - reallow writes to the filesystem
806797
* @sb: the VFS structure for the filesystem
@@ -1599,6 +1590,7 @@ const struct super_operations gfs2_super_ops = {
15991590
.put_super = gfs2_put_super,
16001591
.sync_fs = gfs2_sync_fs,
16011592
.freeze_super = gfs2_freeze_super,
1593+
.freeze_fs = gfs2_freeze_fs,
16021594
.thaw_super = gfs2_thaw_super,
16031595
.statfs = gfs2_statfs,
16041596
.drop_inode = gfs2_drop_inode,

0 commit comments

Comments
 (0)