mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
gfs2: Fix freeze consistency check in gfs2_trans_add_meta
Function gfs2_trans_add_meta() checks for the SDF_FROZEN flag to make sure that no buffers are added to a transaction while the filesystem is frozen. With the recent freeze/thaw rework, the SDF_FROZEN flag is cleared after thaw_super() is called, which is sufficient for serializing freeze/thaw. However, other filesystem operations started after thaw_super() may now be calling gfs2_trans_add_meta() before the SDF_FROZEN flag is cleared, which will trigger the SDF_FROZEN check in gfs2_trans_add_meta(). Fix that by checking the s_writers.frozen state instead. In addition, make sure not to call gfs2_assert_withdraw() with the sd_log_lock spin lock held. Check for a withdrawn filesystem before checking for a frozen filesystem, and don't pin/add buffers to the current transaction in case of a failure in either case. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
This commit is contained in:
parent
94c76955e8
commit
2cbd80642b
@ -230,9 +230,11 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
|
||||
{
|
||||
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
struct super_block *sb = sdp->sd_vfs;
|
||||
struct gfs2_bufdata *bd;
|
||||
struct gfs2_meta_header *mh;
|
||||
struct gfs2_trans *tr = current->journal_info;
|
||||
bool withdraw = false;
|
||||
|
||||
lock_buffer(bh);
|
||||
if (buffer_pinned(bh)) {
|
||||
@ -266,13 +268,15 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
|
||||
(unsigned long long)bd->bd_bh->b_blocknr);
|
||||
BUG();
|
||||
}
|
||||
if (unlikely(test_bit(SDF_FROZEN, &sdp->sd_flags))) {
|
||||
fs_info(sdp, "GFS2:adding buf while frozen\n");
|
||||
gfs2_assert_withdraw(sdp, 0);
|
||||
}
|
||||
if (unlikely(gfs2_withdrawn(sdp))) {
|
||||
fs_info(sdp, "GFS2:adding buf while withdrawn! 0x%llx\n",
|
||||
(unsigned long long)bd->bd_bh->b_blocknr);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (unlikely(sb->s_writers.frozen == SB_FREEZE_COMPLETE)) {
|
||||
fs_info(sdp, "GFS2:adding buf while frozen\n");
|
||||
withdraw = true;
|
||||
goto out_unlock;
|
||||
}
|
||||
gfs2_pin(sdp, bd->bd_bh);
|
||||
mh->__pad0 = cpu_to_be64(0);
|
||||
@ -281,6 +285,8 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
|
||||
tr->tr_num_buf_new++;
|
||||
out_unlock:
|
||||
gfs2_log_unlock(sdp);
|
||||
if (withdraw)
|
||||
gfs2_assert_withdraw(sdp, 0);
|
||||
out:
|
||||
unlock_buffer(bh);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user