linux/fs
Filipe Manana d1d832a0b5 Btrfs: fix data loss after inode eviction, renaming it, and fsync it
When we log an inode, regardless of logging it completely or only that it
exists, we always update it as logged (logged_trans and last_log_commit
fields of the inode are updated). This is generally fine and avoids future
attempts to log it from having to do repeated work that brings no value.

However, if we write data to a file, then evict its inode after all the
dealloc was flushed (and ordered extents completed), rename the file and
fsync it, we end up not logging the new extents, since the rename may
result in logging that the inode exists in case the parent directory was
logged before. The following reproducer shows and explains how this can
happen:

  $ mkfs.btrfs -f /dev/sdb
  $ mount /dev/sdb /mnt

  $ mkdir /mnt/dir
  $ touch /mnt/dir/foo
  $ touch /mnt/dir/bar

  # Do a direct IO write instead of a buffered write because with a
  # buffered write we would need to make sure dealloc gets flushed and
  # complete before we do the inode eviction later, and we can not do that
  # from user space with call to things such as sync(2) since that results
  # in a transaction commit as well.
  $ xfs_io -d -c "pwrite -S 0xd3 0 4K" /mnt/dir/bar

  # Keep the directory dir in use while we evict inodes. We want our file
  # bar's inode to be evicted but we don't want our directory's inode to
  # be evicted (if it were evicted too, we would not be able to reproduce
  # the issue since the first fsync below, of file foo, would result in a
  # transaction commit.
  $ ( cd /mnt/dir; while true; do :; done ) &
  $ pid=$!

  # Wait a bit to give time for the background process to chdir.
  $ sleep 0.1

  # Evict all inodes, except the inode for the directory dir because it is
  # currently in use by our background process.
  $ echo 2 > /proc/sys/vm/drop_caches

  # fsync file foo, which ends up persisting information about the parent
  # directory because it is a new inode.
  $ xfs_io -c fsync /mnt/dir/foo

  # Rename bar, this results in logging that this inode exists (inode item,
  # names, xattrs) because the parent directory is in the log.
  $ mv /mnt/dir/bar /mnt/dir/baz

  # Now fsync baz, which ends up doing absolutely nothing because of the
  # rename operation which logged that the inode exists only.
  $ xfs_io -c fsync /mnt/dir/baz

  <power failure>

  $ mount /dev/sdb /mnt
  $ od -t x1 -A d /mnt/dir/baz
  0000000

    --> Empty file, data we wrote is missing.

Fix this by not updating last_sub_trans of an inode when we are logging
only that it exists and the inode was not yet logged since it was loaded
from disk (full_sync bit set), this is enough to make btrfs_inode_in_log()
return false for this scenario and make us log the inode. The logged_trans
of the inode is still always setsince that alone is used to track if names
need to be deleted as part of unlink operations.

Fixes: 257c62e1bc ("Btrfs: avoid tree log commit when there are no changes")
CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2019-07-02 12:30:48 +02:00
..
9p treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 188 2019-05-30 11:29:21 -07:00
adfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
affs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
afs AFS fixes 2019-06-28 08:34:12 +08:00
autofs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 83 2019-05-24 17:37:52 +02:00
befs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
bfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
btrfs Btrfs: fix data loss after inode eviction, renaming it, and fsync it 2019-07-02 12:30:48 +02:00
cachefiles treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
ceph ceph: fix ceph_mdsc_build_path to not stop on first component 2019-06-27 18:27:36 +02:00
cifs SPDX update for 5.2-rc6 2019-06-21 09:58:42 -07:00
coda treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
configfs SPDX update for 5.2-rc3, round 1 2019-05-31 08:34:32 -07:00
cramfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
crypto treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
debugfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
devpts treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 83 2019-05-24 17:37:52 +02:00
dlm treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 398 2019-06-05 17:37:12 +02:00
ecryptfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 333 2019-06-05 17:37:06 +02:00
efivarfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
efs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
exportfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
ext2 treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
ext4 Bug fixes (including a regression fix) for ext4. 2019-05-25 15:03:12 -07:00
f2fs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
fat treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
freevxfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
fscache treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
fuse Revert "fuse: require /dev/fuse reads to have enough buffer capacity" 2019-06-11 13:35:22 +02:00
gfs2 Fix rounding error in gfs2_iomap_page_prepare 2019-06-14 17:27:12 -10:00
hfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
hfsplus treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
hostfs This pull request contains the following changes for UML: 2019-05-12 17:52:13 -04:00
hpfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
hugetlbfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
isofs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 142 2019-05-30 11:25:17 -07:00
jbd2 treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
jffs2 treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
jfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
kernfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 428 2019-06-05 17:37:16 +02:00
lockd Revert "lockd: Show pid of lockd for remote locks" 2019-05-31 09:43:26 -04:00
minix treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
nfs NFS/flexfiles: Use the correct TCP timeout for flexfiles I/O 2019-06-28 11:48:52 -04:00
nfs_common treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
nfsd treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 1 2019-05-21 11:28:39 +02:00
nilfs2 treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
nls treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
notify fanotify: update connector fsid cache on add mark 2019-06-19 15:53:58 +02:00
ntfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 97 2019-05-24 17:37:53 +02:00
ocfs2 fs/ocfs2: fix race in ocfs2_dentry_attach_lock() 2019-06-13 17:34:56 -10:00
omfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 209 2019-05-30 11:29:53 -07:00
openpromfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
orangefs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
overlayfs SPDX update for 5.2-rc6 2019-06-21 09:58:42 -07:00
proc fs/proc/array.c: allow reporting eip/esp for all coredumping threads 2019-06-29 16:43:44 +08:00
pstore SPDX update for 5.2-rc4 2019-06-08 12:52:42 -07:00
qnx4 treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
qnx6 treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
quota quota: fix a problem about transfer quota 2019-06-19 15:25:41 +02:00
ramfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
reiserfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
romfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
squashfs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 499 2019-06-19 17:09:53 +02:00
sysfs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
sysv treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
tracefs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
ubifs treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 336 2019-06-05 17:37:07 +02:00
udf treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
ufs treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
unicode treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 294 2019-06-05 17:36:38 +02:00
xfs block: return from __bio_try_merge_page if merging occured in the same page 2019-06-17 09:33:02 -06:00
aio.c signal: remove the wrong signal_pending() check in restore_user_sigmask() 2019-06-29 16:43:45 +08:00
anon_inodes.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
attr.c
bad_inode.c
binfmt_aout.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
binfmt_elf_fdpic.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
binfmt_elf.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
binfmt_em86.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
binfmt_flat.c fs/binfmt_flat.c: make load_flat_shared_library() work 2019-06-29 16:43:45 +08:00
binfmt_misc.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
binfmt_script.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
block_dev.c block: Don't revalidate bdev of hidden gendisk 2019-05-27 07:35:02 -06:00
buffer.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
char_dev.c chardev: update comment based on the code 2019-04-02 17:49:58 +02:00
compat_binfmt_elf.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 193 2019-05-30 11:29:21 -07:00
compat_ioctl.c
compat.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
coredump.c
d_path.c
dax.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 288 2019-06-05 17:36:37 +02:00
dcache.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
dcookies.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
direct-io.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
drop_caches.c
eventfd.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
eventpoll.c signal: remove the wrong signal_pending() check in restore_user_sigmask() 2019-06-29 16:43:45 +08:00
exec.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
fcntl.c fs: mark expected switch fall-throughs 2019-04-08 18:21:02 -05:00
fhandle.c
file_table.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
file.c io_uring-2019-03-06 2019-03-08 14:48:40 -08:00
filesystems.c vfs: Implement a filesystem superblock creation/configuration context 2019-02-28 03:29:26 -05:00
fs_context.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
fs_parser.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
fs_pin.c
fs_struct.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
fs_types.c
fs-writeback.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
fsopen.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
inode.c mm: fix page cache convergence regression 2019-05-31 13:52:41 -04:00
internal.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
io_uring.c Merge branch 'akpm' (patches from Andrew) 2019-06-29 17:11:01 +08:00
ioctl.c
iomap.c block: return from __bio_try_merge_page if merging occured in the same page 2019-06-17 09:33:02 -06:00
Kconfig treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
Kconfig.binfmt treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
libfs.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
locks.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
Makefile Add as a feature case-insensitive directories (the casefold feature) 2019-05-07 21:12:44 -07:00
mbcache.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
mount.h
mpage.c block: remove the i argument to bio_for_each_segment_all 2019-04-30 09:26:13 -06:00
namei.c Clean up fscrypt's dcache revalidation support, and other 2019-05-07 21:28:04 -07:00
namespace.c fs/namespace: fix unprivileged mount propagation 2019-06-17 17:36:09 -04:00
no-block.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
nsfs.c nsfs: unobfuscate 2019-04-09 19:20:57 -04:00
open.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
pipe.c Merge branch 'page-refs' (page ref overflow) 2019-04-14 15:09:40 -07:00
pnode.c fs/namespace: fix unprivileged mount propagation 2019-06-17 17:36:09 -04:00
pnode.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 209 2019-05-30 11:29:53 -07:00
posix_acl.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
proc_namespace.c
read_write.c vfs: pass ppos=NULL to .read()/.write() of FMODE_STREAM files 2019-05-06 17:46:52 +03:00
readdir.c
select.c signal: remove the wrong signal_pending() check in restore_user_sigmask() 2019-06-29 16:43:45 +08:00
seq_file.c fs: mark expected switch fall-throughs 2019-04-08 18:21:02 -05:00
signalfd.c fs: mark expected switch fall-throughs 2019-04-08 18:21:02 -05:00
splice.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
stack.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
stat.c
statfs.c
super.c [fix] get rid of checking for absent device name in vfs_get_tree() 2019-04-28 21:34:21 -04:00
sync.c fs/sync.c: sync_file_range(2) may use WB_SYNC_ALL writeback 2019-05-14 09:47:50 -07:00
timerfd.c
userfaultfd.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 499 2019-06-19 17:09:53 +02:00
utimes.c
xattr.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00