linux/fs/btrfs
Filipe Manana b38ef71cb1 Btrfs: ensure ordered extent errors aren't missed on fsync
When doing a fsync with a fast path we have a time window where we can miss
the fact that writeback of some file data failed, and therefore we endup
returning success (0) from fsync when we should return an error.
The steps that lead to this are the following:

1) We start all ordered extents by calling filemap_fdatawrite_range();

2) We do some other work like locking the inode's i_mutex, start a transaction,
   start a log transaction, etc;

3) We enter btrfs_log_inode(), acquire the inode's log_mutex and collect all the
   ordered extents from inode's ordered tree into a list;

4) But by the time we do ordered extent collection, some ordered extents we started
   at step 1) might have already completed with an error, and therefore we didn't
   found them in the ordered tree and had no idea they finished with an error. This
   makes our fsync return success (0) to userspace, but has no bad effects on the log
   like for example insertion of file extent items into the log that point to unwritten
   extents, because the invalid extent maps were removed before the ordered extent
   completed (in inode.c:btrfs_finish_ordered_io).

So after collecting the ordered extents just check if the inode's i_mapping has any
error flags set (AS_EIO or AS_ENOSPC) and leave with an error if it does. Whenever
writeback fails for a page of an ordered extent, we call mapping_set_error (done in
extent_io.c:end_extent_writepage, called by extent_io.c:end_bio_extent_writepage)
that sets one of those error flags in the inode's i_mapping flags.

This change also has the side effect of fixing the issue where for fast fsyncs we
never checked/cleared the error flags from the inode's i_mapping flags, which means
that a full fsync performed after a fast fsync could get such errors that belonged
to the fast fsync - because the full fsync calls btrfs_wait_ordered_range() which
calls filemap_fdatawait_range(), and the later checks for and clears those flags,
while for fast fsyncs we never call filemap_fdatawait_range() or anything else
that checks for and clears the error flags from the inode's i_mapping.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
2014-11-21 11:59:57 -08:00
..
tests Btrfs: remove empty block groups automatically 2014-09-22 17:13:21 -07:00
acl.c
async-thread.c btrfs: remove unlikely from NULL checks 2014-10-02 16:06:19 +02:00
async-thread.h
backref.c btrfs: remove parameter blocksize from read_tree_block 2014-10-02 17:14:50 +02:00
backref.h
btrfs_inode.h Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2014-10-11 08:03:52 -04:00
check-integrity.c Btrfs: check-int: don't complain about balanced blocks 2014-11-20 17:14:30 -08:00
check-integrity.h
compression.c Btrfs: don't ignore compressed bio write errors 2014-11-20 17:14:26 -08:00
compression.h
ctree.c Btrfs: make xattr replace operations atomic 2014-11-20 17:20:07 -08:00
ctree.h Btrfs: ensure ordered extent errors aren't missed on fsync 2014-11-21 11:59:57 -08:00
delayed-inode.c
delayed-inode.h
delayed-ref.c
delayed-ref.h
dev-replace.c Btrfs: return failure if btrfs_dev_replace_finishing() failed 2014-11-20 17:14:28 -08:00
dev-replace.h
dir-item.c Btrfs: make xattr replace operations atomic 2014-11-20 17:20:07 -08:00
disk-io.c Btrfs: make sure logged extents complete in the current transaction V3 2014-11-21 11:58:32 -08:00
disk-io.h Merge branch 'cleanup/blocksize-diet-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus 2014-10-04 09:57:14 -07:00
export.c
export.h
extent_io.c Btrfs: avoid premature -ENOMEM in clear_extent_bit() 2014-11-20 17:20:06 -08:00
extent_io.h Btrfs: set page and mapping error on compressed write failure 2014-11-20 17:14:25 -08:00
extent_map.c Btrfs: do not move em to modified list when unpinning 2014-11-21 11:59:54 -08:00
extent_map.h
extent-tree.c Btrfs: move read only block groups onto their own list V2 2014-11-20 17:20:04 -08:00
file-item.c Btrfs: fix kfree on list_head in btrfs_lookup_csums_range error cleanup 2014-11-04 06:59:04 -08:00
file.c Btrfs: add helper btrfs_fdatawrite_range 2014-11-20 17:14:28 -08:00
free-space-cache.c
free-space-cache.h
hash.c btrfs: LLVMLinux: Remove VLAIS 2014-10-14 10:51:22 +02:00
hash.h
inode-item.c
inode-map.c
inode-map.h
inode.c Btrfs: ensure ordered extent errors aren't missed on fsync 2014-11-21 11:59:57 -08:00
ioctl.c vfs: export check_sticky() 2014-10-24 00:14:36 +02:00
Kconfig
locking.c
locking.h
lzo.c
Makefile
math.h
ordered-data.c Btrfs: collect only the necessary ordered extents on ranged fsync 2014-11-21 11:59:56 -08:00
ordered-data.h Btrfs: collect only the necessary ordered extents on ranged fsync 2014-11-21 11:59:56 -08:00
orphan.c
print-tree.c btrfs: remove parameter blocksize from read_tree_block 2014-10-02 17:14:50 +02:00
print-tree.h
props.c
props.h
qgroup.c btrfs: move checks for DUMMY_ROOT into a helper 2014-10-02 17:30:33 +02:00
qgroup.h
raid56.c
raid56.h
rcu-string.h
reada.c
relocation.c Merge branch 'cleanup/blocksize-diet-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus 2014-10-04 09:57:14 -07:00
root-tree.c
scrub.c btrfs: fix dead lock while running replace and defrag concurrently 2014-11-20 17:20:08 -08:00
send.c Merge branch 'cleanup/misc-for-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus 2014-10-04 09:56:45 -07:00
send.h
struct-funcs.c
super.c btrfs: fix wrong accounting of raid1 data profile in statfs 2014-11-20 17:20:09 -08:00
sysfs.c
sysfs.h
transaction.c Btrfs: make sure logged extents complete in the current transaction V3 2014-11-21 11:58:32 -08:00
transaction.h Btrfs: make sure logged extents complete in the current transaction V3 2014-11-21 11:58:32 -08:00
tree-defrag.c
tree-log.c Btrfs: ensure ordered extent errors aren't missed on fsync 2014-11-21 11:59:57 -08:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c
volumes.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2014-10-11 08:03:52 -04:00
volumes.h Btrfs: remove empty block groups automatically 2014-09-22 17:13:21 -07:00
xattr.c Btrfs: make xattr replace operations atomic 2014-11-20 17:20:07 -08:00
xattr.h
zlib.c