linux/fs/xfs
Brian Foster 04197b341f xfs: don't BUG() on mixed direct and mapped I/O
We've had reports of generic/095 causing XFS to BUG() in
__xfs_get_blocks() due to the existence of delalloc blocks on a
direct I/O read. generic/095 issues a mix of various types of I/O,
including direct and memory mapped I/O to a single file. This is
clearly not supported behavior and is known to lead to such
problems. E.g., the lack of exclusion between the direct I/O and
write fault paths means that a write fault can allocate delalloc
blocks in a region of a file that was previously a hole after the
direct read has attempted to flush/inval the file range, but before
it actually reads the block mapping. In turn, the direct read
discovers a delalloc extent and cannot proceed.

While the appropriate solution here is to not mix direct and memory
mapped I/O to the same regions of the same file, the current
BUG_ON() behavior is probably overkill as it can crash the entire
system.  Instead, localize the failure to the I/O in question by
returning an error for a direct I/O that cannot be handled safely
due to delalloc blocks. Be careful to allow the case of a direct
write to post-eof delalloc blocks. This can occur due to speculative
preallocation and is safe as post-eof blocks are not accompanied by
dirty pages in pagecache (conversely, preallocation within eof must
have been zeroed, and thus dirtied, before the inode size could have
been increased beyond said blocks).

Finally, provide an additional warning if a direct I/O write occurs
while the file is memory mapped. This may not catch all problematic
scenarios, but provides a hint that some known-to-be-problematic I/O
methods are in use.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2016-11-08 12:54:14 +11:00
..
libxfs xfs: defer should abort intent items if the trans roll fails 2016-10-24 14:21:18 +11:00
Kconfig xfs: implement iomap based buffered write path 2016-06-21 09:53:44 +10:00
kmem.c xfs: improve kmem_realloc 2016-04-06 09:47:01 +10:00
kmem.h xfs: improve kmem_realloc 2016-04-06 09:47:01 +10:00
Makefile xfs: introduce the CoW fork 2016-10-04 18:06:40 -07:00
mrlock.h
uuid.c
uuid.h
xfs_acl.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
xfs_acl.h
xfs_aops.c xfs: don't BUG() on mixed direct and mapped I/O 2016-11-08 12:54:14 +11:00
xfs_aops.h xfs: allocate delayed extents in CoW fork 2016-10-04 18:06:41 -07:00
xfs_attr_inactive.c xfs: make several functions static 2016-06-01 17:38:15 +10:00
xfs_attr_list.c xfs: make several functions static 2016-06-01 17:38:15 +10:00
xfs_attr.h xfs: remove put_value from attr ->put_listent context 2016-04-06 07:57:45 +10:00
xfs_bmap_item.c xfs: when replaying bmap operations, don't let unlinked inodes get reaped 2016-10-04 11:05:44 -07:00
xfs_bmap_item.h xfs: log bmap intent items 2016-10-04 11:05:44 -07:00
xfs_bmap_util.c xfs: implement swapext for rmap filesystems 2016-10-05 16:26:32 -07:00
xfs_bmap_util.h xfs: change xfs_bmap_{finish,cancel,init,free} -> xfs_defer_* 2016-08-03 11:18:10 +10:00
xfs_buf_item.c xfs: normalize "infinite" retries in error configs 2016-09-14 07:51:30 +10:00
xfs_buf_item.h
xfs_buf.c xfs: prevent dropping ioend completions during buftarg wait 2016-08-26 16:01:59 +10:00
xfs_buf.h xfs: track and serialize in-flight async buffers against unmount 2016-07-20 11:15:28 +10:00
xfs_dir2_readdir.c xfs: return an error when an inline directory is too small 2016-10-03 09:11:15 -07:00
xfs_discard.c xfs: rmap btree requires more reserved free space 2016-08-03 11:38:24 +10:00
xfs_discard.h
xfs_dquot_item.c xfs: allocate log vector buffers outside CIL context lock 2016-07-22 09:52:35 +10:00
xfs_dquot_item.h
xfs_dquot.c xfs: rename flist/free_list to dfops 2016-08-03 11:19:29 +10:00
xfs_dquot.h
xfs_error.c Merge branch 'xfs-4.8-misc-fixes-3' into for-next 2016-07-20 11:51:08 +10:00
xfs_error.h xfs: simulate per-AG reservations being critically low 2016-10-05 16:26:31 -07:00
xfs_export.c xfs: abstract block export operations from nfsd layouts 2016-07-15 15:31:29 -04:00
xfs_export.h
xfs_extent_busy.c xfs: remote attribute blocks aren't really userdata 2016-09-26 08:21:28 +10:00
xfs_extent_busy.h
xfs_extfree_item.c xfs: remove unnecessary parentheses from log redo item recovery functions 2016-08-03 12:29:32 +10:00
xfs_extfree_item.h xfs: refactor redo intent item processing 2016-08-03 11:23:49 +10:00
xfs_file.c xfs: merge xfs_reflink_remap_range and xfs_file_share_range 2016-10-20 15:50:07 +11:00
xfs_filestream.c Merge branch 'xfs-4.9-log-recovery-fixes' into for-next 2016-10-03 09:56:28 +11:00
xfs_filestream.h
xfs_fsops.c xfs: preallocate blocks for worst-case btree expansion 2016-10-05 16:26:27 -07:00
xfs_fsops.h xfs: preallocate blocks for worst-case btree expansion 2016-10-05 16:26:27 -07:00
xfs_globals.c xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_icache.c xfs: don't skip cow forks w/ delalloc blocks in cowblocks scan 2016-11-08 12:53:33 +11:00
xfs_icache.h xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_icreate_item.c
xfs_icreate_item.h
xfs_inode_item.c xfs: create a separate cow extent size hint for the allocator 2016-10-05 16:26:26 -07:00
xfs_inode_item.h xfs: remove timestamps from incore inode 2016-02-09 16:54:58 +11:00
xfs_inode.c xfs: reflink update for 4.9-rc1 2016-10-13 20:28:22 -07:00
xfs_inode.h xfs: set a default CoW extent size of 32 blocks 2016-10-05 16:26:31 -07:00
xfs_ioctl32.c xfs: don't pass ioflags around in the ioctl path 2016-07-20 11:29:35 +10:00
xfs_ioctl32.h
xfs_ioctl.c xfs: reflink update for 4.9-rc1 2016-10-13 20:28:22 -07:00
xfs_ioctl.h xfs: don't pass ioflags around in the ioctl path 2016-07-20 11:29:35 +10:00
xfs_iomap.c xfs: optimize writes to reflink files 2016-10-20 15:53:50 +11:00
xfs_iomap.h xfs: create a separate cow extent size hint for the allocator 2016-10-05 16:26:26 -07:00
xfs_iops.c xfs: reflink update for 4.9-rc1 2016-10-13 20:28:22 -07:00
xfs_iops.h xfs: Propagate dentry down to inode_change_ok() 2016-09-22 10:56:19 +02:00
xfs_itable.c xfs: create a separate cow extent size hint for the allocator 2016-10-05 16:26:26 -07:00
xfs_itable.h
xfs_linux.h xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_log_cil.c xfs: allocate log vector buffers outside CIL context lock 2016-07-22 09:52:35 +10:00
xfs_log_priv.h xfs: rework log recovery to submit buffers on LSN boundaries 2016-09-26 08:22:16 +10:00
xfs_log_recover.c xfs: when replaying bmap operations, don't let unlinked inodes get reaped 2016-10-04 11:05:44 -07:00
xfs_log.c Merge branch 'xfs-4.8-buf-fixes' into for-next 2016-07-20 11:53:35 +10:00
xfs_log.h xfs: make several functions static 2016-06-01 17:38:15 +10:00
xfs_message.c
xfs_message.h
xfs_mount.c xfs: unset MS_ACTIVE if mount fails 2016-10-20 15:45:40 +11:00
xfs_mount.h xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_mru_cache.c
xfs_mru_cache.h
xfs_ondisk.h xfs: define the on-disk refcount btree format 2016-10-03 09:11:18 -07:00
xfs_pnfs.c xfs: introduce refcount btree definitions 2016-10-03 09:11:16 -07:00
xfs_pnfs.h xfs: abstract block export operations from nfsd layouts 2016-07-15 15:31:29 -04:00
xfs_qm_bhv.c
xfs_qm_syscalls.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_qm.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_qm.h
xfs_quota.h
xfs_quotaops.c
xfs_refcount_item.c xfs: store in-progress CoW allocations in the refcount btree 2016-10-05 16:26:05 -07:00
xfs_refcount_item.h xfs: log refcount intent items 2016-10-03 09:11:21 -07:00
xfs_reflink.c xfs: don't skip cow forks w/ delalloc blocks in cowblocks scan 2016-11-08 12:53:33 +11:00
xfs_reflink.h xfs: don't skip cow forks w/ delalloc blocks in cowblocks scan 2016-11-08 12:53:33 +11:00
xfs_rmap_item.c xfs: convert unwritten status of reverse mappings for shared files 2016-10-05 16:26:29 -07:00
xfs_rmap_item.h xfs: convert RUI log formats to use variable length arrays 2016-09-19 10:24:27 +10:00
xfs_rtalloc.c xfs: rename flist/free_list to dfops 2016-08-03 11:19:29 +10:00
xfs_rtalloc.h xfs: make several functions static 2016-06-01 17:38:15 +10:00
xfs_stats.c xfs: introduce refcount btree definitions 2016-10-03 09:11:16 -07:00
xfs_stats.h xfs: introduce refcount btree definitions 2016-10-03 09:11:16 -07:00
xfs_super.c xfs: check inode reflink flag before calling reflink functions 2016-10-10 16:47:32 +11:00
xfs_super.h xfs: quiesce the filesystem after recovery on readonly mount 2016-09-26 08:21:44 +10:00
xfs_symlink.c xfs: rename flist/free_list to dfops 2016-08-03 11:19:29 +10:00
xfs_symlink.h
xfs_sysctl.c xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_sysctl.h xfs: garbage collect old cowextsz reservations 2016-10-05 16:26:28 -07:00
xfs_sysfs.c xfs: add some 'static' annotations 2016-10-20 15:42:30 +11:00
xfs_sysfs.h xfs: configurable error behavior via sysfs 2016-05-18 10:58:51 +10:00
xfs_trace.c xfs: rework xfs_bmap_free callers to use xfs_defer_ops 2016-08-03 11:15:38 +10:00
xfs_trace.h xfs: optimize xfs_reflink_end_cow 2016-10-20 15:54:45 +11:00
xfs_trans_ail.c xfs: Make xfsaild freezeable again 2016-02-08 14:59:07 +11:00
xfs_trans_bmap.c xfs: implement deferred bmbt map/unmap operations 2016-10-04 11:05:44 -07:00
xfs_trans_buf.c xfs: remove XBF_STALE flag wrapper macros 2016-02-10 15:01:11 +11:00
xfs_trans_dquot.c
xfs_trans_extfree.c xfs: set up per-AG free space reservations 2016-09-19 10:30:52 +10:00
xfs_trans_inode.c fs: Replace current_fs_time() with current_time() 2016-09-27 21:06:22 -04:00
xfs_trans_priv.h
xfs_trans_refcount.c xfs: connect refcount adjust functions to upper layers 2016-10-03 09:11:22 -07:00
xfs_trans_rmap.c xfs: add shared rmap map/unmap/convert log item types 2016-10-05 16:26:29 -07:00
xfs_trans.c Merge branch 'xfs-4.9-reflink-prep' into for-next 2016-10-03 09:52:31 +11:00
xfs_trans.h xfs: implement deferred bmbt map/unmap operations 2016-10-04 11:05:44 -07:00
xfs_xattr.c Make __xfs_xattr_put_listen preperly report errors. 2016-09-14 07:40:35 +10:00
xfs.h