]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Aug 2020 11:26:32 +0000 (13:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Aug 2020 11:26:32 +0000 (13:26 +0200)
added patches:
btrfs-don-t-allocate-anonymous-block-device-for-user-invisible-roots.patch
btrfs-don-t-traverse-into-the-seed-devices-in-show_devname.patch
btrfs-free-anon-block-device-right-after-subvolume-deletion.patch
btrfs-open-device-without-device_list_mutex.patch
btrfs-ref-verify-fix-memory-leak-in-add_block_entry.patch

queue-4.19/btrfs-don-t-allocate-anonymous-block-device-for-user-invisible-roots.patch [new file with mode: 0644]
queue-4.19/btrfs-don-t-traverse-into-the-seed-devices-in-show_devname.patch [new file with mode: 0644]
queue-4.19/btrfs-free-anon-block-device-right-after-subvolume-deletion.patch [new file with mode: 0644]
queue-4.19/btrfs-open-device-without-device_list_mutex.patch [new file with mode: 0644]
queue-4.19/btrfs-ref-verify-fix-memory-leak-in-add_block_entry.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/btrfs-don-t-allocate-anonymous-block-device-for-user-invisible-roots.patch b/queue-4.19/btrfs-don-t-allocate-anonymous-block-device-for-user-invisible-roots.patch
new file mode 100644 (file)
index 0000000..165b0f2
--- /dev/null
@@ -0,0 +1,90 @@
+From 851fd730a743e072badaf67caf39883e32439431 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 16 Jun 2020 10:17:34 +0800
+Subject: btrfs: don't allocate anonymous block device for user invisible roots
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 851fd730a743e072badaf67caf39883e32439431 upstream.
+
+[BUG]
+When a lot of subvolumes are created, there is a user report about
+transaction aborted:
+
+  BTRFS: Transaction aborted (error -24)
+  WARNING: CPU: 17 PID: 17041 at fs/btrfs/transaction.c:1576 create_pending_snapshot+0xbc4/0xd10 [btrfs]
+  RIP: 0010:create_pending_snapshot+0xbc4/0xd10 [btrfs]
+  Call Trace:
+   create_pending_snapshots+0x82/0xa0 [btrfs]
+   btrfs_commit_transaction+0x275/0x8c0 [btrfs]
+   btrfs_mksubvol+0x4b9/0x500 [btrfs]
+   btrfs_ioctl_snap_create_transid+0x174/0x180 [btrfs]
+   btrfs_ioctl_snap_create_v2+0x11c/0x180 [btrfs]
+   btrfs_ioctl+0x11a4/0x2da0 [btrfs]
+   do_vfs_ioctl+0xa9/0x640
+   ksys_ioctl+0x67/0x90
+   __x64_sys_ioctl+0x1a/0x20
+   do_syscall_64+0x5a/0x110
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+  ---[ end trace 33f2f83f3d5250e9 ]---
+  BTRFS: error (device sda1) in create_pending_snapshot:1576: errno=-24 unknown
+  BTRFS info (device sda1): forced readonly
+  BTRFS warning (device sda1): Skipping commit of aborted transaction.
+  BTRFS: error (device sda1) in cleanup_transaction:1831: errno=-24 unknown
+
+[CAUSE]
+The error is EMFILE (Too many files open) and comes from the anonymous
+block device allocation. The ids are in a shared pool of size 1<<20.
+
+The ids are assigned to live subvolumes, ie. the root structure exists
+in memory (eg. after creation or after the root appears in some path).
+The pool could be exhausted if the numbers are not reclaimed fast
+enough, after subvolume deletion or if other system component uses the
+anon block devices.
+
+[WORKAROUND]
+Since it's not possible to completely solve the problem, we can only
+minimize the time the id is allocated to a subvolume root.
+
+Firstly, we can reduce the use of anon_dev by trees that are not
+subvolume roots, like data reloc tree.
+
+This patch will do extra check on root objectid, to skip roots that
+don't need anon_dev.  Currently it's only data reloc tree and orphan
+roots.
+
+Reported-by: Greed Rong <greedrong@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/CA+UqX+NTrZ6boGnWHhSeZmEY5J76CTqmYjO2S+=tHJX7nb9DPw@mail.gmail.com/
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Qu Wenruo <wqu@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>
+
+---
+ fs/btrfs/disk-io.c |   13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1500,9 +1500,16 @@ int btrfs_init_fs_root(struct btrfs_root
+       spin_lock_init(&root->ino_cache_lock);
+       init_waitqueue_head(&root->ino_cache_wait);
+-      ret = get_anon_bdev(&root->anon_dev);
+-      if (ret)
+-              goto fail;
++      /*
++       * Don't assign anonymous block device to roots that are not exposed to
++       * userspace, the id pool is limited to 1M
++       */
++      if (is_fstree(root->root_key.objectid) &&
++          btrfs_root_refs(&root->root_item) > 0) {
++              ret = get_anon_bdev(&root->anon_dev);
++              if (ret)
++                      goto fail;
++      }
+       mutex_lock(&root->objectid_mutex);
+       ret = btrfs_find_highest_objectid(root,
diff --git a/queue-4.19/btrfs-don-t-traverse-into-the-seed-devices-in-show_devname.patch b/queue-4.19/btrfs-don-t-traverse-into-the-seed-devices-in-show_devname.patch
new file mode 100644 (file)
index 0000000..52f9842
--- /dev/null
@@ -0,0 +1,123 @@
+From 4faf55b03823e96c44dc4e364520000ed3b12fdb Mon Sep 17 00:00:00 2001
+From: Anand Jain <anand.jain@oracle.com>
+Date: Fri, 10 Jul 2020 14:37:38 +0800
+Subject: btrfs: don't traverse into the seed devices in show_devname
+
+From: Anand Jain <anand.jain@oracle.com>
+
+commit 4faf55b03823e96c44dc4e364520000ed3b12fdb upstream.
+
+->show_devname currently shows the lowest devid in the list. As the seed
+devices have the lowest devid in the sprouted filesystem, the userland
+tool such as findmnt end up seeing seed device instead of the device from
+the read-writable sprouted filesystem. As shown below.
+
+ mount /dev/sda /btrfs
+ mount: /btrfs: WARNING: device write-protected, mounted read-only.
+
+ findmnt --output SOURCE,TARGET,UUID /btrfs
+ SOURCE   TARGET UUID
+ /dev/sda /btrfs 899f7027-3e46-4626-93e7-7d4c9ad19111
+
+ btrfs dev add -f /dev/sdb /btrfs
+
+ umount /btrfs
+ mount /dev/sdb /btrfs
+
+ findmnt --output SOURCE,TARGET,UUID /btrfs
+ SOURCE   TARGET UUID
+ /dev/sda /btrfs 899f7027-3e46-4626-93e7-7d4c9ad19111
+
+All sprouts from a single seed will show the same seed device and the
+same fsid. That's confusing.
+This is causing problems in our prototype as there isn't any reference
+to the sprout file-system(s) which is being used for actual read and
+write.
+
+This was added in the patch which implemented the show_devname in btrfs
+commit 9c5085c14798 ("Btrfs: implement ->show_devname").
+I tried to look for any particular reason that we need to show the seed
+device, there isn't any.
+
+So instead, do not traverse through the seed devices, just show the
+lowest devid in the sprouted fsid.
+
+After the patch:
+
+ mount /dev/sda /btrfs
+ mount: /btrfs: WARNING: device write-protected, mounted read-only.
+
+ findmnt --output SOURCE,TARGET,UUID /btrfs
+ SOURCE   TARGET UUID
+ /dev/sda /btrfs 899f7027-3e46-4626-93e7-7d4c9ad19111
+
+ btrfs dev add -f /dev/sdb /btrfs
+ mount -o rw,remount /dev/sdb /btrfs
+
+ findmnt --output SOURCE,TARGET,UUID /btrfs
+ SOURCE   TARGET UUID
+ /dev/sdb /btrfs 595ca0e6-b82e-46b5-b9e2-c72a6928be48
+
+ mount /dev/sda /btrfs1
+ mount: /btrfs1: WARNING: device write-protected, mounted read-only.
+
+ btrfs dev add -f /dev/sdc /btrfs1
+
+ findmnt --output SOURCE,TARGET,UUID /btrfs1
+ SOURCE   TARGET  UUID
+ /dev/sdc /btrfs1 ca1dbb7a-8446-4f95-853c-a20f3f82bdbb
+
+ cat /proc/self/mounts | grep btrfs
+ /dev/sdb /btrfs btrfs rw,relatime,noacl,space_cache,subvolid=5,subvol=/ 0 0
+ /dev/sdc /btrfs1 btrfs ro,relatime,noacl,space_cache,subvolid=5,subvol=/ 0 0
+
+Reported-by: Martin K. Petersen <martin.petersen@oracle.com>
+CC: stable@vger.kernel.org # 4.19+
+Tested-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Anand Jain <anand.jain@oracle.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>
+
+---
+ fs/btrfs/super.c |   21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2314,9 +2314,7 @@ static int btrfs_unfreeze(struct super_b
+ static int btrfs_show_devname(struct seq_file *m, struct dentry *root)
+ {
+       struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb);
+-      struct btrfs_fs_devices *cur_devices;
+       struct btrfs_device *dev, *first_dev = NULL;
+-      struct list_head *head;
+       /*
+        * Lightweight locking of the devices. We should not need
+@@ -2326,18 +2324,13 @@ static int btrfs_show_devname(struct seq
+        * least until until the rcu_read_unlock.
+        */
+       rcu_read_lock();
+-      cur_devices = fs_info->fs_devices;
+-      while (cur_devices) {
+-              head = &cur_devices->devices;
+-              list_for_each_entry_rcu(dev, head, dev_list) {
+-                      if (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state))
+-                              continue;
+-                      if (!dev->name)
+-                              continue;
+-                      if (!first_dev || dev->devid < first_dev->devid)
+-                              first_dev = dev;
+-              }
+-              cur_devices = cur_devices->seed;
++      list_for_each_entry_rcu(dev, &fs_info->fs_devices->devices, dev_list) {
++              if (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state))
++                      continue;
++              if (!dev->name)
++                      continue;
++              if (!first_dev || dev->devid < first_dev->devid)
++                      first_dev = dev;
+       }
+       if (first_dev)
diff --git a/queue-4.19/btrfs-free-anon-block-device-right-after-subvolume-deletion.patch b/queue-4.19/btrfs-free-anon-block-device-right-after-subvolume-deletion.patch
new file mode 100644 (file)
index 0000000..ddd5956
--- /dev/null
@@ -0,0 +1,68 @@
+From 082b6c970f02fefd278c7833880cda29691a5f34 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 16 Jun 2020 10:17:37 +0800
+Subject: btrfs: free anon block device right after subvolume deletion
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 082b6c970f02fefd278c7833880cda29691a5f34 upstream.
+
+[BUG]
+When a lot of subvolumes are created, there is a user report about
+transaction aborted caused by slow anonymous block device reclaim:
+
+  BTRFS: Transaction aborted (error -24)
+  WARNING: CPU: 17 PID: 17041 at fs/btrfs/transaction.c:1576 create_pending_snapshot+0xbc4/0xd10 [btrfs]
+  RIP: 0010:create_pending_snapshot+0xbc4/0xd10 [btrfs]
+  Call Trace:
+   create_pending_snapshots+0x82/0xa0 [btrfs]
+   btrfs_commit_transaction+0x275/0x8c0 [btrfs]
+   btrfs_mksubvol+0x4b9/0x500 [btrfs]
+   btrfs_ioctl_snap_create_transid+0x174/0x180 [btrfs]
+   btrfs_ioctl_snap_create_v2+0x11c/0x180 [btrfs]
+   btrfs_ioctl+0x11a4/0x2da0 [btrfs]
+   do_vfs_ioctl+0xa9/0x640
+   ksys_ioctl+0x67/0x90
+   __x64_sys_ioctl+0x1a/0x20
+   do_syscall_64+0x5a/0x110
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+  ---[ end trace 33f2f83f3d5250e9 ]---
+  BTRFS: error (device sda1) in create_pending_snapshot:1576: errno=-24 unknown
+  BTRFS info (device sda1): forced readonly
+  BTRFS warning (device sda1): Skipping commit of aborted transaction.
+  BTRFS: error (device sda1) in cleanup_transaction:1831: errno=-24 unknown
+
+[CAUSE]
+The anonymous device pool is shared and its size is 1M. It's possible to
+hit that limit if the subvolume deletion is not fast enough and the
+subvolumes to be cleaned keep the ids allocated.
+
+[WORKAROUND]
+We can't avoid the anon device pool exhaustion but we can shorten the
+time the id is attached to the subvolume root once the subvolume becomes
+invisible to the user.
+
+Reported-by: Greed Rong <greedrong@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/CA+UqX+NTrZ6boGnWHhSeZmEY5J76CTqmYjO2S+=tHJX7nb9DPw@mail.gmail.com/
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Qu Wenruo <wqu@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>
+
+---
+ fs/btrfs/inode.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4458,6 +4458,8 @@ int btrfs_delete_subvolume(struct inode
+               }
+       }
++      free_anon_bdev(dest->anon_dev);
++      dest->anon_dev = 0;
+ out_end_trans:
+       trans->block_rsv = NULL;
+       trans->bytes_reserved = 0;
diff --git a/queue-4.19/btrfs-open-device-without-device_list_mutex.patch b/queue-4.19/btrfs-open-device-without-device_list_mutex.patch
new file mode 100644 (file)
index 0000000..01bec9c
--- /dev/null
@@ -0,0 +1,253 @@
+From 18c850fdc5a801bad4977b0f1723761d42267e45 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Fri, 17 Jul 2020 15:12:27 -0400
+Subject: btrfs: open device without device_list_mutex
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 18c850fdc5a801bad4977b0f1723761d42267e45 upstream.
+
+There's long existed a lockdep splat because we open our bdev's under
+the ->device_list_mutex at mount time, which acquires the bd_mutex.
+Usually this goes unnoticed, but if you do loopback devices at all
+suddenly the bd_mutex comes with a whole host of other dependencies,
+which results in the splat when you mount a btrfs file system.
+
+======================================================
+WARNING: possible circular locking dependency detected
+5.8.0-0.rc3.1.fc33.x86_64+debug #1 Not tainted
+------------------------------------------------------
+systemd-journal/509 is trying to acquire lock:
+ffff970831f84db0 (&fs_info->reloc_mutex){+.+.}-{3:3}, at: btrfs_record_root_in_trans+0x44/0x70 [btrfs]
+
+but task is already holding lock:
+ffff97083144d598 (sb_pagefaults){.+.+}-{0:0}, at: btrfs_page_mkwrite+0x59/0x560 [btrfs]
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+ -> #6 (sb_pagefaults){.+.+}-{0:0}:
+       __sb_start_write+0x13e/0x220
+       btrfs_page_mkwrite+0x59/0x560 [btrfs]
+       do_page_mkwrite+0x4f/0x130
+       do_wp_page+0x3b0/0x4f0
+       handle_mm_fault+0xf47/0x1850
+       do_user_addr_fault+0x1fc/0x4b0
+       exc_page_fault+0x88/0x300
+       asm_exc_page_fault+0x1e/0x30
+
+ -> #5 (&mm->mmap_lock#2){++++}-{3:3}:
+       __might_fault+0x60/0x80
+       _copy_from_user+0x20/0xb0
+       get_sg_io_hdr+0x9a/0xb0
+       scsi_cmd_ioctl+0x1ea/0x2f0
+       cdrom_ioctl+0x3c/0x12b4
+       sr_block_ioctl+0xa4/0xd0
+       block_ioctl+0x3f/0x50
+       ksys_ioctl+0x82/0xc0
+       __x64_sys_ioctl+0x16/0x20
+       do_syscall_64+0x52/0xb0
+       entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #4 (&cd->lock){+.+.}-{3:3}:
+       __mutex_lock+0x7b/0x820
+       sr_block_open+0xa2/0x180
+       __blkdev_get+0xdd/0x550
+       blkdev_get+0x38/0x150
+       do_dentry_open+0x16b/0x3e0
+       path_openat+0x3c9/0xa00
+       do_filp_open+0x75/0x100
+       do_sys_openat2+0x8a/0x140
+       __x64_sys_openat+0x46/0x70
+       do_syscall_64+0x52/0xb0
+       entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #3 (&bdev->bd_mutex){+.+.}-{3:3}:
+       __mutex_lock+0x7b/0x820
+       __blkdev_get+0x6a/0x550
+       blkdev_get+0x85/0x150
+       blkdev_get_by_path+0x2c/0x70
+       btrfs_get_bdev_and_sb+0x1b/0xb0 [btrfs]
+       open_fs_devices+0x88/0x240 [btrfs]
+       btrfs_open_devices+0x92/0xa0 [btrfs]
+       btrfs_mount_root+0x250/0x490 [btrfs]
+       legacy_get_tree+0x30/0x50
+       vfs_get_tree+0x28/0xc0
+       vfs_kern_mount.part.0+0x71/0xb0
+       btrfs_mount+0x119/0x380 [btrfs]
+       legacy_get_tree+0x30/0x50
+       vfs_get_tree+0x28/0xc0
+       do_mount+0x8c6/0xca0
+       __x64_sys_mount+0x8e/0xd0
+       do_syscall_64+0x52/0xb0
+       entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #2 (&fs_devs->device_list_mutex){+.+.}-{3:3}:
+       __mutex_lock+0x7b/0x820
+       btrfs_run_dev_stats+0x36/0x420 [btrfs]
+       commit_cowonly_roots+0x91/0x2d0 [btrfs]
+       btrfs_commit_transaction+0x4e6/0x9f0 [btrfs]
+       btrfs_sync_file+0x38a/0x480 [btrfs]
+       __x64_sys_fdatasync+0x47/0x80
+       do_syscall_64+0x52/0xb0
+       entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #1 (&fs_info->tree_log_mutex){+.+.}-{3:3}:
+       __mutex_lock+0x7b/0x820
+       btrfs_commit_transaction+0x48e/0x9f0 [btrfs]
+       btrfs_sync_file+0x38a/0x480 [btrfs]
+       __x64_sys_fdatasync+0x47/0x80
+       do_syscall_64+0x52/0xb0
+       entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #0 (&fs_info->reloc_mutex){+.+.}-{3:3}:
+       __lock_acquire+0x1241/0x20c0
+       lock_acquire+0xb0/0x400
+       __mutex_lock+0x7b/0x820
+       btrfs_record_root_in_trans+0x44/0x70 [btrfs]
+       start_transaction+0xd2/0x500 [btrfs]
+       btrfs_dirty_inode+0x44/0xd0 [btrfs]
+       file_update_time+0xc6/0x120
+       btrfs_page_mkwrite+0xda/0x560 [btrfs]
+       do_page_mkwrite+0x4f/0x130
+       do_wp_page+0x3b0/0x4f0
+       handle_mm_fault+0xf47/0x1850
+       do_user_addr_fault+0x1fc/0x4b0
+       exc_page_fault+0x88/0x300
+       asm_exc_page_fault+0x1e/0x30
+
+other info that might help us debug this:
+
+Chain exists of:
+  &fs_info->reloc_mutex --> &mm->mmap_lock#2 --> sb_pagefaults
+
+Possible unsafe locking scenario:
+
+     CPU0                    CPU1
+     ----                    ----
+ lock(sb_pagefaults);
+                             lock(&mm->mmap_lock#2);
+                             lock(sb_pagefaults);
+ lock(&fs_info->reloc_mutex);
+
+ *** DEADLOCK ***
+
+3 locks held by systemd-journal/509:
+ #0: ffff97083bdec8b8 (&mm->mmap_lock#2){++++}-{3:3}, at: do_user_addr_fault+0x12e/0x4b0
+ #1: ffff97083144d598 (sb_pagefaults){.+.+}-{0:0}, at: btrfs_page_mkwrite+0x59/0x560 [btrfs]
+ #2: ffff97083144d6a8 (sb_internal){.+.+}-{0:0}, at: start_transaction+0x3f8/0x500 [btrfs]
+
+stack backtrace:
+CPU: 0 PID: 509 Comm: systemd-journal Not tainted 5.8.0-0.rc3.1.fc33.x86_64+debug #1
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+Call Trace:
+ dump_stack+0x92/0xc8
+ check_noncircular+0x134/0x150
+ __lock_acquire+0x1241/0x20c0
+ lock_acquire+0xb0/0x400
+ ? btrfs_record_root_in_trans+0x44/0x70 [btrfs]
+ ? lock_acquire+0xb0/0x400
+ ? btrfs_record_root_in_trans+0x44/0x70 [btrfs]
+ __mutex_lock+0x7b/0x820
+ ? btrfs_record_root_in_trans+0x44/0x70 [btrfs]
+ ? kvm_sched_clock_read+0x14/0x30
+ ? sched_clock+0x5/0x10
+ ? sched_clock_cpu+0xc/0xb0
+ btrfs_record_root_in_trans+0x44/0x70 [btrfs]
+ start_transaction+0xd2/0x500 [btrfs]
+ btrfs_dirty_inode+0x44/0xd0 [btrfs]
+ file_update_time+0xc6/0x120
+ btrfs_page_mkwrite+0xda/0x560 [btrfs]
+ ? sched_clock+0x5/0x10
+ do_page_mkwrite+0x4f/0x130
+ do_wp_page+0x3b0/0x4f0
+ handle_mm_fault+0xf47/0x1850
+ do_user_addr_fault+0x1fc/0x4b0
+ exc_page_fault+0x88/0x300
+ ? asm_exc_page_fault+0x8/0x30
+ asm_exc_page_fault+0x1e/0x30
+RIP: 0033:0x7fa3972fdbfe
+Code: Bad RIP value.
+
+Fix this by not holding the ->device_list_mutex at this point.  The
+device_list_mutex exists to protect us from modifying the device list
+while the file system is running.
+
+However it can also be modified by doing a scan on a device.  But this
+action is specifically protected by the uuid_mutex, which we are holding
+here.  We cannot race with opening at this point because we have the
+->s_mount lock held during the mount.  Not having the
+->device_list_mutex here is perfectly safe as we're not going to change
+the devices at this point.
+
+CC: stable@vger.kernel.org # 4.19+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+[ add some comments ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c |   21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -155,7 +155,9 @@ static int __btrfs_map_block(struct btrf
+  *
+  * global::fs_devs - add, remove, updates to the global list
+  *
+- * does not protect: manipulation of the fs_devices::devices list!
++ * does not protect: manipulation of the fs_devices::devices list in general
++ * but in mount context it could be used to exclude list modifications by eg.
++ * scan ioctl
+  *
+  * btrfs_device::name - renames (write side), read is RCU
+  *
+@@ -168,6 +170,9 @@ static int __btrfs_map_block(struct btrf
+  * may be used to exclude some operations from running concurrently without any
+  * modifications to the list (see write_all_supers)
+  *
++ * Is not required at mount and close times, because our device list is
++ * protected by the uuid_mutex at that point.
++ *
+  * balance_mutex
+  * -------------
+  * protects balance structures (status, state) and context accessed from
+@@ -656,6 +661,11 @@ static void btrfs_free_stale_devices(con
+       }
+ }
++/*
++ * This is only used on mount, and we are protected from competing things
++ * messing with our fs_devices by the uuid_mutex, thus we do not need the
++ * fs_devices->device_list_mutex here.
++ */
+ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
+                       struct btrfs_device *device, fmode_t flags,
+                       void *holder)
+@@ -1153,8 +1163,14 @@ int btrfs_open_devices(struct btrfs_fs_d
+       int ret;
+       lockdep_assert_held(&uuid_mutex);
++      /*
++       * The device_list_mutex cannot be taken here in case opening the
++       * underlying device takes further locks like bd_mutex.
++       *
++       * We also don't need the lock here as this is called during mount and
++       * exclusion is provided by uuid_mutex
++       */
+-      mutex_lock(&fs_devices->device_list_mutex);
+       if (fs_devices->opened) {
+               fs_devices->opened++;
+               ret = 0;
+@@ -1162,7 +1178,6 @@ int btrfs_open_devices(struct btrfs_fs_d
+               list_sort(NULL, &fs_devices->devices, devid_cmp);
+               ret = open_fs_devices(fs_devices, flags, holder);
+       }
+-      mutex_unlock(&fs_devices->device_list_mutex);
+       return ret;
+ }
diff --git a/queue-4.19/btrfs-ref-verify-fix-memory-leak-in-add_block_entry.patch b/queue-4.19/btrfs-ref-verify-fix-memory-leak-in-add_block_entry.patch
new file mode 100644 (file)
index 0000000..a4f0716
--- /dev/null
@@ -0,0 +1,50 @@
+From d60ba8de1164e1b42e296ff270c622a070ef8fe7 Mon Sep 17 00:00:00 2001
+From: Tom Rix <trix@redhat.com>
+Date: Tue, 7 Jul 2020 06:29:08 -0700
+Subject: btrfs: ref-verify: fix memory leak in add_block_entry
+
+From: Tom Rix <trix@redhat.com>
+
+commit d60ba8de1164e1b42e296ff270c622a070ef8fe7 upstream.
+
+clang static analysis flags this error
+
+fs/btrfs/ref-verify.c:290:3: warning: Potential leak of memory pointed to by 're' [unix.Malloc]
+                kfree(be);
+                ^~~~~
+
+The problem is in this block of code:
+
+       if (root_objectid) {
+               struct root_entry *exist_re;
+
+               exist_re = insert_root_entry(&exist->roots, re);
+               if (exist_re)
+                       kfree(re);
+       }
+
+There is no 'else' block freeing when root_objectid is 0. Add the
+missing kfree to the else branch.
+
+Fixes: fd708b81d972 ("Btrfs: add a extent ref verify tool")
+CC: stable@vger.kernel.org # 4.19+
+Signed-off-by: Tom Rix <trix@redhat.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>
+
+---
+ fs/btrfs/ref-verify.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/ref-verify.c
++++ b/fs/btrfs/ref-verify.c
+@@ -297,6 +297,8 @@ static struct block_entry *add_block_ent
+                       exist_re = insert_root_entry(&exist->roots, re);
+                       if (exist_re)
+                               kfree(re);
++              } else {
++                      kfree(re);
+               }
+               kfree(be);
+               return exist;
index 688368742c29f21f285eb7b92715bac6c2e6331b..0ad98c2b3d006e45e99a8a6fdd2a510becbcad1b 100644 (file)
@@ -6,3 +6,8 @@ pci-add-device-even-if-driver-attach-failed.patch
 pci-qcom-define-some-parf-params-needed-for-ipq8064-soc.patch
 pci-qcom-add-support-for-tx-term-offset-for-rev-2.1.0.patch
 pci-probe-bridge-window-attributes-once-at-enumeration-time.patch
+btrfs-free-anon-block-device-right-after-subvolume-deletion.patch
+btrfs-don-t-allocate-anonymous-block-device-for-user-invisible-roots.patch
+btrfs-ref-verify-fix-memory-leak-in-add_block_entry.patch
+btrfs-don-t-traverse-into-the-seed-devices-in-show_devname.patch
+btrfs-open-device-without-device_list_mutex.patch