• Bob Peterson's avatar
    gfs2: Perform second log flush in gfs2_make_fs_ro · 68ca088d
    Bob Peterson authored
    Before this patch, function gfs2_make_fs_ro called gfs2_log_flush once to
    finalize the log. However, if there's dirty metadata, log flushes tend
    to sync the metadata and formulate revokes. Before this patch, those
    revokes may not be written out to the journal immediately, which meant
    unresolved glocks could still have revokes in their ail lists. When the
    glock worker runs, it tries to transition the glock, but the unresolved
    revokes in the ail still need to be written, so it tries to start a
    transaction. It's impossible to start a transaction because at that
    point, the SDF_JOURNAL_LIVE flag has been cleared by gfs2_make_fs_ro.
    That causes the glock worker to fail, unable to write the revokes. The
    calling sequence looked something like this:
    
    gfs2_make_fs_ro
       gfs2_log_flush - with GFS2_LOG_HEAD_FLUSH_SHUTDOWN flag set
    	if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN)
    		clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
    ...meanwhile...
    glock_work_func
       do_xmote
          rgrp_go_sync (or possibly inode_go_sync)
             ...
             gfs2_ail_empty_gl
                __gfs2_trans_begin
                   if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
                   ...
                      return -EROFS;
    
    The previous patch in the series ("gfs2: return errors from
    gfs2_ail_empty_gl") now causes the transaction error to no longer be
    ignored, so it causes a warning from MOST of the xfstests:
    
    WARNING: CPU: 11 PID: X at fs/gfs2/super.c:603 gfs2_put_super [gfs2]
    
    which corresponds to:
    
    WARN_ON(gfs2_withdrawing(sdp));
    
    The withdraw was triggered silently from do_xmote by:
    
    	if (unlikely(sdp->sd_log_error && !gfs2_withdrawn(sdp)))
    		gfs2_withdraw_delayed(sdp);
    
    This patch adds a second log_flush to gfs2_make_fs_ro: one to sync the
    data and one to sync any outstanding revokes and finalize the journal.
    Note that both of these log flushes need to be "special," in other
    words, not GFS2_LOG_HEAD_FLUSH_NORMAL.
    Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
    Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
    68ca088d
super.c 38.4 KB