linux/fs/xfs/libxfs
Brian Foster f65e6fad29 xfs: use iomap new flag for newly allocated delalloc blocks
Commit fa7f138 ("xfs: clear delalloc and cache on buffered write
failure") fixed one regression in the iomap error handling code and
exposed another. The fundamental problem is that if a buffered write
is a rewrite of preexisting delalloc blocks and the write fails, the
failure handling code can punch out preexisting blocks with valid
file data.

This was reproduced directly by sub-block writes in the LTP
kernel/syscalls/write/write03 test. A first 100 byte write allocates
a single block in a file. A subsequent 100 byte write fails and
punches out the block, including the data successfully written by
the previous write.

To address this problem, update the ->iomap_begin() handler to
distinguish newly allocated delalloc blocks from preexisting
delalloc blocks via the IOMAP_F_NEW flag. Use this flag in the
->iomap_end() handler to decide when a failed or short write should
punch out delalloc blocks.

This introduces the subtle requirement that ->iomap_begin() should
never combine newly allocated delalloc blocks with existing blocks
in the resulting iomap descriptor. This can occur when a new
delalloc reservation merges with a neighboring extent that is part
of the current write, for example. Therefore, drop the
post-allocation extent lookup from xfs_bmapi_reserve_delalloc() and
just return the record inserted into the fork. This ensures only new
blocks are returned and thus that preexisting delalloc blocks are
always handled as "found" blocks and not punched out on a failed
rewrite.

Reported-by: Xiong Zhou <xzhou@redhat.com>
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>
2017-03-08 09:58:08 -08:00
..
xfs_ag_resv.c xfs: use per-AG reservations for the finobt 2017-01-25 07:49:35 -08:00
xfs_ag_resv.h xfs: set up per-AG free space reservations 2016-09-19 10:30:52 +10:00
xfs_alloc_btree.c Merge branch 'xfs-4.10-misc-fixes-4' into for-next 2016-12-09 16:56:26 +11:00
xfs_alloc_btree.h
xfs_alloc.c xfs: remove XFS_ALLOCTYPE_ANY_AG and XFS_ALLOCTYPE_START_AG 2017-02-17 20:32:10 -08:00
xfs_alloc.h xfs: remove XFS_ALLOCTYPE_ANY_AG and XFS_ALLOCTYPE_START_AG 2017-02-17 20:32:10 -08:00
xfs_attr_leaf.c xfs: ignore leaf attr ichdr.count in verifier during log replay 2016-12-09 16:49:47 +11:00
xfs_attr_leaf.h Merge branch 'xfs-4.10-misc-fixes-3' into for-next 2016-12-07 17:42:30 +11:00
xfs_attr_remote.c xfs: rename flist/free_list to dfops 2016-08-03 11:19:29 +10:00
xfs_attr_remote.h
xfs_attr_sf.h xfs: move struct xfs_attr_shortform to xfs_da_format.h 2016-02-08 15:00:01 +11:00
xfs_attr.c xfs: remove racy hasattr check from attr ops 2017-01-25 07:53:43 -08:00
xfs_bit.c libxfs: Optimize the loop for xfs_bitmap_empty 2016-01-04 16:10:19 +11:00
xfs_bit.h
xfs_bmap_btree.c xfs: remove boilerplate around xfs_btree_init_block 2017-01-30 16:32:24 -08:00
xfs_bmap_btree.h
xfs_bmap.c xfs: use iomap new flag for newly allocated delalloc blocks 2017-03-08 09:58:08 -08:00
xfs_bmap.h xfs: fix COW writeback race 2017-01-23 10:55:07 -08:00
xfs_btree.c xfs: filter out obviously bad btree pointers 2017-02-02 15:13:58 -08:00
xfs_btree.h xfs: filter out obviously bad btree pointers 2017-02-02 15:13:58 -08:00
xfs_cksum.h xfs: optimise CRC updates 2016-12-05 14:40:32 +11:00
xfs_da_btree.c xfs: fail _dir_open when readahead fails 2017-02-02 15:13:58 -08:00
xfs_da_btree.h xfs: fail _dir_open when readahead fails 2017-02-02 15:13:58 -08:00
xfs_da_format.c xfs: kill xfs_dir2_inou_t 2016-07-20 11:48:31 +10:00
xfs_da_format.h xfs: fix attr shortform structure alignment on cris 2016-08-03 10:59:42 +10:00
xfs_defer.c xfs: defer should abort intent items if the trans roll fails 2016-10-24 14:21:18 +11:00
xfs_defer.h xfs: implement deferred bmbt map/unmap operations 2016-10-04 11:05:44 -07:00
xfs_dir2_block.c xfs: print name of verifier if it fails 2016-01-04 16:10:19 +11:00
xfs_dir2_data.c Merge branch 'xfs-4.10-misc-fixes-3' into for-next 2016-12-07 17:42:30 +11:00
xfs_dir2_leaf.c xfs: print name of verifier if it fails 2016-01-04 16:10:19 +11:00
xfs_dir2_node.c xfs: verify free block header fields 2017-02-02 15:14:00 -08:00
xfs_dir2_priv.h xfs: move dir_ino_validate declaration per xfsprogs 2016-11-08 11:59:12 +11:00
xfs_dir2_sf.c xfs: kill xfs_dir2_inou_t 2016-07-20 11:48:31 +10:00
xfs_dir2.c xfs: fix xfs_mode_to_ftype() prototype 2017-01-18 12:39:21 -08:00
xfs_dir2.h xfs: fix xfs_mode_to_ftype() prototype 2017-01-18 12:39:21 -08:00
xfs_dquot_buf.c libxfs: clean up _calc_dquots_per_chunk 2016-10-20 15:46:18 +11:00
xfs_format.h libxfs: v3 inodes are only valid on crc-enabled filesystems 2016-10-20 15:48:38 +11:00
xfs_fs.h xfs: create a separate cow extent size hint for the allocator 2016-10-05 16:26:26 -07:00
xfs_ialloc_btree.c xfs: use per-AG reservations for the finobt 2017-01-25 07:49:35 -08:00
xfs_ialloc_btree.h xfs: use per-AG reservations for the finobt 2017-01-25 07:49:35 -08:00
xfs_ialloc.c xfs: Use xfs_icluster_size_fsb() to calculate inode chunk alignment 2017-02-16 17:20:38 -08:00
xfs_ialloc.h xfs: rename flist/free_list to dfops 2016-08-03 11:19:29 +10:00
xfs_inode_buf.c xfs: sanity check inode di_mode 2017-01-17 11:42:22 -08:00
xfs_inode_buf.h libxfs: convert ushort to unsigned short 2016-11-08 11:55:48 +11:00
xfs_inode_fork.c xfs: check for obviously bad level values in the bmbt root 2017-02-02 15:13:59 -08:00
xfs_inode_fork.h xfs: new inode extent list lookup helpers 2016-11-24 11:39:32 +11:00
xfs_log_format.h libxfs: convert ushort to unsigned short 2016-11-08 11:55:48 +11:00
xfs_log_recover.h xfs: remove unused struct declarations 2017-01-30 16:32:25 -08:00
xfs_log_rlimit.c xfs: move most of xfs_sb.h to xfs_format.h 2014-11-28 14:27:09 +11:00
xfs_quota_defs.h xfs: wire up Q_XGETNEXTQUOTA / get_nextdqblk 2016-02-08 11:27:38 +11:00
xfs_refcount_btree.c xfs: use the actual AG length when reserving blocks 2017-01-03 18:39:33 -08:00
xfs_refcount_btree.h xfs: use the actual AG length when reserving blocks 2017-01-03 18:39:33 -08:00
xfs_refcount.c xfs: rework refcount cow recovery error handling 2016-10-10 17:23:07 +11:00
xfs_refcount.h xfs: store in-progress CoW allocations in the refcount btree 2016-10-05 16:26:05 -07:00
xfs_rmap_btree.c xfs: use the actual AG length when reserving blocks 2017-01-03 18:39:33 -08:00
xfs_rmap_btree.h xfs: use the actual AG length when reserving blocks 2017-01-03 18:39:33 -08:00
xfs_rmap.c xfs: convert unwritten status of reverse mappings for shared files 2016-10-05 16:26:29 -07:00
xfs_rmap.h xfs: use interval query for rmap alloc operations on shared files 2016-10-05 16:26:29 -07:00
xfs_rtbitmap.c libxfs: fix whitespace problems 2016-11-08 11:56:13 +11:00
xfs_sb.c xfs: verify dirblocklog correctly 2017-01-24 12:23:33 -08:00
xfs_sb.h xfs: remove unused function definitions 2016-02-08 14:58:07 +11:00
xfs_shared.h xfs: define the on-disk refcount btree format 2016-10-03 09:11:18 -07:00
xfs_symlink_remote.c xfs: print name of verifier if it fails 2016-01-04 16:10:19 +11:00
xfs_trans_resv.c xfs: increase log reservations for reflink 2016-10-05 16:26:29 -07:00
xfs_trans_resv.h xfs: increase log reservations for reflink 2016-10-05 16:26:29 -07:00
xfs_trans_space.h xfs: implement swapext for rmap filesystems 2016-10-05 16:26:32 -07:00
xfs_types.h Merge branch 'xfs-4.10-extent-lookup' into for-next 2016-11-24 11:41:59 +11:00