qubes-linux-kernel/patches.suse/xfs-dmapi-re-add-flags-for-xfs_free_eofblocks

75 lines
2.1 KiB
Plaintext
Raw Normal View History

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;
}