• Dave Chinner's avatar
    xfs: xfs_trans_commit() path must check for log shutdown · 3c4cb76b
    Dave Chinner authored
    If a shut races with xfs_trans_commit() and we have shut down the
    filesystem but not the log, we will still cancel the transaction.
    This can result in aborting dirty log items instead of committing and
    pinning them whilst the log is still running. Hence we can end up
    with dirty, unlogged metadata that isn't in the AIL in memory that
    can be flushed to disk via writeback clustering.
    
    This was discovered from a g/388 trace where an inode log item was
    having IO completed on it and it wasn't in the AIL, hence tripping
    asserts xfs_ail_check(). Inode cluster writeback started long after
    the filesystem shutdown started, and long after the transaction
    containing the dirty inode was aborted and the log item marked
    XFS_LI_ABORTED. The inode was seen as dirty and unpinned, so it
    was flushed. IO completion tried to remove the inode from the AIL,
    at which point stuff went bad:
    
     XFS (pmem1): Log I/O Error (0x6) detected at xfs_fs_goingdown+0xa3/0xf0 (fs/xfs/xfs_fsops.c:500).  Shutting down filesystem.
     XFS: Assertion failed: in_ail, file: fs/xfs/xfs_trans_ail.c, line: 67
     XFS (pmem1): Please unmount the filesystem and rectify the problem(s)
     Workqueue: xfs-buf/pmem1 xfs_buf_ioend_work
     RIP: 0010:assfail+0x27/0x2d
     Call Trace:
      <TASK>
      xfs_ail_check+0xa8/0x180
      xfs_ail_delete_one+0x3b/0xf0
      xfs_buf_inode_iodone+0x329/0x3f0
      xfs_buf_ioend+0x1f8/0x530
      xfs_buf_ioend_work+0x15/0x20
      process_one_work+0x1ac/0x390
      worker_thread+0x56/0x3c0
      kthread+0xf6/0x120
      ret_from_fork+0x1f/0x30
      </TASK>
    
    xfs_trans_commit() needs to check log state for shutdown, not mount
    state. It cannot abort dirty log items while the log is still
    running as dirty items must remained pinned in memory until they are
    either committed to the journal or the log has shut down and they
    can be safely tossed away. Hence if the log has not shut down, the
    xfs_trans_commit() path must allow completed transactions to commit
    to the CIL and pin the dirty items even if a mount shutdown has
    started.
    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>
    3c4cb76b
xfs_trans.c 35.3 KB