linux/fs/xfs
Brian Foster 59e4293149 xfs: fix shared extent data corruption due to missing cow reservation
Page writeback indirectly handles shared extents via the existence
of overlapping COW fork blocks. If COW fork blocks exist, writeback
always performs the associated copy-on-write regardless if the
underlying blocks are actually shared. If the blocks are shared,
then overlapping COW fork blocks must always exist.

fstests shared/010 reproduces a case where a buffered write occurs
over a shared block without performing the requisite COW fork
reservation.  This ultimately causes writeback to the shared extent
and data corruption that is detected across md5 checks of the
filesystem across a mount cycle.

The problem occurs when a buffered write lands over a shared extent
that crosses an extent size hint boundary and that also happens to
have a partial COW reservation that doesn't cover the start and end
blocks of the data fork extent.

For example, a buffered write occurs across the file offset (in FSB
units) range of [29, 57]. A shared extent exists at blocks [29, 35]
and COW reservation already exists at blocks [32, 34]. After
accommodating a COW extent size hint of 32 blocks and the existing
reservation at offset 32, xfs_reflink_reserve_cow() allocates 32
blocks of reservation at offset 0 and returns with COW reservation
across the range of [0, 34]. The associated data fork extent is
still [29, 35], however, which isn't fully covered by the COW
reservation.

This leads to a buffered write at file offset 35 over a shared
extent without associated COW reservation. Writeback eventually
kicks in, performs an overwrite of the underlying shared block and
causes the associated data corruption.

Update xfs_reflink_reserve_cow() to accommodate the fact that a
delalloc allocation request may not fully cover the extent in the
data fork. Trim the data fork extent appropriately, just as is done
for shared extent boundaries and/or existing COW reservations that
happen to overlap the start of the data fork extent. This prevents
shared/010 failures due to data corruption on reflink enabled
filesystems.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
2018-11-19 13:30:38 -08:00
..
libxfs xfs: fix overflow in xfs_attr3_leaf_verify 2018-11-06 07:50:50 -08:00
scrub xfs: fix buffer state management in xrep_findroot_block 2018-10-18 17:20:35 +11:00
Kconfig xfs: implement the metadata repair ioctl flag 2018-05-15 18:12:50 -07:00
kmem.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
kmem.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
Makefile xfs: move the repair extent list into its own file 2018-07-29 22:37:09 -07:00
mrlock.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_acl.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_acl.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_aops.c xfs: remove XFS_IO_INVALID 2018-10-18 17:17:50 +11:00
xfs_aops.h xfs: remove XFS_IO_INVALID 2018-10-18 17:17:50 +11:00
xfs_attr_inactive.c xfs: remove all boilerplate defer init/finish code 2018-07-26 10:15:15 -07:00
xfs_attr_list.c xfs: substitute spaces with tabs 2018-08-02 23:05:14 -07:00
xfs_bmap_item.c xfs: pass transaction to xfs_defer_add() 2018-08-02 23:05:14 -07:00
xfs_bmap_item.h xfs: use transaction for intent recovery instead of raw dfops 2018-08-02 23:05:13 -07:00
xfs_bmap_util.c xfs: cancel COW blocks before swapext 2018-10-18 17:21:55 +11:00
xfs_bmap_util.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_buf_item.c xfs: refactor xfs_buf_log_item reference count handling 2018-09-29 13:45:26 +10:00
xfs_buf_item.h xfs: refactor xfs_buf_log_item reference count handling 2018-09-29 13:45:26 +10:00
xfs_buf.c xfs: clear ail delwri queued bufs on unmount of shutdown fs 2018-10-18 17:21:49 +11:00
xfs_buf.h xfs: always assign buffer verifiers when one is provided 2018-10-18 17:20:30 +11:00
xfs_dir2_readdir.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_discard.c xfs: trivial xfs_btree_del_cursor cleanups 2018-07-23 09:08:00 -07:00
xfs_discard.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_dquot_item.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_dquot_item.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_dquot.c xfs: remove dead error handling code in xfs_dquot_disk_alloc() 2018-08-07 10:57:13 -07:00
xfs_dquot.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_error.c xfs: force summary counter recalc at next mount 2018-07-23 09:08:01 -07:00
xfs_error.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_export.c xfs: clean up IRELE/iput callsites 2018-07-26 10:15:16 -07:00
xfs_export.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_extent_busy.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_extent_busy.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_extfree_item.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_extfree_item.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_file.c xfs: remove xfs_reflink_remap_range 2018-10-30 10:47:26 +11:00
xfs_filestream.c xfs: replace dop_low with transaction flag 2018-08-02 23:05:13 -07:00
xfs_filestream.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_fsmap.c xfs: trivial xfs_btree_del_cursor cleanups 2018-07-23 09:08:00 -07:00
xfs_fsmap.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_fsops.c xfs: issue log message on user force shutdown 2018-10-18 17:20:39 +11:00
xfs_fsops.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_globals.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_icache.c xfs: introduce a new xfs_inode_has_cow_data helper 2018-07-30 07:57:48 -07:00
xfs_icache.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_icreate_item.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_icreate_item.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_inode_item.c xfs: remove if_real_bytes 2018-07-30 07:57:48 -07:00
xfs_inode_item.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_inode.c xfs: remove last of unnecessary xfs_defer_cancel() callers 2018-09-29 13:41:58 +10:00
xfs_inode.h xfs: fold dfops into the transaction 2018-08-02 23:05:14 -07:00
xfs_ioctl32.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_ioctl32.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_ioctl.c xfs: Fix error code in 'xfs_ioc_getbmap()' 2018-11-06 07:50:50 -08:00
xfs_ioctl.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_iomap.c xfs: remove the unused trimmed argument from xfs_reflink_trim_around_shared 2018-10-18 17:19:48 +11:00
xfs_iomap.h xfs: avoid COW fork extent lookups in writeback if the fork didn't change 2018-07-31 13:18:09 -07:00
xfs_iops.c xfs: don't crash the vfs on a garbage inline symlink 2018-09-29 13:40:40 +10:00
xfs_iops.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_itable.c xfs: clean up IRELE/iput callsites 2018-07-26 10:15:16 -07:00
xfs_itable.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_linux.h xfs: replace do_mod with native operations 2018-06-08 10:07:52 -07:00
xfs_log_cil.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_log_priv.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_log_recover.c xfs: remove invalid log recovery first/last cycle check 2018-09-29 13:50:41 +10:00
xfs_log.c xfs: fix a comment in xfs_log_reserve 2018-08-03 08:17:54 -07:00
xfs_log.h xfs: refactor log recovery check 2018-08-01 07:40:48 -07:00
xfs_message.c xfs: print buffer offsets when dumping corrupt buffers 2018-11-06 07:50:50 -08:00
xfs_message.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfs_mount.c xfs: recalculate summary counters at mount time if icount is bad 2018-08-13 07:58:27 -07:00
xfs_mount.h xfs: remove deprecated barrier/nobarrier mount 2018-07-26 10:15:17 -07:00
xfs_mru_cache.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_mru_cache.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_ondisk.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_pnfs.c xfs: prepare xfs_break_layouts() for another layout type 2018-05-22 07:19:08 -07:00
xfs_pnfs.h xfs: prepare xfs_break_layouts() for another layout type 2018-05-22 07:19:08 -07:00
xfs_qm_bhv.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_qm_syscalls.c xfs: clean up IRELE/iput callsites 2018-07-26 10:15:16 -07:00
xfs_qm.c xfs: clean up IRELE/iput callsites 2018-07-26 10:15:16 -07:00
xfs_qm.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_quota.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_quotaops.c xfs: clean up IRELE/iput callsites 2018-07-26 10:15:16 -07:00
xfs_refcount_item.c xfs: pass transaction to xfs_defer_add() 2018-08-02 23:05:14 -07:00
xfs_refcount_item.h xfs: use transaction for intent recovery instead of raw dfops 2018-08-02 23:05:13 -07:00
xfs_reflink.c xfs: fix shared extent data corruption due to missing cow reservation 2018-11-19 13:30:38 -08:00
xfs_reflink.h vfs: rework data cloning infrastructure 2018-11-02 09:33:08 -07:00
xfs_rmap_item.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_rmap_item.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_rtalloc.c xfs: clean up IRELE/iput callsites 2018-07-26 10:15:16 -07:00
xfs_rtalloc.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_stats.c xfs: use offsetof() in place of offset macros for __xfsstats 2018-10-18 17:21:39 +11:00
xfs_stats.h xfs: use offsetof() in place of offset macros for __xfsstats 2018-10-18 17:21:39 +11:00
xfs_super.c xfs: add a define for statfs magic to uapi 2018-10-18 17:20:19 +11:00
xfs_super.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_symlink.c xfs: automatic dfops inode relogging 2018-08-02 23:05:14 -07:00
xfs_symlink.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_sysctl.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_sysctl.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_sysfs.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_sysfs.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_trace.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_trace.h xfs: don't unlock invalidated buf on aborted tx commit 2018-09-29 13:44:40 +10:00
xfs_trans_ail.c xfs: clear ail delwri queued bufs on unmount of shutdown fs 2018-10-18 17:21:49 +11:00
xfs_trans_bmap.c xfs: drop dop param from xfs_defer_op_type ->finish_item() callback 2018-08-02 23:05:14 -07:00
xfs_trans_buf.c xfs: fix buffer state management in xrep_findroot_block 2018-10-18 17:20:35 +11:00
xfs_trans_dquot.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_trans_extfree.c xfs: drop dop param from xfs_defer_op_type ->finish_item() callback 2018-08-02 23:05:14 -07:00
xfs_trans_inode.c vfs/y2038: inode timestamps conversion to timespec64 2018-06-15 07:31:07 +09:00
xfs_trans_priv.h xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs_trans_refcount.c xfs: drop dop param from xfs_defer_op_type ->finish_item() callback 2018-08-02 23:05:14 -07:00
xfs_trans_rmap.c xfs: drop dop param from xfs_defer_op_type ->finish_item() callback 2018-08-02 23:05:14 -07:00
xfs_trans.c xfs: avoid lockdep false positives in xfs_trans_alloc 2018-09-29 13:46:21 +10:00
xfs_trans.h xfs: fix buffer state management in xrep_findroot_block 2018-10-18 17:20:35 +11:00
xfs_xattr.c xfs: convert to SPDX license tags 2018-06-06 14:17:53 -07:00
xfs.h xfs: remove b_last_holder & associated macros 2018-08-12 08:37:31 -07:00