Skip to content

Commit

Permalink
xfs: wait for the write the superblock on unmount
Browse files Browse the repository at this point in the history
v2: Add the xfs_buf_lock to xfs_quiesce_attr().
    Add explaination why xfs_buf_lock() is used to wait for write.

xfs_wait_buftarg() does not wait for the completion of the write of the
uncached superblock. This write can race with the shutdown of the log
and causes a panic if the write does not win the race.

During the log write, xfsaild_push() will lock the buffer and set the
XBF_ASYNC flag. Because the XBF_FLAG is set, complete() is not performed
on the buffer's iowait entry, we cannot call xfs_buf_iowait() to wait
for the write to complete. The buffer's lock is held until the write is
complete, so we can block on a xfs_buf_lock() request to be notified
that the write is complete.

Signed-off-by: Mark Tinguely <tinguely@sgi.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ben Myers <bpm@sgi.com>
  • Loading branch information
Mark Tinguely authored and Ben Myers committed Jul 29, 2012
1 parent 8375f92 commit 9a57fa8
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
9 changes: 9 additions & 0 deletions fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,15 @@ xfs_unmountfs(
xfs_ail_push_all_sync(mp->m_ail);
xfs_wait_buftarg(mp->m_ddev_targp);

/*
* The superblock buffer is uncached and xfsaild_push() will lock and
* set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
* here but a lock on the superblock buffer will block until iodone()
* has completed.
*/
xfs_buf_lock(mp->m_sb_bp);
xfs_buf_unlock(mp->m_sb_bp);

xfs_log_unmount_write(mp);
xfs_log_unmount(mp);
xfs_uuid_unmount(mp);
Expand Down
9 changes: 9 additions & 0 deletions fs/xfs/xfs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,15 @@ xfs_quiesce_attr(
* added an item to the AIL, thus flush it again.
*/
xfs_ail_push_all_sync(mp->m_ail);

/*
* The superblock buffer is uncached and xfsaild_push() will lock and
* set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
* here but a lock on the superblock buffer will block until iodone()
* has completed.
*/
xfs_buf_lock(mp->m_sb_bp);
xfs_buf_unlock(mp->m_sb_bp);
}

static void
Expand Down

0 comments on commit 9a57fa8

Please sign in to comment.