• Dave Chinner's avatar
    xfs: make forced shutdown processing atomic · b36d4651
    Dave Chinner authored
    The running of a forced shutdown is a bit of a mess. It does racy
    checks for XFS_MOUNT_SHUTDOWN in xfs_do_force_shutdown(), then
    does more racy checks in xfs_log_force_unmount() before finally
    setting XFS_MOUNT_SHUTDOWN and XLOG_IO_ERROR under the
    log->icloglock.
    
    Move the checking and setting of XFS_MOUNT_SHUTDOWN into
    xfs_do_force_shutdown() so we only process a shutdown once and once
    only. Serialise this with the mp->m_sb_lock spinlock so that the
    state change is atomic and won't race. Move all the mount specific
    shutdown state changes from xfs_log_force_unmount() to
    xfs_do_force_shutdown() so they are done atomically with setting
    XFS_MOUNT_SHUTDOWN.
    
    Then get rid of the racy xlog_is_shutdown() check from
    xlog_force_shutdown(), and gate the log shutdown on the
    test_and_set_bit(XLOG_IO_ERROR) test under the icloglock. This
    means that the log is shutdown once and once only, and code that
    needs to prevent races with shutdown can do so by holding the
    icloglock and checking the return value of xlog_is_shutdown().
    
    This results in a predictable shutdown execution process - we set the
    shutdown flags once and process the shutdown once rather than the
    current "as many concurrent shutdowns as can race to the flag
    setting" situation we have now.
    
    Also, now that shutdown is atomic, alway emit a stack trace when the
    error level for the filesystem is high enough. This means that we
    always get a stack trace when trying to diagnose the cause of
    shutdowns in the field, rather than just for SHUTDOWN_CORRUPT_INCORE
    cases.
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
    b36d4651
xfs_log.c 110 KB