xfs
[Top] [All Lists]

[PATCH v2] xfs: wait for the write the superblock on unmount

To: xfs@xxxxxxxxxxx
Subject: [PATCH v2] xfs: wait for the write the superblock on unmount
From: tinguely@xxxxxxx
Date: Tue, 24 Jul 2012 10:59:19 -0500
References: <20120724155918.484063773@xxxxxxx>
User-agent: quilt/0.51-1
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@xxxxxxx>
Reviewed-by: Christoph Hellwig<hch@xxxxxx>

---
 fs/xfs/xfs_mount.c |    9 +++++++++
 fs/xfs/xfs_sync.c  |    9 +++++++++
 2 files changed, 18 insertions(+)

Index: b/fs/xfs/xfs_mount.c
===================================================================
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -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);
Index: b/fs/xfs/xfs_sync.c
===================================================================
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -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


<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH v2] xfs: wait for the write the superblock on unmount, tinguely <=