From: David Chinner <dgc@sgi.com>
To: xfs-dev <xfs-dev@sgi.com>
Cc: xfs-oss <xfs@oss.sgi.com>
Subject: review: prevent log tail-pushing unmount deadlock
Date: Wed, 6 Jun 2007 15:37:48 +1000 [thread overview]
Message-ID: <20070606053748.GV86004887@sgi.com> (raw)
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.
Recently discovered during testing with filestreams enabled.
Cheers,
Dave.
--
Dave Chinner
Principal Engineer
SGI Australian Software Group
---
fs/xfs/xfs_mount.c | 11 +++++++++++
1 file changed, 11 insertions(+)
Index: 2.6.x-xfs-new/fs/xfs/xfs_mount.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_mount.c 2007-04-19 13:47:41.272642686 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_mount.c 2007-04-19 13:49:53.643581957 +1000
@@ -1162,6 +1162,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct 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);
reply other threads:[~2007-06-06 5:38 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070606053748.GV86004887@sgi.com \
--to=dgc@sgi.com \
--cc=xfs-dev@sgi.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox