aboutsummaryrefslogtreecommitdiffstats
path: root/module/spl
diff options
context:
space:
mode:
authorTim Chase <[email protected]>2016-04-26 06:33:52 -0500
committerBrian Behlendorf <[email protected]>2016-04-26 11:22:43 -0700
commitea2633ad264912788428213607f8298c0aeafec4 (patch)
treed6cc68698af35de4be1c2cb7b3417163f9175420 /module/spl
parent3bf657b90c792ff4539a75d3b66593de556580c0 (diff)
Clear PF_FSTRANS over spl_filp_fallocate()
The problem described in 2a5d574 also applies to XFS's file or inode fallocate method. Both paths may trigger writeback and expose this issue, see the full stack below. When layered on XFS a warning will be emitted under CentOS7 when entering either the file or inode fallocate method with PF_FSTRANS already set. To avoid triggering this error PF_FSTRANS is cleared and then reset in vn_space(). WARNING: at fs/xfs/xfs_aops.c:982 xfs_vm_writepage+0x58b/0x5d0 Call Trace: [<ffffffff810a1ed5>] warn_slowpath_common+0x95/0xe0 [<ffffffff810a1f3a>] warn_slowpath_null+0x1a/0x20 [<ffffffffa0231fdb>] xfs_vm_writepage+0x58b/0x5d0 [xfs] [<ffffffff81173ed7>] __writepage+0x17/0x40 [<ffffffff81176f81>] write_cache_pages+0x251/0x530 [<ffffffff811772b1>] generic_writepages+0x51/0x80 [<ffffffffa0230cb0>] xfs_vm_writepages+0x60/0x80 [xfs] [<ffffffff81177300>] do_writepages+0x20/0x30 [<ffffffff8116a5f5>] __filemap_fdatawrite_range+0xb5/0x100 [<ffffffff8116a6cb>] filemap_write_and_wait_range+0x8b/0xd0 [<ffffffffa0235bb4>] xfs_free_file_space+0xf4/0x520 [xfs] [<ffffffffa023cbce>] xfs_file_fallocate+0x19e/0x2c0 [xfs] [<ffffffffa036c6fc>] vn_space+0x3c/0x40 [spl] [<ffffffffa0434817>] vdev_file_io_start+0x207/0x260 [zfs] [<ffffffffa047170d>] zio_vdev_io_start+0xad/0x2d0 [zfs] [<ffffffffa0474942>] zio_execute+0x82/0xe0 [zfs] [<ffffffffa036ba7d>] taskq_thread+0x28d/0x5a0 [spl] [<ffffffff810c1777>] kthread+0xd7/0xf0 [<ffffffff8167de2f>] ret_from_fork+0x3f/0x70 Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Tim Chase <[email protected]> Signed-off-by: Nikolay Borisov <[email protected]> Closes zfsonlinux/zfs#4529
Diffstat (limited to 'module/spl')
-rw-r--r--module/spl/spl-vnode.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c
index 80e4a0ffd..a914e046c 100644
--- a/module/spl/spl-vnode.c
+++ b/module/spl/spl-vnode.c
@@ -571,6 +571,9 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
offset_t offset, void *x6, void *x7)
{
int error = EOPNOTSUPP;
+#ifdef FALLOC_FL_PUNCH_HOLE
+ int fstrans;
+#endif
if (cmd != F_FREESP || bfp->l_whence != 0)
return (EOPNOTSUPP);
@@ -581,12 +584,24 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
#ifdef FALLOC_FL_PUNCH_HOLE
/*
+ * May enter XFS which generates a warning when PF_FSTRANS is set.
+ * To avoid this the flag is cleared over vfs_sync() and then reset.
+ */
+ fstrans = spl_fstrans_check();
+ if (fstrans)
+ current->flags &= ~(PF_FSTRANS);
+
+ /*
* When supported by the underlying file system preferentially
* use the fallocate() callback to preallocate the space.
*/
error = -spl_filp_fallocate(vp->v_file,
FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
bfp->l_start, bfp->l_len);
+
+ if (fstrans)
+ current->flags |= PF_FSTRANS;
+
if (error == 0)
return (0);
#endif