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:
 [<ffffffff8105dee1>] warn_slowpath_common+0x61/0x80
 [<ffffffffa01706fb>] xfs_vm_writepage+0x5ab/0x5c0 [xfs]
 [<ffffffff8114b833>] __writepage+0x13/0x50
 [<ffffffff8114c341>] write_cache_pages+0x251/0x4d0
 [<ffffffff8114c60d>] generic_writepages+0x4d/0x80
 [<ffffffffa016fc93>] xfs_vm_writepages+0x43/0x50 [xfs]
 [<ffffffff8114d68e>] do_writepages+0x1e/0x40
 [<ffffffff81142bd5>] __filemap_fdatawrite_range+0x65/0x80
 [<ffffffff81142cea>] filemap_write_and_wait_range+0x2a/0x70
 [<ffffffffa017a5b6>] xfs_file_fsync+0x66/0x1f0 [xfs]
 [<ffffffff811df54b>] vfs_fsync+0x2b/0x40
 [<ffffffffa03a88bd>] vn_fsync+0x2d/0x90 [spl]
 [<ffffffffa0520c33>] spa_config_sync+0x503/0x680 [zfs]
 [<ffffffffa0520ee4>] spa_config_update+0x134/0x170 [zfs]
 [<ffffffffa0520eba>] spa_config_update+0x10a/0x170 [zfs]
 [<ffffffffa051c54f>] spa_import+0x5bf/0x7b0 [zfs]
 [<ffffffffa055c754>] zfs_ioc_pool_import+0x104/0x150 [zfs]
 [<ffffffffa056294f>] zfsdev_ioctl+0x4cf/0x5c0 [zfs]
 [<ffffffffa0562480>] ? pool_status_check+0xf0/0xf0 [zfs]
 [<ffffffff811c2c85>] do_vfs_ioctl+0x2e5/0x4c0
 [<ffffffff811c2f01>] SyS_ioctl+0xa1/0xc0
 [<ffffffff815f3219>] system_call_fastpath+0x16/0x1b

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
Brian Behlendorf 2015-04-07 10:05:17 -07:00
parent ae26dd0039
commit 2a5d574eca
1 changed files with 15 additions and 1 deletions

View File

@ -543,6 +543,8 @@ EXPORT_SYMBOL(vn_getattr);
int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4) int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
{ {
int datasync = 0; int datasync = 0;
int error;
int fstrans;
ASSERT(vp); ASSERT(vp);
ASSERT(vp->v_file); ASSERT(vp->v_file);
@ -550,7 +552,19 @@ int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
if (flags & FDSYNC) if (flags & FDSYNC)
datasync = 1; 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() */ } /* vn_fsync() */
EXPORT_SYMBOL(vn_fsync); EXPORT_SYMBOL(vn_fsync);