From: Dave Chinner <david@fromorbit.com>
To: stable@kernel.org
Cc: xfs@oss.sgi.com
Subject: [PATCH 02/19] xfs: fix mmap_sem/iolock inversion in xfs_free_eofblocks
Date: Fri, 12 Mar 2010 09:42:00 +1100 [thread overview]
Message-ID: <1268347337-7160-3-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1268347337-7160-1-git-send-email-david@fromorbit.com>
From: Christoph Hellwig <hch@infradead.org>
>From c56c9631cbe88f08854a56ff9776c1f310916830
Date: Mon, 19 Oct 2009 04:03:46 +0000
When xfs_free_eofblocks is called from ->release the VM might already
hold the mmap_sem, but in the write path we take the iolock before
taking the mmap_sem in the generic write code.
Switch xfs_free_eofblocks to only trylock the iolock if called from
->release and skip trimming the prellocated blocks in that case.
We'll still free them later on the final iput.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
---
fs/xfs/xfs_rw.h | 7 -------
fs/xfs/xfs_vnodeops.c | 34 ++++++++++++++++++++++++++--------
2 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index f5e4874..726014d 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -37,13 +37,6 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
}
/*
- * Flags for xfs_free_eofblocks
- */
-#define XFS_FREE_EOF_LOCK (1<<0)
-#define XFS_FREE_EOF_NOLOCK (1<<1)
-
-
-/*
* helper function to extract extent size hint from inode
*/
STATIC_INLINE xfs_extlen_t
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 3fac146..d984014 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -709,6 +709,11 @@ xfs_fsync(
}
/*
+ * Flags for xfs_free_eofblocks
+ */
+#define XFS_FREE_EOF_TRYLOCK (1<<0)
+
+/*
* This is called by xfs_inactive to free any blocks beyond eof
* when the link count isn't zero and by xfs_dm_punch_hole() when
* punching a hole to EOF.
@@ -726,7 +731,6 @@ xfs_free_eofblocks(
xfs_filblks_t map_len;
int nimaps;
xfs_bmbt_irec_t imap;
- int use_iolock = (flags & XFS_FREE_EOF_LOCK);
/*
* Figure out if there are any blocks beyond the end
@@ -768,14 +772,19 @@ xfs_free_eofblocks(
* cache and we can't
* do that within a transaction.
*/
- if (use_iolock)
+ if (flags & XFS_FREE_EOF_TRYLOCK) {
+ if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
+ xfs_trans_cancel(tp, 0);
+ return 0;
+ }
+ } else {
xfs_ilock(ip, XFS_IOLOCK_EXCL);
+ }
error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
ip->i_size);
if (error) {
xfs_trans_cancel(tp, 0);
- if (use_iolock)
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
@@ -812,8 +821,7 @@ xfs_free_eofblocks(
error = xfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES);
}
- xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)
- : XFS_ILOCK_EXCL));
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
}
return error;
}
@@ -1113,7 +1121,17 @@ xfs_release(
(ip->i_df.if_flags & XFS_IFEXTENTS)) &&
(!(ip->i_d.di_flags &
(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
- error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK);
+
+ /*
+ * If we can't get the iolock just skip truncating
+ * the blocks past EOF because we could deadlock
+ * with the mmap_sem otherwise. We'll get another
+ * chance to drop them once the last reference to
+ * the inode is dropped, so we'll never leak blocks
+ * permanently.
+ */
+ error = xfs_free_eofblocks(mp, ip,
+ XFS_FREE_EOF_TRYLOCK);
if (error)
return error;
}
@@ -1184,7 +1202,7 @@ xfs_inactive(
(!(ip->i_d.di_flags &
(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
(ip->i_delayed_blks != 0)))) {
- error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK);
+ error = xfs_free_eofblocks(mp, ip, 0);
if (error)
return VN_INACTIVE_CACHE;
}
--
1.6.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2010-03-11 22:40 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1268347337-7160-1-git-send-email-david@fromorbit.com>
2010-03-11 22:41 ` [PATCH 01/19] xfs: simplify inode teardown Dave Chinner
2010-03-11 22:42 ` Dave Chinner [this message]
2010-03-11 22:42 ` [PATCH 03/19] xfs: I/O completion handlers must use NOFS allocations Dave Chinner
2010-03-11 22:42 ` [PATCH 04/19] xfs: Wrapped journal record corruption on read at recovery Dave Chinner
2010-03-11 22:42 ` [PATCH 05/19] xfs: Fix error return for fallocate() on XFS Dave Chinner
2010-03-11 22:42 ` [PATCH 06/19] xfs: check for not fully initialized inodes in xfs_ireclaim Dave Chinner
2010-03-11 22:42 ` [PATCH 07/19] xfs: fix timestamp handling in xfs_setattr Dave Chinner
2010-03-11 22:42 ` [PATCH 08/19] xfs: Don't flush stale inodes Dave Chinner
2010-03-11 22:42 ` [PATCH 09/19] xfs: Ensure we force all busy extents in range to disk Dave Chinner
2010-03-11 22:42 ` [PATCH 10/19] xfs: reclaim inodes under a write lock Dave Chinner
2010-03-11 22:42 ` [PATCH 11/19] xfs: Avoid inodes in reclaim when flushing from inode cache Dave Chinner
2010-03-11 22:42 ` [PATCH 12/19] xfs: reclaim all inodes by background tree walks Dave Chinner
2010-03-11 22:42 ` [PATCH 13/19] xfs: fix stale inode flush avoidance Dave Chinner
2010-03-11 22:42 ` [PATCH 14/19] xfs: xfs_swap_extents needs to handle dynamic fork offsets Dave Chinner
2010-03-11 22:42 ` [PATCH 15/19] xfs: quota limit statvfs available blocks Dave Chinner
2010-03-11 22:42 ` [PATCH 16/19] xfs: don't hold onto reserved blocks on remount,ro Dave Chinner
2010-03-11 22:42 ` [PATCH 17/19] xfs: remove invalid barrier optimization from xfs_fsync Dave Chinner
2010-03-11 22:42 ` [PATCH 18/19] xfs: Non-blocking inode locking in IO completion Dave Chinner
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=1268347337-7160-3-git-send-email-david@fromorbit.com \
--to=david@fromorbit.com \
--cc=stable@kernel.org \
--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