android_kernel_samsung_a7y1.../fs
Josef Bacik 8e3cbb4ad9 btrfs: flush write bio if we loop in extent_write_cache_pages
[ Upstream commit 42ffb0bf584ae5b6b38f72259af1e0ee417ac77f ]

There exists a deadlock with range_cyclic that has existed forever.  If
we loop around with a bio already built we could deadlock with a writer
who has the page locked that we're attempting to write but is waiting on
a page in our bio to be written out.  The task traces are as follows

  PID: 1329874  TASK: ffff889ebcdf3800  CPU: 33  COMMAND: "kworker/u113:5"
   #0 [ffffc900297bb658] __schedule at ffffffff81a4c33f
   #1 [ffffc900297bb6e0] schedule at ffffffff81a4c6e3
   #2 [ffffc900297bb6f8] io_schedule at ffffffff81a4ca42
   #3 [ffffc900297bb708] __lock_page at ffffffff811f145b
   #4 [ffffc900297bb798] __process_pages_contig at ffffffff814bc502
   #5 [ffffc900297bb8c8] lock_delalloc_pages at ffffffff814bc684
   #6 [ffffc900297bb900] find_lock_delalloc_range at ffffffff814be9ff
   #7 [ffffc900297bb9a0] writepage_delalloc at ffffffff814bebd0
   #8 [ffffc900297bba18] __extent_writepage at ffffffff814bfbf2
   #9 [ffffc900297bba98] extent_write_cache_pages at ffffffff814bffbd

  PID: 2167901  TASK: ffff889dc6a59c00  CPU: 14  COMMAND:
  "aio-dio-invalid"
   #0 [ffffc9003b50bb18] __schedule at ffffffff81a4c33f
   #1 [ffffc9003b50bba0] schedule at ffffffff81a4c6e3
   #2 [ffffc9003b50bbb8] io_schedule at ffffffff81a4ca42
   #3 [ffffc9003b50bbc8] wait_on_page_bit at ffffffff811f24d6
   #4 [ffffc9003b50bc60] prepare_pages at ffffffff814b05a7
   #5 [ffffc9003b50bcd8] btrfs_buffered_write at ffffffff814b1359
   #6 [ffffc9003b50bdb0] btrfs_file_write_iter at ffffffff814b5933
   #7 [ffffc9003b50be38] new_sync_write at ffffffff8128f6a8
   #8 [ffffc9003b50bec8] vfs_write at ffffffff81292b9d
   #9 [ffffc9003b50bf00] ksys_pwrite64 at ffffffff81293032

I used drgn to find the respective pages we were stuck on

page_entry.page 0xffffea00fbfc7500 index 8148 bit 15 pid 2167901
page_entry.page 0xffffea00f9bb7400 index 7680 bit 0 pid 1329874

As you can see the kworker is waiting for bit 0 (PG_locked) on index
7680, and aio-dio-invalid is waiting for bit 15 (PG_writeback) on index
8148.  aio-dio-invalid has 7680, and the kworker epd looks like the
following

  crash> struct extent_page_data ffffc900297bbbb0
  struct extent_page_data {
    bio = 0xffff889f747ed830,
    tree = 0xffff889eed6ba448,
    extent_locked = 0,
    sync_io = 0
  }

Probably worth mentioning as well that it waits for writeback of the
page to complete while holding a lock on it (at prepare_pages()).

Using drgn I walked the bio pages looking for page
0xffffea00fbfc7500 which is the one we're waiting for writeback on

  bio = Object(prog, 'struct bio', address=0xffff889f747ed830)
  for i in range(0, bio.bi_vcnt.value_()):
      bv = bio.bi_io_vec[i]
      if bv.bv_page.value_() == 0xffffea00fbfc7500:
	  print("FOUND IT")

which validated what I suspected.

The fix for this is simple, flush the epd before we loop back around to
the beginning of the file during writeout.

Fixes: b293f02e1423 ("Btrfs: Add writepages support")
CC: stable@vger.kernel.org # 4.4+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-04-07 13:51:27 +02:00
..
9p 9p: avoid attaching writeback_fid on mmap with type PRIVATE 2020-04-07 08:07:58 +02:00
adfs fs/adfs: super: fix use-after-free bug 2020-04-06 20:26:54 +02:00
affs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
afs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
autofs4 autofs: fix a leak in autofs_expire_indirect() 2020-04-07 12:44:02 +02:00
befs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
bfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
btrfs btrfs: flush write bio if we loop in extent_write_cache_pages 2020-04-07 13:51:27 +02:00
cachefiles A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
ceph ceph: fix dentry leak in ceph_readdir_prepopulate 2020-04-07 12:35:17 +02:00
cifs signal: Allow cifs and drbd to receive their terminating signals 2020-04-07 13:42:54 +02:00
coda coda: add error handling for fget 2020-04-06 20:27:22 +02:00
configfs configfs: fix a deadlock in configfs_symlink() 2020-04-07 11:49:08 +02:00
cramfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
crypto A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
debugfs debugfs: fix use-after-free on symlink traversal 2020-04-06 16:42:15 +02:00
devpts A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
dlm dlm: fix invalid cluster name warning 2020-04-07 12:45:23 +02:00
ecryptfs ecryptfs_lookup_interpose(): lower_dentry->d_parent is not stable either 2020-04-07 12:26:27 +02:00
efivarfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
efs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
exofs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
exportfs exportfs: fix 'passing zero to ERR_PTR()' warning 2020-04-07 13:39:20 +02:00
ext2 ext2: Adjust indentation in ext2_fill_super 2020-04-07 13:50:47 +02:00
ext4 ext4: set error return correctly when ext4_htree_store_dirent fails 2020-04-07 13:42:46 +02:00
f2fs f2fs: fix to do sanity check on segment bitmap of LFS curseg 2020-04-07 07:36:58 +02:00
fat fat: work around race with userspace's read via blockdev while mounting 2020-04-07 07:53:48 +02:00
freevxfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
fscache A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
fuse fuse: verify attributes 2020-04-07 12:45:40 +02:00
gfs2 gfs2: take jdata unstuff into account in do_grow 2020-04-07 12:41:53 +02:00
hfs fs/hfs/extent.c: fix array out of bounds read of array extent 2020-04-07 12:35:57 +02:00
hfsplus hfsplus: fix return value of hfsplus_get_block() 2020-04-07 12:35:53 +02:00
hostfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
hpfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
hugetlbfs hugetlb: use same fault hash key for shared and private mappings 2020-04-06 18:15:12 +02:00
isofs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
jbd2 jbd2: Fix statistics for the number of logged blocks 2020-04-07 13:22:59 +02:00
jffs2 jffs2: fix use-after-free on symlink traversal 2020-04-06 16:42:13 +02:00
jfs jfs: fix bogus variable self-initialization 2020-04-07 13:41:05 +02:00
kernfs kernfs: Fix range checks in kernfs_get_target_path 2020-04-07 12:28:12 +02:00
lockd A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
logfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
minix A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
ncpfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
nfs NFS: Directory page cache pages need to be locked when read 2020-04-07 13:51:10 +02:00
nfs_common A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
nfsd nfsd: Return EPERM, not EACCES, in some SETATTR cases 2020-04-07 12:45:30 +02:00
nilfs2 A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
nls A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
notify A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
ntfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
ocfs2 ocfs2: call journal flush to mark journal as empty after journal recovery when mount 2020-04-07 13:37:23 +02:00
omfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
openpromfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
overlayfs Revert "ovl: modify ovl_permission() to do checks on two inodes" 2020-04-07 13:49:58 +02:00
proc mm/page_alloc.c: calculate 'available' memory in a separate function 2020-04-07 13:36:28 +02:00
pstore pstore/ram: Write new dumps to start of recycled zones 2020-04-07 13:25:10 +02:00
qnx4 A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
qnx6 A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
quota fs/quota: handle overflows of sysctl fs.quota.* and report as unsigned long 2020-04-07 13:23:11 +02:00
ramfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
reiserfs reiserfs: Fix memory leak of journal device string 2020-04-07 13:48:20 +02:00
romfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
sdcardfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
sdfat A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
squashfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
sysfs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
sysv A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
tracefs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
ubifs A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
udf udf: Fix incorrect final NOT_ALLOCATED (hole) extent length 2020-04-06 19:26:24 +02:00
ufs ufs: fix braino in ufs_get_inode_gid() for solaris UFS flavour 2020-04-06 18:14:41 +02:00
xfs xfs: Sanity check flags of Q_XQUOTARM call 2020-04-07 13:39:05 +02:00
aio.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
anon_inodes.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
attr.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
bad_inode.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
binfmt_aout.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
binfmt_elf_fdpic.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
binfmt_elf.c binfmt_elf: switch to new creds when switching to new mm 2020-04-06 14:52:46 +02:00
binfmt_em86.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
binfmt_flat.c fs/binfmt_flat.c: make load_flat_shared_library() work 2020-04-06 19:13:44 +02:00
binfmt_misc.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
binfmt_script.c exec: load_script: Do not exec truncated interpreter path 2020-04-07 09:27:31 +02:00
block_dev.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
buffer.c fs: fix guard_bio_eod to check for real EOD errors 2020-04-06 14:50:20 +02:00
char_dev.c chardev: Avoid potential use-after-free in 'chrdev_open()' 2020-04-07 13:29:29 +02:00
compat_binfmt_elf.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
compat_ioctl.c compat_ioctl: pppoe: fix PPPOEIOCSFWD handling 2020-04-06 20:28:29 +02:00
compat.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
coredump.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
dax.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
dcache.c fs/dcache: move security_d_instantiate() behind attaching dentry to inode 2020-04-07 09:57:56 +02:00
dcookies.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
direct-io.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
dlog_hook.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
drop_caches.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
eventfd.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
eventpoll.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
exec.c sched/fair: Don't free p->numa_faults with concurrent readers 2020-04-06 20:26:24 +02:00
fcntl.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
fhandle.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
file_table.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
file.c fs/file.c: initialize init_files.resize_wait 2020-04-06 14:49:46 +02:00
filesystems.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
fs_pin.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
fs_struct.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
fs-writeback.c cgroup,writeback: don't switch wbs immediately on dead wbs if the memcg is dead 2020-04-07 11:58:54 +02:00
inode.c Abort file_remove_privs() for non-reg. files 2020-04-06 19:09:43 +02:00
internal.h A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
ioctl.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
Kconfig A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
Kconfig.binfmt A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
libfs.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
locks.c locks: print unsigned ino in /proc/locks 2020-04-07 13:24:39 +02:00
Makefile A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
mbcache.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
mount.h A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
mpage.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
namei.c vfs: fix do_last() regression 2020-04-07 13:46:02 +02:00
namespace.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
no-block.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
nsfs.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
open.c access: avoid the RCU grace period for the temporary subjective credentials 2020-04-06 20:24:58 +02:00
pipe.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
pnode.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
pnode.h A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
posix_acl.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
proc_namespace.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
read_write.c fs: stream_open - opener for stream-like files so that read and write can run simultaneously without deadlock 2020-04-06 18:47:45 +02:00
readdir.c filldir[64]: remove WARN_ON_ONCE() for bad directory entries 2020-04-07 13:23:50 +02:00
select.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
seq_file.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
signalfd.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
splice.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
stack.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
stat.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
statfs.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
super.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
sync.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
timerfd.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
userfaultfd.c userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx 2020-04-06 21:09:04 +02:00
utimes.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
xattr.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30