75 lines
2.1 KiB
Plaintext
75 lines
2.1 KiB
Plaintext
From: Jeff Mahoney <jeffm@suse.com>
|
|
Subject: xfs/dmapi: Re-add flags for xfs_free_eofblocks
|
|
Patch-mainline: Depends on dmapi being upstream
|
|
|
|
2.6.33 removed the NOLOCK flag from xfs_free_eofblocks. xfs_dm_punch_hole
|
|
needs it because it already holds the iolock for the vnode it's operating
|
|
on. This patch restores the flag to avoid a pretty obvious deadlock in
|
|
dmapi.
|
|
|
|
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
|
---
|
|
fs/xfs/dmapi/xfs_dm.c | 2 +-
|
|
fs/xfs/xfs_rw.h | 6 ++++++
|
|
fs/xfs/xfs_vnodeops.c | 10 +++-------
|
|
3 files changed, 10 insertions(+), 8 deletions(-)
|
|
|
|
--- a/fs/xfs/dmapi/xfs_dm.c
|
|
+++ b/fs/xfs/dmapi/xfs_dm.c
|
|
@@ -2481,7 +2481,7 @@ xfs_dm_punch_hole(
|
|
* leaving them around if we are migrating the file....
|
|
*/
|
|
if (!error && (len == 0)) {
|
|
- error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_NOLOCK);
|
|
+ error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_HASLOCK);
|
|
}
|
|
|
|
/*
|
|
--- a/fs/xfs/xfs_rw.h
|
|
+++ b/fs/xfs/xfs_rw.h
|
|
@@ -48,6 +48,12 @@ extern xfs_extlen_t xfs_get_extsz_hint(s
|
|
/*
|
|
* Prototypes for functions in xfs_vnodeops.c.
|
|
*/
|
|
+
|
|
+/*
|
|
+ * Flags for xfs_free_eofblocks
|
|
+ */
|
|
+#define XFS_FREE_EOF_TRYLOCK (1<<0)
|
|
+#define XFS_FREE_EOF_HASLOCK (1<<1)
|
|
extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip,
|
|
int flags);
|
|
|
|
--- a/fs/xfs/xfs_vnodeops.c
|
|
+++ b/fs/xfs/xfs_vnodeops.c
|
|
@@ -584,11 +584,6 @@ xfs_readlink(
|
|
}
|
|
|
|
/*
|
|
- * 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.
|
|
@@ -652,14 +647,15 @@ xfs_free_eofblocks(
|
|
xfs_trans_cancel(tp, 0);
|
|
return 0;
|
|
}
|
|
- } else {
|
|
+ } else if (!(flags & XFS_FREE_EOF_HASLOCK)){
|
|
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
|
}
|
|
error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
|
|
ip->i_size);
|
|
if (error) {
|
|
xfs_trans_cancel(tp, 0);
|
|
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
|
+ if (!(flags & XFS_FREE_EOF_HASLOCK))
|
|
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
|
return error;
|
|
}
|
|
|