Before this patch, function rgrp_go_inval would not invalidate the ail list, which meant that there might still be buffers outstanding on the ail that had revokes still pending. If the revokes had still not been written when the glock was given to another node, and that node (with outstanding revokes) died for some reason, the resulting journal replay would replay the un-revoked rgrps, thus wiping out changes made by the node who rightfully received the rgrp in EX. This caused metadata corruption.
Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/glops.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 9c86c8004ba7..4b0e52bf5825 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -166,6 +166,8 @@ static void rgrp_go_sync(struct gfs2_glock *gl) error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); mapping_set_error(mapping, error); gfs2_ail_empty_gl(gl); + gfs2_assert_withdraw(gl->gl_name.ln_sbd, + gl->gl_name.ln_sbd->sd_log_error == 0); spin_lock(&gl->gl_lockref.lock); rgd = gl->gl_object; @@ -196,6 +198,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags) WARN_ON_ONCE(!(flags & DIO_METADATA)); gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end); + gfs2_ail_empty_gl(gl); if (rgd) rgd->rd_flags &= ~GFS2_RDF_UPTODATE; -- 2.20.1