android_kernel_oneplus_msm8998/fs
Filipe Manana 686e4352e3 Btrfs: do not start a transaction at iterate_extent_inodes()
commit bfc61c36260ca990937539cd648ede3cd749bc10 upstream.

When finding out which inodes have references on a particular extent, done
by backref.c:iterate_extent_inodes(), from the BTRFS_IOC_LOGICAL_INO (both
v1 and v2) ioctl and from scrub we use the transaction join API to grab a
reference on the currently running transaction, since in order to give
accurate results we need to inspect the delayed references of the currently
running transaction.

However, if there is currently no running transaction, the join operation
will create a new transaction. This is inefficient as the transaction will
eventually be committed, doing unnecessary IO and introducing a potential
point of failure that will lead to a transaction abort due to -ENOSPC, as
recently reported [1].

That's because the join, creates the transaction but does not reserve any
space, so when attempting to update the root item of the root passed to
btrfs_join_transaction(), during the transaction commit, we can end up
failling with -ENOSPC. Users of a join operation are supposed to actually
do some filesystem changes and reserve space by some means, which is not
the case of iterate_extent_inodes(), it is a read-only operation for all
contextes from which it is called.

The reported [1] -ENOSPC failure stack trace is the following:

 heisenberg kernel: ------------[ cut here ]------------
 heisenberg kernel: BTRFS: Transaction aborted (error -28)
 heisenberg kernel: WARNING: CPU: 0 PID: 7137 at fs/btrfs/root-tree.c:136 btrfs_update_root+0x22b/0x320 [btrfs]
(...)
 heisenberg kernel: CPU: 0 PID: 7137 Comm: btrfs-transacti Not tainted 4.19.0-4-amd64  Debian 4.19.28-2
 heisenberg kernel: Hardware name: FUJITSU LIFEBOOK U757/FJNB2A5, BIOS Version 1.21 03/19/2018
 heisenberg kernel: RIP: 0010:btrfs_update_root+0x22b/0x320 [btrfs]
(...)
 heisenberg kernel: RSP: 0018:ffffb5448828bd40 EFLAGS: 00010286
 heisenberg kernel: RAX: 0000000000000000 RBX: ffff8ed56bccef50 RCX: 0000000000000006
 heisenberg kernel: RDX: 0000000000000007 RSI: 0000000000000092 RDI: ffff8ed6bda166a0
 heisenberg kernel: RBP: 00000000ffffffe4 R08: 00000000000003df R09: 0000000000000007
 heisenberg kernel: R10: 0000000000000000 R11: 0000000000000001 R12: ffff8ed63396a078
 heisenberg kernel: R13: ffff8ed092d7c800 R14: ffff8ed64f5db028 R15: ffff8ed6bd03d068
 heisenberg kernel: FS:  0000000000000000(0000) GS:ffff8ed6bda00000(0000) knlGS:0000000000000000
 heisenberg kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 heisenberg kernel: CR2: 00007f46f75f8000 CR3: 0000000310a0a002 CR4: 00000000003606f0
 heisenberg kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 heisenberg kernel: DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
 heisenberg kernel: Call Trace:
 heisenberg kernel:  commit_fs_roots+0x166/0x1d0 [btrfs]
 heisenberg kernel:  ? _cond_resched+0x15/0x30
 heisenberg kernel:  ? btrfs_run_delayed_refs+0xac/0x180 [btrfs]
 heisenberg kernel:  btrfs_commit_transaction+0x2bd/0x870 [btrfs]
 heisenberg kernel:  ? start_transaction+0x9d/0x3f0 [btrfs]
 heisenberg kernel:  transaction_kthread+0x147/0x180 [btrfs]
 heisenberg kernel:  ? btrfs_cleanup_transaction+0x530/0x530 [btrfs]
 heisenberg kernel:  kthread+0x112/0x130
 heisenberg kernel:  ? kthread_bind+0x30/0x30
 heisenberg kernel:  ret_from_fork+0x35/0x40
 heisenberg kernel: ---[ end trace 05de912e30e012d9 ]---

So fix that by using the attach API, which does not create a transaction
when there is currently no running transaction.

[1] https://lore.kernel.org/linux-btrfs/b2a668d7124f1d3e410367f587926f622b3f03a4.camel@scientia.net/

Reported-by: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-11 12:23:38 +02:00
..
9p 9p locks: add mount option for lock retry interval 2019-04-27 09:33:58 +02:00
adfs
affs affs_lookup(): close a race with affs_remove_link() 2018-05-30 07:48:51 +02:00
afs afs: Fix afs_kill_pages() 2017-12-20 10:04:56 +01:00
autofs4 autofs: fix error return in autofs_fill_super() 2019-03-23 08:44:27 +01:00
befs
bfs bfs: add sanity check at bfs_fill_super() 2018-12-01 09:46:33 +01:00
btrfs Btrfs: do not start a transaction at iterate_extent_inodes() 2019-06-11 12:23:38 +02:00
cachefiles fscache, cachefiles: remove redundant variable 'cache' 2018-12-17 21:55:12 +01:00
ceph ceph: fix use-after-free on symlink traversal 2019-05-16 19:44:59 +02:00
cifs cifs: do not attempt cifs operation on smb2+ rename error 2019-05-16 19:44:43 +02:00
coda coda: fix 'kernel memory exposure attempt' in fsync 2017-11-24 08:32:25 +01:00
configfs configfs: replace strncpy with memcpy 2018-11-21 09:27:44 +01:00
cramfs Cramfs: fix abad comparison when wrap-arounds occur 2018-11-21 09:27:37 +01:00
debugfs debugfs: fix use-after-free on symlink traversal 2019-05-16 19:45:01 +02:00
devpts devpts: clean up interface to pty drivers 2016-08-16 09:30:49 +02:00
dlm dlm: Don't swamp the CPU with callbacks queued during recovery 2019-02-20 10:13:04 +01:00
ecryptfs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
efivarfs efi: Make efivarfs entries immutable by default 2016-03-03 15:07:09 -08:00
efs
exofs fs/exofs: fix potential memory leak in mount option parsing 2018-11-27 16:08:00 +01:00
exportfs exportfs: do not read dentry after free 2018-12-17 21:55:10 +01:00
ext2 ext2: Fix underflow in ext2_max_size() 2019-03-23 08:44:36 +01:00
ext4 ext4: fix ext4_show_options for file systems w/o journal 2019-06-11 12:23:38 +02:00
f2fs f2fs: fix to do sanity check with current segment number 2019-04-27 09:33:58 +02:00
fat fs/fat/fatent.c: add cond_resched() to fat_count_free_clusters() 2018-11-10 07:41:40 -08:00
freevxfs
fscache fscache: fix race between enablement and dropping of object 2018-12-17 21:55:11 +01:00
fuse fuse: handle zero sized retrieve correctly 2019-02-20 10:13:16 +01:00
gfs2 gfs2: Revert "Fix loop in gfs2_rbm_find" 2019-02-06 19:43:07 +01:00
hfs hfs: do not free node before using 2018-12-17 21:55:12 +01:00
hfsplus hfsplus: do not free node before using 2018-12-17 21:55:12 +01:00
hostfs hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common() 2016-09-30 10:18:39 +02:00
hpfs hpfs: implement the show_options method 2016-06-01 12:15:54 -07:00
hugetlbfs hugetlbfs: fix memory leak for resv_map 2019-05-16 19:45:02 +02:00
isofs isofs: fix timestamps beyond 2027 2017-11-30 08:37:20 +00:00
jbd2 jbd2: fix compile warning when using JBUFFER_TRACE 2019-03-23 08:44:37 +01:00
jffs2 jffs2: fix use-after-free on symlink traversal 2019-05-16 19:45:01 +02:00
jfs jfs: Fix inconsistency between memory allocation and ea_buf->max_size 2018-08-09 12:19:28 +02:00
kernfs kernfs: Replace strncpy with memcpy 2018-12-13 09:21:29 +01:00
lockd lockd: fix access beyond unterminated strings in prints 2018-11-21 09:27:36 +01:00
logfs mm, fs: introduce mapping_gfp_constraint() 2015-11-06 17:50:42 -08:00
minix
ncpfs ncpfs: fix build warning of strncpy 2019-03-23 08:44:21 +01:00
nfs NFS: Forbid setting AF_INET6 to "struct sockaddr_in"->sin_family. 2019-05-16 19:44:51 +02:00
nfs_common lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:04:28 +01:00
nfsd nfsd: Don't release the callback slot unless it was actually held 2019-05-16 19:44:44 +02:00
nilfs2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
nls
notify fanotify: fix logic of events on child 2018-04-24 09:32:11 +02:00
ntfs mm, fs: introduce mapping_gfp_constraint() 2015-11-06 17:50:42 -08:00
ocfs2 ocfs2: fix ocfs2 read inode data panic in ocfs2_iget 2019-06-11 12:23:37 +02:00
omfs
openpromfs
overlayfs ovl: fix uid/gid when creating over whiteout 2019-04-27 09:33:59 +02:00
proc fs/proc/proc_sysctl.c: Fix a NULL pointer dereference 2019-05-16 19:44:51 +02:00
pstore pstore/ram: Do not treat empty buffers as valid 2019-01-26 09:42:53 +01:00
qnx4
qnx6
quota fs/quota: Fix spectre gadget in do_quotactl 2018-09-09 20:04:36 +02:00
ramfs
reiserfs reiserfs: propagate errors from fill_with_dentries() properly 2018-11-27 16:08:00 +01:00
romfs romfs: use different way to generate fsid for BLOCK or MTD 2017-06-17 06:39:38 +02:00
squashfs squashfs: more metadata hardenings 2018-08-06 16:24:42 +02:00
sysfs scsi: sysfs: Introduce sysfs_{un,}break_active_protection() 2018-09-05 09:18:40 +02:00
sysv sysv: return 'err' instead of 0 in __sysv_write_inode 2018-12-17 21:55:09 +01:00
tracefs
ubifs ubifs: Check for name being NULL while mounting 2018-10-13 09:11:34 +02:00
udf udf: Fix crash on IO error during truncate 2019-04-03 06:23:14 +02:00
ufs do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:48:52 +02:00
xfs xfs: don't fail when converting shortform attr to long form during ATTR_REPLACE 2019-01-26 09:42:52 +01:00
aio.c aio: fix spectre gadget in lookup_ioctx 2018-12-21 14:09:50 +01:00
anon_inodes.c
attr.c vfs: move permission checking into notify_change() for utimes(NULL) 2016-10-22 12:26:56 +02:00
bad_inode.c
binfmt_aout.c
binfmt_elf.c binfmt_elf: switch to new creds when switching to new mm 2019-04-27 09:33:53 +02:00
binfmt_elf_fdpic.c libnvdimm for 4.4: 2015-11-10 12:07:22 -08:00
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c fs/binfmt_misc.c: do not allow offset overflow 2018-07-03 11:21:26 +02:00
binfmt_script.c Revert "exec: load_script: don't blindly truncate shebang string" 2019-02-20 10:13:20 +01:00
block_dev.c fs/block_dev: always invalidate cleancache in invalidate_bdev() 2017-05-20 14:27:01 +02:00
buffer.c fs: fix guard_bio_eod to check for real EOD errors 2019-04-27 09:33:49 +02:00
char_dev.c
compat.c
compat_binfmt_elf.c binfmt_elf: compat: avoid unused function warning 2018-02-25 11:03:51 +01:00
compat_ioctl.c fs: compat: Remove warning from COMPATIBLE_IOCTL 2018-04-08 11:51:57 +02:00
coredump.c coredump: Ensure proper size of sparse core files 2017-07-05 14:37:20 +02:00
dax.c dax: disable pmd mappings 2015-11-16 23:54:45 -08:00
dcache.c Hang/soft lockup in d_invalidate with simultaneous calls 2019-04-03 06:23:19 +02:00
dcookies.c
direct-io.c direct-io: Prevent NULL pointer access in submit_page_section 2017-10-18 09:20:42 +02:00
drop_caches.c fs/drop_caches.c: avoid softlockups in drop_pagecache_sb() 2019-03-23 08:44:26 +01:00
eventfd.c
eventpoll.c fs/epoll: drop ovflist branch prediction 2019-02-20 10:13:14 +01:00
exec.c mm: replace get_user_pages() write/force parameters with gup_flags 2018-12-17 21:55:16 +01:00
fcntl.c fs/fcntl: f_setown, avoid undefined behaviour 2018-01-31 12:06:11 +01:00
fhandle.c fs/coredump: prevent fsuid=0 dumps into user-controlled directories 2016-04-12 09:08:58 -07:00
file.c fs/file.c: initialize init_files.resize_wait 2019-04-27 09:33:49 +02:00
file_table.c
filesystems.c
fs-writeback.c bdi: Fix oops in wb_workfn() 2018-05-16 10:06:51 +02:00
fs_pin.c
fs_struct.c
inode.c writeback: initialize inode members that track writeback history 2019-04-03 06:23:21 +02:00
internal.h
ioctl.c
Kconfig dax: disable pmd mappings 2015-11-16 23:54:45 -08:00
Kconfig.binfmt
libfs.c
locks.c locks: don't check for race with close when setting OFD lock 2018-01-17 09:35:27 +01:00
Makefile
mbcache.c
mount.h mnt: In propgate_umount handle visiting mounts in any order 2017-07-21 07:44:57 +02:00
mpage.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
namei.c namei: allow restricted O_CREAT of FIFOs and regular files 2018-12-01 09:46:41 +01:00
namespace.c mount: Prevent MNT_DETACH from disconnecting locked mounts 2018-11-21 09:27:44 +01:00
no-block.c
nsfs.c nsfs: mark dentry with DCACHE_RCUACCESS 2018-02-16 20:09:43 +01:00
open.c fs: completely ignore unknown open flags 2017-07-15 11:57:44 +02:00
pipe.c pipe: cap initial pipe capacity according to pipe-max-size limit 2018-05-26 08:48:51 +02:00
pnode.c mnt: Make propagate_umount less slow for overlapping mount propagation trees 2017-07-21 07:44:58 +02:00
pnode.h mnt: Add a per mount namespace limit on the number of mounts 2017-04-30 05:49:28 +02:00
posix_acl.c tmpfs: clear S_ISGID when setting posix ACLs 2017-01-26 08:23:47 +01:00
proc_namespace.c vfs: show_vfsstat: do not ignore errors from show_devname method 2016-04-12 09:08:55 -07:00
read_write.c fs: add the fsnotify call to vfs_iter_write 2019-02-06 19:43:06 +01:00
readdir.c
select.c fs/select: add vmalloc fallback for select(2) 2018-01-31 12:06:09 +01:00
seq_file.c Make file credentials available to the seqfile interfaces 2017-08-06 19:19:42 -07:00
signalfd.c
splice.c vfs: fix uninitialized flags in splice_to_pipe() 2017-02-23 17:43:09 +01:00
stack.c
stat.c ufs: restore maintaining ->i_blocks 2017-06-14 13:16:24 +02:00
statfs.c
super.c fs: don't scan the inode cache before SB_BORN is set 2019-02-06 19:43:08 +01:00
sync.c fs/sync.c: make sync_file_range(2) use WB_SYNC_NONE writeback 2015-11-06 17:50:42 -08:00
timerfd.c timerfd: Protect the might cancel mechanism proper 2017-05-08 07:46:01 +02:00
userfaultfd.c userfaultfd: shmem: __do_fault requires VM_FAULT_NOPAGE 2017-12-20 10:04:53 +01:00
utimes.c vfs: move permission checking into notify_change() for utimes(NULL) 2016-10-22 12:26:56 +02:00
xattr.c getxattr: use correct xattr length 2018-09-09 20:04:36 +02:00