linux/fs
Liu Bo ebb70442cd Btrfs: fix list_add corruption and soft lockups in fsync
Xfstests btrfs/146 revealed this corruption,

[   58.138831] Buffer I/O error on dev dm-0, logical block 2621424, async page read
[   58.151233] BTRFS error (device sdf): bdev /dev/mapper/error-test errs: wr 1, rd 0, flush 0, corrupt 0, gen 0
[   58.152403] list_add corruption. prev->next should be next (ffff88005e6775d8), but was ffffc9000189be88. (prev=ffffc9000189be88).
[   58.153518] ------------[ cut here ]------------
[   58.153892] WARNING: CPU: 1 PID: 1287 at lib/list_debug.c:31 __list_add_valid+0x169/0x1f0
...
[   58.157379] RIP: 0010:__list_add_valid+0x169/0x1f0
...
[   58.161956] Call Trace:
[   58.162264]  btrfs_log_inode_parent+0x5bd/0xfb0 [btrfs]
[   58.163583]  btrfs_log_dentry_safe+0x60/0x80 [btrfs]
[   58.164003]  btrfs_sync_file+0x4c2/0x6f0 [btrfs]
[   58.164393]  vfs_fsync_range+0x5f/0xd0
[   58.164898]  do_fsync+0x5a/0x90
[   58.165170]  SyS_fsync+0x10/0x20
[   58.165395]  entry_SYSCALL_64_fastpath+0x1f/0xbe
...

It turns out that we could record btrfs_log_ctx:io_err in
log_one_extents when IO fails, but make log_one_extents() return '0'
instead of -EIO, so the IO error is not acknowledged by the callers,
i.e.  btrfs_log_inode_parent(), which would remove btrfs_log_ctx:list
from list head 'root->log_ctxs'.  Since btrfs_log_ctx is allocated
from stack memory, it'd get freed with a object alive on the
list. then a future list_add will throw the above warning.

This returns the correct error in the above case.

Jeff also reported this while testing against his fsync error
patch set[1].

[1]: https://www.spinics.net/lists/linux-btrfs/msg65308.html
"btrfs list corruption and soft lockups while testing writeback error handling"

Fixes: 8407f55326 ("Btrfs: fix data corruption after fast fsync and writeback error")
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2017-11-27 17:41:19 +01:00
..
9p 9p: set page uptodate when required in write_end() 2017-10-11 09:30:08 -07:00
adfs
affs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
afs Merge branch 'akpm' (patches from Andrew) 2017-09-06 20:49:49 -07:00
autofs4 Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
befs VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
bfs bfs: fix sanity checks for empty files 2017-07-12 16:26:00 -07:00
btrfs Btrfs: fix list_add corruption and soft lockups in fsync 2017-11-27 17:41:19 +01:00
cachefiles VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
ceph ceph: unlock dangling spinlock in try_flush_caps() 2017-10-25 08:31:15 +02:00
cifs SMB3: Validate negotiate request must always be signed 2017-10-26 12:20:59 -05:00
coda fs: fix kernel_read prototype 2017-09-04 19:05:15 -04:00
configfs configfs: Introduce config_item_get_unless_zero() 2017-06-12 13:20:20 +02:00
cramfs
crypto fscrypt: fix dereference of NULL user_key_payload 2017-10-12 17:16:40 +01:00
debugfs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-07-15 12:00:42 -07:00
devpts pty: Repair TIOCGPTPEER 2017-08-24 13:23:03 -07:00
dlm File locking related changes for v4.14 2017-09-06 13:43:26 -07:00
ecryptfs ecryptfs: fix dereference of NULL user_key_payload 2017-10-12 17:16:40 +01:00
efivarfs VFS: Kill off s_options and helpers 2017-07-11 06:09:21 -04:00
efs VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
exofs Merge branch 'for-4.14/block' of git://git.kernel.dk/linux-block 2017-09-07 11:59:42 -07:00
exportfs
ext2 Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
ext4 Convert fs/*/* to SB_I_VERSION 2017-10-18 18:51:27 -04:00
f2fs f2fs: fix potential panic during fstrim 2017-10-03 08:06:05 -07:00
fat Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
freevxfs
fscache FS-Cache: fix dereference of NULL user_key_payload 2017-10-12 17:16:40 +01:00
fuse fuse: fix READDIRPLUS skipping an entry 2017-10-25 16:34:27 +02:00
gfs2 GFS2: Fix an old regression in GFS2's debugfs interface 2017-09-25 15:41:56 -07:00
hfs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
hfsplus Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
hostfs fs: convert a pile of fsync routines to errseq_t based reporting 2017-08-01 08:39:29 -04:00
hpfs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
hugetlbfs lib/interval_tree: fast overlap detection 2017-09-08 18:26:49 -07:00
isofs isofs: fix build regression 2017-09-18 12:24:26 +02:00
jbd2 Writeback error handling fixes (pile #2) 2017-07-07 19:38:17 -07:00
jffs2 Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
jfs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
kernfs Merge branch 'for-4.14/block' of git://git.kernel.dk/linux-block 2017-09-07 11:59:42 -07:00
lockd NFS client updates for Linux 4.14 2017-09-11 22:01:44 -07:00
minix VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
ncpfs fs: convert a pile of fsync routines to errseq_t based reporting 2017-08-01 08:39:29 -04:00
nfs NFSv4/pnfs: Fix an infinite layoutget loop 2017-10-04 14:06:54 -04:00
nfs_common
nfsd nfsd4: define nfsd4_secinfo_no_name_release() 2017-10-05 14:45:25 -04:00
nilfs2 Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
nls
notify fsnotify: make dnotify_fsnotify_ops const 2017-08-30 16:02:48 +02:00
ntfs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
ocfs2 Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
omfs omfs: Implement show_options 2017-07-06 03:31:46 -04:00
openpromfs
orangefs orangefs: Adjust three checks for null pointers 2017-09-14 14:58:31 -04:00
overlayfs ovl: do not cleanup unsupported index entries 2017-10-24 16:06:17 +02:00
proc sched/debug: Add explicit TASK_PARKED printing 2017-09-29 11:02:57 +02:00
pstore Revert "pstore: Honor dmesg_restrict sysctl on dmesg dumps" 2017-08-17 16:29:19 -07:00
qnx4
qnx6
quota quota: Generate warnings for DQUOT_SPACE_NOFAIL allocations 2017-10-10 17:24:46 +02:00
ramfs mm: make pagevec_lookup() update index 2017-09-06 17:27:26 -07:00
reiserfs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
romfs
squashfs squashfs: Add zstd support 2017-09-08 19:33:25 -07:00
sysfs
sysv VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
tracefs VFS: Don't use save/replace_mount_options if not using generic_show_options 2017-07-06 03:31:46 -04:00
ubifs Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
udf Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
ufs VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
xfs Changes since last time: 2017-10-26 08:45:40 +02:00
aio.c Merge branch 'work.read_write' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 19:29:55 -07:00
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c fs: fix kernel_read prototype 2017-09-04 19:05:15 -04:00
binfmt_elf_fdpic.c Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
binfmt_elf.c Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
binfmt_em86.c
binfmt_flat.c Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
binfmt_misc.c fs/binfmt_misc.c: node could be NULL when evicting inode 2017-10-13 16:18:33 -07:00
binfmt_script.c exec: load_script: kill the onstack interp[BINPRM_BUF_SIZE] array 2017-10-03 17:54:25 -07:00
block_dev.c fs/mpage.c: fix mpage_writepage() for pages with buffers 2017-10-13 16:18:33 -07:00
buffer.c Merge branch 'for-4.14/block' of git://git.kernel.dk/linux-block 2017-09-07 11:59:42 -07:00
char_dev.c char_dev: order /proc/devices by major number 2017-07-17 15:28:50 +02:00
compat_binfmt_elf.c
compat_ioctl.c media: get rid of removed DMX_GET_CAPS and DMX_SET_SOURCE leftovers 2017-09-05 08:25:07 -04:00
compat.c
coredump.c mm: treewide: remove GFP_TEMPORARY allocation flag 2017-09-13 18:53:16 -07:00
dax.c - Some request-based DM core and DM multipath fixes and cleanups 2017-09-14 13:43:16 -07:00
dcache.c Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-07-15 12:00:42 -07:00
dcookies.c
direct-io.c Changes since last update: 2017-10-18 14:51:50 -04:00
drop_caches.c
eventfd.c There has been a fair amount of activity in the docs tree this time 2017-07-03 21:13:25 -07:00
eventpoll.c fs/epoll: use faster rb_first_cached() 2017-09-08 18:26:49 -07:00
exec.c membarrier: Provide register expedited private command 2017-10-19 22:13:40 -04:00
fcntl.c fcntl: Don't set si_code to SI_SIGIO when sig == SIGPOLL 2017-09-18 22:51:14 -05:00
fhandle.c
file_table.c fput: Don't reinvent the wheel but use existing llist API 2017-08-28 00:50:23 -04:00
file.c fs/file.c: replace alloc_fdmem() with kvmalloc() alternative 2017-07-06 16:24:30 -07:00
filesystems.c Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-07-15 12:00:42 -07:00
fs_pin.c sched/wait: Disambiguate wq_entry->task_list and wq_head->task_list naming 2017-06-20 12:19:14 +02:00
fs_struct.c
fs-writeback.c writeback: rework wb_[dec|inc]_stat family of functions 2017-07-12 16:26:05 -07:00
inode.c Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs 2017-09-13 09:11:44 -07:00
internal.h Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs 2017-09-13 09:11:44 -07:00
ioctl.c
iomap.c fs: invalidate page cache after end_io() in dio completion 2017-10-16 12:11:56 -07:00
Kconfig fs/Kconfig: kill CONFIG_PERCPU_RWSEM some more 2017-07-12 16:26:00 -07:00
Kconfig.binfmt
libfs.c fs: convert __generic_file_fsync to use errseq_t based reporting 2017-07-06 07:02:29 -04:00
locks.c locks: restore a warn for leaked locks on close 2017-07-21 13:57:31 -04:00
Makefile
mbcache.c ext4: xattr inode deduplication 2017-06-22 11:44:55 -04:00
mount.h Now that IPC and other changes have landed, enable manual markings for 2017-07-19 08:55:18 -07:00
mpage.c fs/mpage.c: fix mpage_writepage() for pages with buffers 2017-10-13 16:18:33 -07:00
namei.c Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
namespace.c vfs: fix mounting a filesystem with i_version 2017-10-17 02:22:07 -04:00
no-block.c
nsfs.c VFS: Provide empty name qstr 2017-07-06 03:27:09 -04:00
open.c ovl: don't allow writing ioctl on lower layer 2017-09-05 12:53:12 +02:00
pipe.c VFS: Provide empty name qstr 2017-07-06 03:27:09 -04:00
pnode.c mnt: Make propagate_umount less slow for overlapping mount propagation trees 2017-05-23 08:41:17 -05:00
pnode.h
posix_acl.c
proc_namespace.c VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) 2017-07-17 08:45:34 +01:00
read_write.c vfs: Return -ENXIO for negative SEEK_HOLE / SEEK_DATA offsets 2017-09-26 13:46:06 -07:00
readdir.c
select.c fs/select: Fix memory corruption in compat_get_fd_set() 2017-08-28 16:09:19 -07:00
seq_file.c mm: introduce kv[mz]alloc helpers 2017-05-08 17:15:12 -07:00
signalfd.c signal: Remove kernel interal si_code magic 2017-07-24 14:30:28 -05:00
splice.c fs: move kernel_write to fs/read_write.c 2017-09-04 19:05:15 -04:00
stack.c
stat.c fs: Provide __inode_get_bytes() 2017-08-17 22:06:03 +02:00
statfs.c Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-07-08 10:50:54 -07:00
super.c Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
sync.c Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:54:01 -07:00
timerfd.c timerfd: Use get_itimerspec64() and put_itimerspec64() 2017-06-30 04:14:38 -04:00
userfaultfd.c userfaultfd: non-cooperative: fix fork use after free 2017-10-03 17:54:25 -07:00
utimes.c utimes: Make utimes y2038 safe 2017-09-03 20:24:30 -04:00
xattr.c lsm: fix smack_inode_removexattr and xattr_getsecurity memleak 2017-10-04 18:03:15 +11:00