linux/fs/xfs
Brian Foster 07d08681d2 xfs: restore buffer_head unwritten bit on ioend cancel
xfs_vm_writepage() walks each buffer_head on the page, maps to the block
on disk and attaches to a running ioend structure that represents the
I/O submission. A new ioend is created when the type of I/O (unwritten,
delayed allocation or overwrite) required for a particular buffer_head
differs from the previous. If a buffer_head is a delalloc or unwritten
buffer, the associated bits are cleared by xfs_map_at_offset() once the
buffer_head is added to the ioend.

The process of mapping each buffer_head occurs in xfs_map_blocks() and
acquires the ilock in blocking or non-blocking mode, depending on the
type of writeback in progress. If the lock cannot be acquired for
non-blocking writeback, we cancel the ioend, redirty the page and
return. Writeback will revisit the page at some later point.

Note that we acquire the ilock for each buffer on the page. Therefore
during non-blocking writeback, it is possible to add an unwritten buffer
to the ioend, clear the unwritten state, fail to acquire the ilock when
mapping a subsequent buffer and cancel the ioend. If this occurs, the
unwritten status of the buffer sitting in the ioend has been lost. The
page will eventually hit writeback again, but xfs_vm_writepage() submits
overwrite I/O instead of unwritten I/O and does not perform unwritten
extent conversion at I/O completion. This leads to data corruption
because unwritten extents are treated as holes on reads and zeroes are
returned instead of reading from disk.

Modify xfs_cancel_ioend() to restore the buffer unwritten bit for ioends
of type XFS_IO_UNWRITTEN. This ensures that unwritten extent conversion
occurs once the page is eventually written back.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-10-02 09:42:06 +10:00
..
libxfs xfs: fix crc field handling in xfs_sb_to/from_disk 2014-10-02 09:24:11 +10:00
Kconfig xfs: require 64-bit sector_t 2014-07-30 09:12:05 +10:00
kmem.c xfs: kill time.h 2014-10-02 09:18:13 +10:00
kmem.h xfs: simplify kmem_{zone_}zalloc 2013-11-06 16:31:27 -06:00
Makefile xfs: add xfs_mount sysfs kobject 2014-07-15 08:07:01 +10:00
mrlock.h
uuid.c
uuid.h
xfs_acl.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_acl.h xfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
xfs_aops.c xfs: restore buffer_head unwritten bit on ioend cancel 2014-10-02 09:42:06 +10:00
xfs_aops.h direct-io: Implement generic deferred AIO completions 2013-09-04 09:23:46 -04:00
xfs_attr_inactive.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_attr_list.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_attr.h xfs: kill xfs_vnodeops.[ch] 2013-08-12 16:53:39 -05:00
xfs_bit.c xfs: fix static and extern sparse warnings 2013-10-30 13:59:56 -05:00
xfs_bmap_util.c xfs: xfs_swap_extent_flush can be static 2014-09-23 16:20:11 +10:00
xfs_bmap_util.h xfs: refine the allocation stack switch 2014-07-15 07:08:24 +10:00
xfs_buf_item.c xfs: xfs_buf_write_fail_rl_state can be static 2014-09-23 16:15:45 +10:00
xfs_buf_item.h xfs: decouple inode and bmap btree header files 2013-10-23 16:28:49 -05:00
xfs_buf.c xfs: mark all internal workqueues as freezable 2014-09-09 11:44:46 +10:00
xfs_buf.h xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_dir2_readdir.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_discard.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_discard.h
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_dquot.c xfs: quotacheck leaves dquot buffers without verifiers 2014-08-04 12:43:26 +10:00
xfs_dquot.h xfs: run an eofblocks scan on ENOSPC/EDQUOT 2014-07-24 19:49:28 +10:00
xfs_error.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_error.h xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_export.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_export.h
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: global error sign conversion 2014-06-25 14:58:08 +10: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: lseek: the "whence" argument is called "whence" 2014-09-09 11:57:10 +10:00
xfs_filestream.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_filestream.h xfs: add filestream allocator tracepoints 2014-04-23 07:11:52 +10:00
xfs_fs.h Merge branch 'xfs-misc-fixes-3.17-1' into for-next 2014-08-04 13:54:14 +10:00
xfs_fsops.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_fsops.h
xfs_globals.c xfs: export log_recovery_delay to delay mount time log recovery 2014-09-09 11:56:13 +10:00
xfs_icache.c xfs: remove second xfs_quota.h inclusion in xfs_icache.c 2014-09-23 16:05:55 +10:00
xfs_icache.h xfs: run an eofblocks scan on ENOSPC/EDQUOT 2014-07-24 19:49:28 +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_item.c xfs: global error sign conversion 2014-06-25 14:58:08 +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_inode.c xfs: project id inheritance is a directory only flag 2014-10-02 09:18:40 +10:00
xfs_inode.h xfs: check for inode size overflow in xfs_new_eof() 2014-10-02 09:21:53 +10:00
xfs_ioctl32.c xfs: compat_xfs_bstat does not have forkoff 2014-10-02 09:17:58 +10:00
xfs_ioctl32.h xfs: compat_xfs_bstat does not have forkoff 2014-10-02 09:17:58 +10:00
xfs_ioctl.c xfs: only set extent size hint when asked 2014-10-02 09:20:30 +10:00
xfs_ioctl.h xfs: consolidate extent swap code 2013-08-12 16:56:06 -05:00
xfs_iomap.c xfs: check for null dquot in xfs_quota_calc_throttle() 2014-10-02 09:27:09 +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 xfs: flush entire last page of old EOF on truncate up 2014-09-23 22:55:00 +10:00
xfs_iops.h xfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
xfs_itable.c xfs: introduce xfs_bulkstat_ag_ichunk 2014-08-04 11:22:31 +10:00
xfs_itable.h xfs: introduce xfs_bulkstat_ag_ichunk 2014-08-04 11:22:31 +10:00
xfs_linux.h xfs: kill time.h 2014-10-02 09:18:13 +10:00
xfs_log_cil.c xfs: xlog_cil_force_lsn doesn't always wait correctly 2014-09-23 15:57:59 +10:00
xfs_log_priv.h xfs: add xlog sysfs kobject and attribute handlers 2014-07-15 08:07:29 +10:00
xfs_log_recover.c xfs: deduplicate xlog_do_recovery_pass() 2014-09-09 11:57:29 +10:00
xfs_log.c Merge branch 'xfs-misc-fixes-3.17-2' into for-next 2014-08-04 13:55:27 +10:00
xfs_log.h xfs: log vector rounding leaks log space 2014-05-20 08:18:09 +10:00
xfs_message.c xfs: decouple log and transaction headers 2013-10-23 16:17:44 -05:00
xfs_message.h
xfs_mount.c Merge branch 'xfs-misc-fixes-3.17-2' into for-next 2014-08-04 13:55:27 +10:00
xfs_mount.h xfs: add xfs_mount sysfs kobject 2014-07-15 08:07:01 +10:00
xfs_mru_cache.c xfs: mark all internal workqueues as freezable 2014-09-09 11:44:46 +10:00
xfs_mru_cache.h xfs: embedd mru_elem into parent structure 2014-04-23 07:11:51 +10:00
xfs_qm_bhv.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_qm_syscalls.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_qm.c Merge branch 'xfs-misc-fixes-3.17-2' into for-next 2014-08-04 13:55:27 +10:00
xfs_qm.h xfs: mark xfs_qm_quotacheck as static 2014-07-24 20:49:57 +10:00
xfs_quota.h xfs: split dquot buffer operations out 2013-10-23 14:28:35 -05:00
xfs_quotaops.c xfs: fix uflags detection at xfs_fs_rm_xquota 2014-07-24 21:27:17 +10:00
xfs_rtalloc.c xfs: xfs_rtget_summary can be static 2014-09-23 16:11:43 +10:00
xfs_rtalloc.h xfs: combine xfs_rtmodify_summary and xfs_rtget_summary 2014-09-09 11:58:42 +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 xfs: add debug sysfs attribute set 2014-09-09 11:52:42 +10:00
xfs_super.h xfs: require 64-bit sector_t 2014-07-30 09:12:05 +10:00
xfs_symlink.c xfs: check resblks before calling xfs_dir_canenter 2014-09-09 11:57:52 +10:00
xfs_symlink.h xfs: push down inactive transaction mgmt for remote symlinks 2013-10-08 14:53:02 -05: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: export log_recovery_delay to delay mount time log recovery 2014-09-09 11:56:13 +10:00
xfs_sysfs.c xfs: export log_recovery_delay to delay mount time log recovery 2014-09-09 11:56:13 +10:00
xfs_sysfs.h xfs: add debug sysfs attribute set 2014-09-09 11:52:42 +10: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_ail.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_trans_buf.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_trans_dquot.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs_trans_extfree.c xfs: decouple log and transaction headers 2013-10-23 16:17:44 -05:00
xfs_trans_inode.c xfs: kill time.h 2014-10-02 09:18:13 +10: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.c xfs: global error sign conversion 2014-06-25 14:58:08 +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_types.h xfs: require 64-bit sector_t 2014-07-30 09:12:05 +10:00
xfs_xattr.c xfs: global error sign conversion 2014-06-25 14:58:08 +10:00
xfs.h