From 2a5d574ecae612a3e3ec488841b40d262184a7a3 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 7 Apr 2015 10:05:17 -0700 Subject: [PATCH] Clear PF_FSTRANS over vfs_sync() When layered on XFS the following warning will be emitted under CentOS7 when entering vfs_fsync() with PF_FSTRANS already set. This is not an issue for other stock Linux file systems and the warning was removed for newer kernels. However, to avoid triggering this error PF_FSTRANS is cleared and then reset in vn_fsync(). WARNING: at fs/xfs/xfs_aops.c:968 xfs_vm_writepage+0x5ab/0x5c0 Call Trace: [] warn_slowpath_common+0x61/0x80 [] xfs_vm_writepage+0x5ab/0x5c0 [xfs] [] __writepage+0x13/0x50 [] write_cache_pages+0x251/0x4d0 [] generic_writepages+0x4d/0x80 [] xfs_vm_writepages+0x43/0x50 [xfs] [] do_writepages+0x1e/0x40 [] __filemap_fdatawrite_range+0x65/0x80 [] filemap_write_and_wait_range+0x2a/0x70 [] xfs_file_fsync+0x66/0x1f0 [xfs] [] vfs_fsync+0x2b/0x40 [] vn_fsync+0x2d/0x90 [spl] [] spa_config_sync+0x503/0x680 [zfs] [] spa_config_update+0x134/0x170 [zfs] [] spa_config_update+0x10a/0x170 [zfs] [] spa_import+0x5bf/0x7b0 [zfs] [] zfs_ioc_pool_import+0x104/0x150 [zfs] [] zfsdev_ioctl+0x4cf/0x5c0 [zfs] [] ? pool_status_check+0xf0/0xf0 [zfs] [] do_vfs_ioctl+0x2e5/0x4c0 [] SyS_ioctl+0xa1/0xc0 [] system_call_fastpath+0x16/0x1b Signed-off-by: Brian Behlendorf --- module/spl/spl-vnode.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index bce28a580b..1e26b8e29a 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -543,6 +543,8 @@ EXPORT_SYMBOL(vn_getattr); int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4) { int datasync = 0; + int error; + int fstrans; ASSERT(vp); ASSERT(vp->v_file); @@ -550,7 +552,19 @@ int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4) if (flags & FDSYNC) datasync = 1; - return (-spl_filp_fsync(vp->v_file, datasync)); + /* + * 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); + + error = -spl_filp_fsync(vp->v_file, datasync); + if (fstrans) + current->flags |= PF_FSTRANS; + + return (error); } /* vn_fsync() */ EXPORT_SYMBOL(vn_fsync);