linux_dsm_epyc7002/fs
Josef Bacik d62b23c949 btrfs: set trans->drity in btrfs_commit_transaction
If we abort a transaction we have the following sequence

if (!trans->dirty && list_empty(&trans->new_bgs))
	return;
WRITE_ONCE(trans->transaction->aborted, err);

The idea being if we didn't modify anything with our trans handle then
we don't really need to abort the whole transaction, maybe the other
trans handles are fine and we can carry on.

However in the case of create_snapshot we add a pending_snapshot object
to our transaction and then commit the transaction.  We don't actually
modify anything.  sync() behaves the same way, attach to an existing
transaction and commit it.  This means that if we have an IO error in
the right places we could abort the committing transaction with our
trans->dirty being not set and thus not set transaction->aborted.

This is a problem because in the create_snapshot() case we depend on
pending->error being set to something, or btrfs_commit_transaction
returning an error.

If we are not the trans handle that gets to commit the transaction, and
we're waiting on the commit to happen we get our return value from
cur_trans->aborted.  If this was not set to anything because sync() hit
an error in the transaction commit before it could modify anything then
cur_trans->aborted would be 0.  Thus we'd return 0 from
btrfs_commit_transaction() in create_snapshot.

This is a problem because we then try to do things with
pending_snapshot->snap, which will be NULL because we didn't create the
snapshot, and then we'll get a NULL pointer dereference like the
following

"BUG: kernel NULL pointer dereference, address: 00000000000001f0"
RIP: 0010:btrfs_orphan_cleanup+0x2d/0x330
Call Trace:
 ? btrfs_mksubvol.isra.31+0x3f2/0x510
 btrfs_mksubvol.isra.31+0x4bc/0x510
 ? __sb_start_write+0xfa/0x200
 ? mnt_want_write_file+0x24/0x50
 btrfs_ioctl_snap_create_transid+0x16c/0x1a0
 btrfs_ioctl_snap_create_v2+0x11e/0x1a0
 btrfs_ioctl+0x1534/0x2c10
 ? free_debug_processing+0x262/0x2a3
 do_vfs_ioctl+0xa6/0x6b0
 ? do_sys_open+0x188/0x220
 ? syscall_trace_enter+0x1f8/0x330
 ksys_ioctl+0x60/0x90
 __x64_sys_ioctl+0x16/0x20
 do_syscall_64+0x4a/0x1b0

In order to fix this we need to make sure anybody who calls
commit_transaction has trans->dirty set so that they properly set the
trans->transaction->aborted value properly so any waiters know bad
things happened.

This was found while I was running generic/475 with my modified
fsstress, it reproduced within a few runs.  I ran with this patch all
night and didn't see the problem again.

CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2020-01-23 17:24:37 +01:00
..
9p
adfs
affs
afs Merge branch 'dhowells' (patches from DavidH) 2020-01-14 09:56:31 -08:00
autofs
befs
bfs fs: Fill in max and min timestamps in superblock 2019-08-30 07:27:17 -07:00
btrfs btrfs: set trans->drity in btrfs_commit_transaction 2020-01-23 17:24:37 +01:00
cachefiles
ceph
cifs cifs: Optimize readdir on reparse points 2019-12-23 09:04:44 -06:00
coda
configfs configfs: calculate the depth of parent item 2019-11-06 18:36:01 +01:00
cramfs
crypto
debugfs
devpts
dlm
ecryptfs
efivarfs
efs fs: Fill in max and min timestamps in superblock 2019-08-30 07:27:17 -07:00
erofs Changes since last update: 2019-12-11 12:25:32 -08:00
exportfs exportfs_decode_fh(): negative pinned may become positive without the parent locked 2019-11-10 11:56:05 -05:00
ext2 \n 2019-11-30 11:16:07 -08:00
ext4 Ext4 bug fixes (including a regression fix) for 5.5 2019-12-22 10:41:48 -08:00
f2fs
fat compat_ioctl: move drivers to compat_ptr_ioctl 2019-10-23 17:23:43 +02:00
freevxfs fs: Fill in max and min timestamps in superblock 2019-08-30 07:27:17 -07:00
fscache
fuse fuse: fix fuse_send_readpages() in the syncronous read case 2020-01-16 11:09:36 +01:00
gfs2 GFS2 changes for this merge window: 2019-12-05 13:20:11 -08:00
hfs
hfsplus
hostfs
hpfs
hugetlbfs mm/hugetlbfs: fix for_each_hstate() loop in init_hugetlbfs_fs() 2020-01-03 10:39:08 -08:00
iomap iomap: stop using ioend after it's been freed in iomap_finish_ioend() 2019-12-05 07:41:16 -08:00
isofs
jbd2
jffs2
jfs
kernfs
lockd
minix
nfs reimplement path_mountpoint() with less magic 2020-01-15 01:36:06 -05:00
nfs_common
nfsd
nilfs2
nls
notify fs: call fsnotify_sb_delete after evict_inodes 2019-12-18 00:03:01 -05:00
ntfs
ocfs2 ocfs2: fix the crash due to call ocfs2_get_dlm_debug once less 2020-01-04 13:55:09 -08:00
omfs
openpromfs Merge branch 'work.mount0' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-07-19 10:42:02 -07:00
orangefs
overlayfs overlayfs fixes for 5.5-rc2 2019-12-14 11:13:54 -08:00
proc sched/cputime, proc/stat: Fix incorrect guest nice cpustat value 2019-12-11 07:09:58 +01:00
pstore pstore/ram: Regularize prz label allocation lifetime 2020-01-08 17:05:45 -08:00
qnx4
qnx6
quota fs: avoid softlockups in s_inodes iterators 2019-12-18 00:03:01 -05:00
ramfs vfs: Convert ramfs, shmem, tmpfs, devtmpfs, rootfs to use the new mount API 2019-09-12 21:05:34 -04:00
reiserfs
romfs
squashfs
sysfs
sysv
tracefs
ubifs
udf
ufs y2038: add inode timestamp clamping 2019-09-19 09:42:37 -07:00
unicode unicode: make array 'token' static const, makes object smaller 2019-09-17 11:48:24 -04:00
verity
xfs xfs: Make the symbol 'xfs_rtalloc_log_count' static 2019-12-20 08:07:31 -08:00
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c y2038: elfcore: Use __kernel_old_timeval for process times 2019-11-15 14:38:29 +01:00
binfmt_elf.c
binfmt_em86.c
binfmt_flat.c fs/binfmt_flat.c: remove set but not used variable 'inode' 2019-07-16 19:23:22 -07:00
binfmt_misc.c
binfmt_script.c
block_dev.c
buffer.c fs: move guard_bio_eod() after bio_set_op_attrs 2020-01-09 08:16:12 -07:00
char_dev.c chardev: Avoid potential use-after-free in 'chrdev_open()' 2020-01-06 20:10:26 +01:00
compat_binfmt_elf.c y2038: elfcore: Use __kernel_old_timeval for process times 2019-11-15 14:38:29 +01:00
compat_ioctl.c New code for 5.5: 2019-12-02 14:46:22 -08:00
compat.c
coredump.c
d_path.c
dax.c
dcache.c
dcookies.c
direct-io.c fs/direct-io.c: include fs/internal.h for missing prototype 2020-01-04 13:55:09 -08:00
drop_caches.c fs: avoid softlockups in s_inodes iterators 2019-12-18 00:03:01 -05:00
eventfd.c
eventpoll.c
exec.c
fcntl.c
fhandle.c
file_table.c
file.c Revert "fs: remove ksys_dup()" 2020-01-02 16:15:33 -08:00
filesystems.c
fs_context.c
fs_parser.c
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
fsopen.c
inode.c fs: avoid softlockups in s_inodes iterators 2019-12-18 00:03:01 -05:00
internal.h fs: move guard_bio_eod() after bio_set_op_attrs 2020-01-09 08:16:12 -07:00
io_uring.c io_uring: only allow submit from owning task 2020-01-16 21:43:24 -07:00
io-wq.c io-wq: cancel work if we fail getting a mm reference 2020-01-14 22:06:11 -07:00
io-wq.h io-wq: re-add io_wq_current_is_worker() 2019-12-17 19:57:20 -07:00
ioctl.c
Kconfig
Kconfig.binfmt
libfs.c
locks.c locks: print unsigned ino in /proc/locks 2019-12-29 09:00:58 -05:00
Makefile io-wq: small threadpool implementation for io_uring 2019-10-29 12:43:00 -06:00
mbcache.c
mount.h
mpage.c fs: move guard_bio_eod() after bio_set_op_attrs 2020-01-09 08:16:12 -07:00
namei.c fix autofs regression caused by follow_managed() changes 2020-01-15 01:36:46 -05:00
namespace.c fs/namespace.c: make to_mnt_ns() static 2020-01-04 13:55:09 -08:00
no-block.c
nsfs.c fs/nsfs.c: include headers for missing declarations 2020-01-04 13:55:09 -08:00
open.c
pipe.c pipe: fix empty pipe check in pipe_write() 2019-12-22 09:47:47 -08:00
pnode.c
pnode.h
posix_acl.c fs/posix_acl.c: fix kernel-doc warnings 2020-01-04 13:55:09 -08:00
proc_namespace.c
read_write.c vfs: fix page locking deadlocks when deduping files 2019-08-16 18:43:24 -07:00
readdir.c
select.c
seq_file.c seq_file: fix problem when seeking mid-record 2019-08-13 16:06:52 -07:00
signalfd.c
splice.c
stack.c
stat.c
statfs.c
super.c fs: call fsnotify_sb_delete after evict_inodes 2019-12-18 00:03:01 -05:00
sync.c
timerfd.c
userfaultfd.c
utimes.c
xattr.c