aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorMark Tinguely <tinguely@sgi.com>2012-07-24 11:59:19 -0400
committerBen Myers <bpm@sgi.com>2012-07-29 17:34:19 -0400
commit9a57fa8ee7c29e11c2a29ce058573ba99157eda7 (patch)
tree3fc564a3ad53b16a6604aa89ae3d4d26e07e2d38 /fs/xfs
parent8375f922aaa6e7a880022529202fb486315568c3 (diff)
xfs: wait for the write the superblock on unmount
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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_mount.c9
-rw-r--r--fs/xfs/xfs_sync.c9
2 files changed, 18 insertions, 0 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 9536fd190191..711ca51ca3d7 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1529,6 +1529,15 @@ xfs_unmountfs(
1529 xfs_ail_push_all_sync(mp->m_ail); 1529 xfs_ail_push_all_sync(mp->m_ail);
1530 xfs_wait_buftarg(mp->m_ddev_targp); 1530 xfs_wait_buftarg(mp->m_ddev_targp);
1531 1531
1532 /*
1533 * The superblock buffer is uncached and xfsaild_push() will lock and
1534 * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
1535 * here but a lock on the superblock buffer will block until iodone()
1536 * has completed.
1537 */
1538 xfs_buf_lock(mp->m_sb_bp);
1539 xfs_buf_unlock(mp->m_sb_bp);
1540
1532 xfs_log_unmount_write(mp); 1541 xfs_log_unmount_write(mp);
1533 xfs_log_unmount(mp); 1542 xfs_log_unmount(mp);
1534 xfs_uuid_unmount(mp); 1543 xfs_uuid_unmount(mp);
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c
index e61fc1519073..97304f10e78a 100644
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -359,6 +359,15 @@ xfs_quiesce_attr(
359 * added an item to the AIL, thus flush it again. 359 * added an item to the AIL, thus flush it again.
360 */ 360 */
361 xfs_ail_push_all_sync(mp->m_ail); 361 xfs_ail_push_all_sync(mp->m_ail);
362
363 /*
364 * The superblock buffer is uncached and xfsaild_push() will lock and
365 * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
366 * here but a lock on the superblock buffer will block until iodone()
367 * has completed.
368 */
369 xfs_buf_lock(mp->m_sb_bp);
370 xfs_buf_unlock(mp->m_sb_bp);
362} 371}
363 372
364static void 373static void