Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=641c56fbfeae85d5ec87fee90a752f7b7224f236
Commit:     641c56fbfeae85d5ec87fee90a752f7b7224f236
Parent:     0164af51cedf46e1d58fd53854373f544150c597
Author:     David Chinner <[EMAIL PROTECTED]>
AuthorDate: Mon Jun 18 16:50:17 2007 +1000
Committer:  Tim Shimmin <[EMAIL PROTECTED]>
CommitDate: Sat Jul 14 15:33:38 2007 +1000

    [XFS] Prevent deadlock when flushing inodes on unmount
    
    When we are unmounting the filesystem, we flush all the inodes to disk.
    Unfortunately, if we have an inode cluster that has just been freed and
    marked stale sitting in an incore log buffer (i.e. hasn't been flushed to
    disk), it will be holding all the flush locks on the inodes in that
    cluster.
    
    xfs_iflush_all() which is called during unmount walks all the inodes
    trying to reclaim them, and it doing so calls xfs_finish_reclaim() on each
    inode. If the inode is dirty, if grabs the flush lock and flushes it.
    Unfortunately, find dirty inodes that already have their flush lock held
    and so we sleep.
    
    At this point in the unmount process, we are running single-threaded.
    There is nothing more that can push on the log to force the transaction
    holding the inode flush locks to disk and hence we deadlock.
    
    The fix is to issue a log force before flushing the inodes on unmount so
    that all the flush locks will be released before we start flushing the
    inodes.
    
    SGI-PV: 964538
    SGI-Modid: xfs-linux-melb:xfs-kern:28862a
    
    Signed-off-by: David Chinner <[EMAIL PROTECTED]>
    Signed-off-by: Tim Shimmin <[EMAIL PROTECTED]>
---
 fs/xfs/xfs_mount.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index f6fe47d..39cf6f3 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1182,6 +1182,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
        int64_t         fsid;
 #endif
 
+       /*
+        * We can potentially deadlock here if we have an inode cluster
+        * that has been freed has it's buffer still pinned in memory because
+        * the transaction is still sitting in a iclog. The stale inodes
+        * on that buffer will have their flush locks held until the
+        * transaction hits the disk and the callbacks run. the inode
+        * flush takes the flush lock unconditionally and with nothing to
+        * push out the iclog we will never get that unlocked. hence we
+        * need to force the log first.
+        */
+       xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);
        xfs_iflush_all(mp);
 
        XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to