linux/fs/xfs
Dave Chinner e81cffc4ef xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly
commit 0d085a529b upstream.

XFS has been having trouble with stray delayed allocation extents
beyond EOF for a long time. Recent changes to the collapse range
code has triggered erroneous EBUSY errors on page invalidtion for
block size smaller than page size filesystems. These
have been caused by dirty buffers beyond EOF on a partial page which
do not get written to disk during a sync.

The issue is that write-ahead in xfs_cluster_write() finds such a
partial page and handles it by leaving the page dirty but pushing it
into a writeback state. This used to work just fine, as the
write_cache_pages() code would then find the dirty partial page in
the next mapping tree lookup as the dirty tag is still set.

Unfortunately, when we moved to a mark and sweep approach to
writeback to fix other writeback sync issues, we broken this. THe
act of marking the page as under writeback now clears the TOWRITE
tag in the radix tree, even though the page is still dirty. This
causes the TOWRITE tag to be cleared, and hence the next lookup on
the mapping tree does not find the dirty partial page and so doesn't
try to write it again.

This same writeback bug was found recently in ext4 and fixed in
commit 1c8349a ("ext4: fix data integrity sync in ordered mode")
without communication to the wider filesystem community. We can use
exactly the same fix here so the TOWRITE flag is not cleared on
partial page writes.

cc: stable@vger.kernel.org # dependent on 1c8349a171
Root-cause-found-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2014-10-30 09:40:18 -07:00
..
Kconfig xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
kmem.c xfs: use NOIO contexts for vm_map_ram 2014-03-07 16:19:14 +11:00
kmem.h xfs: simplify kmem_{zone_}zalloc 2013-11-06 16:31:27 -06:00
Makefile xfs: abstract the differences in dir2/dir3 via an ops vector 2013-10-30 13:37:38 -05:00
mrlock.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
time.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
uuid.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
uuid.h xfs: add CRC infrastructure 2012-11-19 20:11:24 -06:00
xfs.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_acl.c xfs: return -E2BIG if hit the maximum size limits of ACLs 2014-02-07 15:26:11 +11:00
xfs_acl.h xfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
xfs_ag.h xfs: support the XFS_BTNUM_FINOBT free inode btree type 2014-04-24 16:00:52 +10:00
xfs_alloc.c xfs: Fix rounding in xfs_alloc_fix_len() 2014-06-06 16:06:37 +10:00
xfs_alloc.h xfs: create a shared header file for format-related information 2013-10-23 14:11:30 -05:00
xfs_alloc_btree.c xfs: remove unused length arg from alloc_block ops 2014-04-14 19:03:53 +10:00
xfs_alloc_btree.h xfs: decouple inode and bmap btree header files 2013-10-23 16:28:49 -05:00
xfs_aops.c xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly 2014-10-30 09:40:18 -07:00
xfs_aops.h direct-io: Implement generic deferred AIO completions 2013-09-04 09:23:46 -04:00
xfs_attr.c xfs: remove redundant geometry information from xfs_da_state 2014-06-06 15:22:04 +10:00
xfs_attr.h xfs: kill xfs_vnodeops.[ch] 2013-08-12 16:53:39 -05:00
xfs_attr_inactive.c xfs: vectorise encoding/decoding directory headers 2013-10-30 13:47:22 -05:00
xfs_attr_leaf.c xfs: remove redundant geometry information from xfs_da_state 2014-06-06 15:22:04 +10:00
xfs_attr_leaf.h xfs: pass xfs_da_args to xfs_attr_leaf_newentsize 2014-06-06 15:21:27 +10:00
xfs_attr_list.c xfs: introduce directory geometry structure 2014-06-06 15:01:58 +10:00
xfs_attr_remote.c xfs: replace attr LBSIZE with xfs_da_geometry 2014-06-06 15:21:45 +10:00
xfs_attr_remote.h xfs: unify directory/attribute format definitions 2013-10-23 14:21:40 -05:00
xfs_attr_sf.h xfs: convert attr to use unsigned names 2010-01-20 10:47:48 +11:00
xfs_bit.c xfs: fix static and extern sparse warnings 2013-10-30 13:59:56 -05:00
xfs_bit.h xfs: small cleanup in xfs_lowbit64() 2014-06-06 16:04:42 +10:00
xfs_bmap.c xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_bmap.h xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_bmap_btree.c xfs: remove unused length arg from alloc_block ops 2014-04-14 19:03:53 +10:00
xfs_bmap_btree.h xfs: remove unused mp arg from xfs_bmdr_maxrecs() 2014-04-14 18:58:51 +10:00
xfs_bmap_util.c xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_bmap_util.h xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_btree.c xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_btree.h Merge branch 'xfs-free-inode-btree' into for-next 2014-05-15 09:37:44 +10:00
xfs_buf.c Merge branch 'xfs-unused-args-cleanup' into for-next 2014-05-15 09:36:35 +10:00
xfs_buf.h Merge branch 'xfs-misc-fixes-3-for-3.16' into for-next 2014-06-10 07:32:56 +10:00
xfs_buf_item.c Merge branch 'xfs-misc-fixes-3-for-3.16' into for-next 2014-06-10 07:32:56 +10:00
xfs_buf_item.h xfs: decouple inode and bmap btree header files 2013-10-23 16:28:49 -05:00
xfs_cksum.h xfs: add CRC infrastructure 2012-11-19 20:11:24 -06:00
xfs_da_btree.c Merge branch 'xfs-da-geom' into for-next 2014-06-10 07:32:41 +10:00
xfs_da_btree.h xfs: remove redundant geometry information from xfs_da_state 2014-06-06 15:22:04 +10:00
xfs_da_format.c xfs: convert m_dirblksize to xfs_da_geometry 2014-06-06 15:15:59 +10:00
xfs_da_format.h xfs: replace attr LBSIZE with xfs_da_geometry 2014-06-06 15:21:45 +10:00
xfs_dinode.h xfs: Use defines for CRC offsets in all cases 2014-02-27 15:15:27 +11:00
xfs_dir2.c Merge branch 'xfs-da-geom' into for-next 2014-06-10 07:32:41 +10:00
xfs_dir2.h xfs: remove mp->m_dir_geo from directory logging 2014-06-06 15:20:54 +10:00
xfs_dir2_block.c xfs: remove mp->m_dir_geo from directory logging 2014-06-06 15:20:54 +10:00
xfs_dir2_data.c xfs: remove mp->m_dir_geo from directory logging 2014-06-06 15:20:54 +10:00
xfs_dir2_leaf.c xfs: remove mp->m_dir_geo from directory logging 2014-06-06 15:20:54 +10:00
xfs_dir2_node.c xfs: remove redundant geometry information from xfs_da_state 2014-06-06 15:22:04 +10:00
xfs_dir2_priv.h xfs: remove mp->m_dir_geo from directory logging 2014-06-06 15:20:54 +10:00
xfs_dir2_readdir.c xfs: fix xfs_da_args sparse warning in xfs_readdir 2014-06-10 07:30:36 +10:00
xfs_dir2_sf.c xfs: convert m_dirblksize to xfs_da_geometry 2014-06-06 15:15:59 +10:00
xfs_discard.c xfs: don't perform discard if the given range length is less than block size 2013-12-10 10:00:33 -06:00
xfs_discard.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_dquot.c xfs: quotacheck leaves dquot buffers without verifiers 2014-09-17 09:22:17 -07:00
xfs_dquot.h xfs: remove dquot hints 2014-05-05 17:30:15 +10:00
xfs_dquot_buf.c xfs: remove unused mp arg from xfs_calc_dquots_per_chunk() 2014-04-14 19:03:34 +10:00
xfs_dquot_item.c xfs: remove the quotaoff log format from the quotaoff log item 2013-12-13 11:34:08 +11:00
xfs_dquot_item.h xfs: remove the quotaoff log format from the quotaoff log item 2013-12-13 11:34:08 +11:00
xfs_error.c xfs: print useful caller information in xfs_error_report 2014-02-27 15:21:37 +11:00
xfs_error.h xfs: add xfs_verifier_error() 2014-02-27 15:21:07 +11:00
xfs_export.c xfs: xfs_commit_metadata returns wrong errno 2014-05-15 09:21:52 +10:00
xfs_export.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_extent_busy.c xfs: decouple inode and bmap btree header files 2013-10-23 16:28:49 -05:00
xfs_extent_busy.h xfs: decouple inode and bmap btree header files 2013-10-23 16:28:49 -05:00
xfs_extfree_item.c xfs: format log items write directly into the linear CIL buffer 2013-12-13 11:34:02 +11:00
xfs_extfree_item.h xfs: split out EFI/EFD log item format definition 2013-08-12 16:07:13 -05:00
xfs_file.c xfs: don't zero partial page cache pages during O_DIRECT writes 2014-09-17 09:22:18 -07:00
xfs_filestream.c xfs: add filestream allocator tracepoints 2014-04-23 07:11:52 +10:00
xfs_filestream.h xfs: add filestream allocator tracepoints 2014-04-23 07:11:52 +10:00
xfs_format.h xfs: support the XFS_BTNUM_FINOBT free inode btree type 2014-04-24 16:00:52 +10:00
xfs_fs.h xfs: report finobt status in fs geometry 2014-04-24 16:01:41 +10:00
xfs_fsops.c Merge branch 'xfs-da-geom' into for-next 2014-06-10 07:32:41 +10:00
xfs_fsops.h xfs: ensure log covering transactions are synchronous 2011-01-11 20:28:17 -06:00
xfs_globals.c xfs: add background scanning to clear eofblocks inodes 2012-11-08 15:34:59 -06:00
xfs_ialloc.c Merge branch 'xfs-misc-fixes-3-for-3.16' into for-next 2014-06-10 07:32:56 +10:00
xfs_ialloc.h xfs: fix compile error when libxfs header used in C++ code 2014-05-20 08:52:21 +10:00
xfs_ialloc_btree.c Merge branch 'xfs-free-inode-btree' into for-next 2014-05-15 09:37:44 +10:00
xfs_ialloc_btree.h xfs: refactor xfs_ialloc_btree.c to support multiple inobt numbers 2014-04-24 16:00:50 +10:00
xfs_icache.c xfs: remove unused pag ptr arg from iterator execute functions 2014-04-14 19:04:19 +10:00
xfs_icache.h xfs: remove unused pag ptr arg from iterator execute functions 2014-04-14 19:04:19 +10:00
xfs_icreate_item.c xfs: format log items write directly into the linear CIL buffer 2013-12-13 11:34:02 +11:00
xfs_icreate_item.h xfs: separate icreate log format definitions from xfs_icreate_item.h 2013-08-12 16:10:35 -05:00
xfs_inode.c Merge branch 'xfs-feature-bit-cleanup' into for-next 2014-05-20 08:57:02 +10:00
xfs_inode.h Merge branch 'xfs-feature-bit-cleanup' into for-next 2014-05-20 08:57:02 +10:00
xfs_inode_buf.c xfs: turn NLINK feature on by default 2014-05-20 07:46:40 +10:00
xfs_inode_buf.h xfs: create a shared header file for format-related information 2013-10-23 14:11:30 -05:00
xfs_inode_fork.c xfs: remove unused bp arg from xfs_iflush_fork() 2014-04-14 19:04:46 +10:00
xfs_inode_fork.h xfs: remove unused bp arg from xfs_iflush_fork() 2014-04-14 19:04:46 +10:00
xfs_inode_item.c xfs: turn NLINK feature on by default 2014-05-20 07:46:40 +10:00
xfs_inode_item.h xfs: remove the inode log format from the inode log item 2013-12-13 11:34:05 +11:00
xfs_inum.h xfs: move xfsagino_t to xfs_types.h 2012-05-14 16:20:54 -05:00
xfs_ioctl.c xfs: update for 3.16-rc1 2014-06-11 09:03:47 -07:00
xfs_ioctl.h xfs: consolidate extent swap code 2013-08-12 16:56:06 -05:00
xfs_ioctl32.c xfs: Fix wrong error codes being returned 2014-05-05 17:30:20 +10:00
xfs_ioctl32.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_iomap.c xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_iomap.h xfs: get rid of count from xfs_iomap_write_allocate() 2013-10-01 15:42:34 -05:00
xfs_iops.c Merge branch 'xfs-misc-fixes-1-for-3.16' into for-next 2014-05-15 09:38:15 +10:00
xfs_iops.h xfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
xfs_itable.c xfs: refactor xfs_ialloc_btree.c to support multiple inobt numbers 2014-04-24 16:00:50 +10:00
xfs_itable.h xfs: remove block number from inode lookup code 2010-06-24 11:35:17 +10:00
xfs_linux.h xfs: add xfs_verifier_error() 2014-02-27 15:21:07 +11:00
xfs_log.c Merge branch 'xfs-misc-fixes-3-for-3.16' into for-next 2014-06-10 07:32:56 +10:00
xfs_log.h xfs: log vector rounding leaks log space 2014-05-20 08:18:09 +10:00
xfs_log_cil.c Merge branch 'xfs-misc-fixes-2-for-3.16' into for-next 2014-05-20 08:56:00 +10:00
xfs_log_format.h xfs: create a shared header file for format-related information 2013-10-23 14:11:30 -05:00
xfs_log_priv.h xfs: decouple log and transaction headers 2013-10-23 16:17:44 -05:00
xfs_log_recover.c xfs: ensure verifiers are attached to recovered buffers 2014-09-17 09:22:17 -07:00
xfs_log_recover.h xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_log_rlimit.c xfs: use xfs_da_geometry for block size in attr code 2014-06-06 15:21:10 +10:00
xfs_message.c xfs: decouple log and transaction headers 2013-10-23 16:17:44 -05:00
xfs_message.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_mount.c Merge branch 'xfs-misc-fixes-3-for-3.16' into for-next 2014-06-10 07:32:56 +10:00
xfs_mount.h xfs: move node entry counts to xfs_da_geometry 2014-06-06 15:20:02 +10:00
xfs_mru_cache.c xfs: embedd mru_elem into parent structure 2014-04-23 07:11:51 +10:00
xfs_mru_cache.h xfs: embedd mru_elem into parent structure 2014-04-23 07:11:51 +10:00
xfs_qm.c xfs: quotacheck leaves dquot buffers without verifiers 2014-09-17 09:22:17 -07:00
xfs_qm.h xfs: integrate xfs_quota_priv header file to xfs_qm 2013-12-06 14:16:33 -06:00
xfs_qm_bhv.c xfs: decouple inode and bmap btree header files 2013-10-23 16:28:49 -05:00
xfs_qm_syscalls.c Merge branch 'xfs-misc-fixes-1-for-3.16' into for-next 2014-05-15 09:38:15 +10:00
xfs_quota.h xfs: split dquot buffer operations out 2013-10-23 14:28:35 -05:00
xfs_quota_defs.h xfs: remove unused mp arg from xfs_calc_dquots_per_chunk() 2014-04-14 19:03:34 +10:00
xfs_quotaops.c xfs: fix Q_XQUOTARM ioctl 2014-05-05 17:25:50 +10:00
xfs_rtalloc.c xfs: use tr_growrtalloc for growing rt files 2014-02-07 14:53:50 +11:00
xfs_rtalloc.h xfs: split xfs_rtalloc.c for userspace sanity 2013-10-23 17:16:32 -05:00
xfs_rtbitmap.c xfs: kill xfs_buf_geterror() 2014-06-06 16:02:12 +10:00
xfs_sb.c xfs: null unused quota inodes when quota is on 2014-07-15 07:28:41 +10:00
xfs_sb.h Merge branch 'xfs-feature-bit-cleanup' into for-next 2014-05-20 08:57:02 +10:00
xfs_shared.h xfs: remove unused xfs_mount arg from xfs_symlink_hdr_ok() 2014-04-14 19:05:43 +10:00
xfs_stats.c xfs: support the XFS_BTNUM_FINOBT free inode btree type 2014-04-24 16:00:52 +10:00
xfs_stats.h xfs: support the XFS_BTNUM_FINOBT free inode btree type 2014-04-24 16:00:52 +10:00
xfs_super.c Merge branch 'xfs-filestreams-lookup' into for-next 2014-05-15 09:36:59 +10:00
xfs_super.h xfs: xfs_sync_data is redundant. 2012-10-17 12:01:25 -05:00
xfs_symlink.c xfs: convert m_dirblkfsbs to xfs_da_geometry 2014-06-06 15:14:11 +10:00
xfs_symlink.h xfs: push down inactive transaction mgmt for remote symlinks 2013-10-08 14:53:02 -05:00
xfs_symlink_remote.c xfs: remove unused xfs_mount arg from xfs_symlink_hdr_ok() 2014-04-14 19:05:43 +10:00
xfs_sysctl.c xfs: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 17:42:25 -05:00
xfs_sysctl.h xfs: add background scanning to clear eofblocks inodes 2012-11-08 15:34:59 -06:00
xfs_trace.c xfs: add filestream allocator tracepoints 2014-04-23 07:11:52 +10:00
xfs_trace.h Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2014-06-12 10:30:18 -07:00
xfs_trans.c xfs: remove unused ail pointer arg from xfs_trans_ail_cursor_done() 2014-04-14 19:06:05 +10:00
xfs_trans.h xfs: format log items write directly into the linear CIL buffer 2013-12-13 11:34:02 +11:00
xfs_trans_ail.c xfs: remove unused ail pointer arg from xfs_trans_ail_cursor_done() 2014-04-14 19:06:05 +10:00
xfs_trans_buf.c xfs: don't leak EFSBADCRC to userspace 2014-03-07 16:19:14 +11:00
xfs_trans_dquot.c xfs: fix the comment explaining xfs_trans_dqlockedjoin 2013-12-04 14:26:57 -06:00
xfs_trans_extfree.c xfs: decouple log and transaction headers 2013-10-23 16:17:44 -05:00
xfs_trans_inode.c xfs: open code inc_inode_iversion when logging an inode 2013-11-18 09:42:08 -06:00
xfs_trans_priv.h xfs: remove unused ail pointer arg from xfs_trans_ail_cursor_done() 2014-04-14 19:06:05 +10:00
xfs_trans_resv.c xfs: convert m_dirblksize to xfs_da_geometry 2014-06-06 15:15:59 +10:00
xfs_trans_resv.h Merge branch 'xfs-O_TMPFILE-support' into for-next 2014-03-13 19:14:43 +11:00
xfs_trans_space.h xfs: convert m_dirblkfsbs to xfs_da_geometry 2014-06-06 15:14:11 +10:00
xfs_types.h xfs: support the XFS_BTNUM_FINOBT free inode btree type 2014-04-24 16:00:52 +10:00
xfs_vnode.h xfs: remove unused FI_ flags 2013-12-04 14:11:05 -06:00
xfs_xattr.c xfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00