diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2023-12-19 16:49:26 +0100 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2023-12-27 13:16:48 +0100 |
commit | e345b87b0b0444d1c644b0ea15cfb50e88f10b55 (patch) | |
tree | 33e0443704bcdc2bc1844d04200ca0bc994ac597 /fs/gfs2/log.c | |
parent | 4e58543e7da4859c4ba61d15493e3522b6ad71fd (diff) |
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>
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 6b3ba8f7b67a..8cddf955ebc0 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -913,8 +913,9 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, static void log_write_header(struct gfs2_sbd *sdp, u32 flags) { blk_opf_t op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC; + struct super_block *sb = sdp->sd_vfs; - gfs2_assert_withdraw(sdp, !test_bit(SDF_FROZEN, &sdp->sd_flags)); + gfs2_assert_withdraw(sdp, sb->s_writers.frozen != SB_FREEZE_COMPLETE); if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { gfs2_ordered_wait(sdp); |