• Dave Chinner's avatar
    xfs: xfs_do_force_shutdown needs to block racing shutdowns · 41e63621
    Dave Chinner authored
    When we call xfs_forced_shutdown(), the caller often expects the
    filesystem to be completely shut down when it returns. However,
    if we have racing xfs_forced_shutdown() calls, the first caller sets
    the mount shutdown flag then goes to shutdown the log. The second
    caller sees the mount shutdown flag and returns immediately - it
    does not wait for the log to be shut down.
    
    Unfortunately, xfs_forced_shutdown() is used in some places that
    expect it to completely shut down the filesystem before it returns
    (e.g. xfs_trans_log_inode()). As such, returning before the log has
    been shut down leaves us in a place where the transaction failed to
    complete correctly but we still call xfs_trans_commit(). This
    situation arises because xfs_trans_log_inode() does not return an
    error and instead calls xfs_force_shutdown() to ensure that the
    transaction being committed is aborted.
    
    Unfortunately, we have a race condition where xfs_trans_commit()
    needs to check xlog_is_shutdown() because it can't abort log items
    before the log is shut down, but it needs to use xfs_is_shutdown()
    because xfs_forced_shutdown() does not block waiting for the log to
    shut down.
    
    To fix this conundrum, first we make all calls to
    xfs_forced_shutdown() block until the log is also shut down. This
    means we can then safely use xfs_forced_shutdown() as a mechanism
    that ensures the currently running transaction will be aborted by
    xfs_trans_commit() regardless of the shutdown check it uses.
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
    Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
    41e63621
xfs_log_priv.h 25.1 KB