Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKernel Build Daemon <kbuild@suse.de>2019-12-24 07:15:33 +0100
committerKernel Build Daemon <kbuild@suse.de>2019-12-24 07:15:33 +0100
commitdf84e26b2c431e68c1631f480074dc389fd30392 (patch)
tree53bd86bb46e02a07a36462499b73e00a8e2b5313
parente14fb2cb91fc5b7229ed8704ef125223b15f7d85 (diff)
parentf3e89f43545c9ec11be56b6c9f23d95642e5be10 (diff)
Merge branch 'SLE12-SP4' into SLE12-SP4-AZURESLE12-SP4-AZURE
-rw-r--r--patches.suse/0001-btrfs-harden-agaist-duplicate-fsid-on-scanned-device.patch112
-rw-r--r--patches.suse/0001-btrfs-volumes-Use-more-straightforward-way-to-calcul.patch48
-rw-r--r--patches.suse/0002-btrfs-Ensure-we-trim-ranges-across-block-group-bound.patch190
-rw-r--r--series.conf3
4 files changed, 353 insertions, 0 deletions
diff --git a/patches.suse/0001-btrfs-harden-agaist-duplicate-fsid-on-scanned-device.patch b/patches.suse/0001-btrfs-harden-agaist-duplicate-fsid-on-scanned-device.patch
new file mode 100644
index 0000000000..6dc19c2536
--- /dev/null
+++ b/patches.suse/0001-btrfs-harden-agaist-duplicate-fsid-on-scanned-device.patch
@@ -0,0 +1,112 @@
+From a9261d4125c97ce8624e9941b75dee1b43ad5df9 Mon Sep 17 00:00:00 2001
+Patch-mainline: v5.1
+References: bsc#1134973
+Git-commit: a9261d4125c97ce8624e9941b75dee1b43ad5df9
+From: Anand Jain <anand.jain@oracle.com>
+Date: Mon, 15 Oct 2018 10:45:17 +0800
+Subject: [PATCH] btrfs: harden agaist duplicate fsid on scanned devices
+
+It's not that impossible to imagine that a device OR a btrfs image is
+copied just by using the dd or the cp command. Which in case both the
+copies of the btrfs will have the same fsid. If on the system with
+automount enabled, the copied FS gets scanned.
+
+We have a known bug in btrfs, that we let the device path be changed
+after the device has been mounted. So using this loop hole the new
+copied device would appears as if its mounted immediately after it's
+been copied.
+
+For example:
+
+Initially.. /dev/mmcblk0p4 is mounted as /
+
+ $ lsblk
+ NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
+ mmcblk0 179:0 0 29.2G 0 disk
+ |-mmcblk0p4 179:4 0 4G 0 part /
+ |-mmcblk0p2 179:2 0 500M 0 part /boot
+ |-mmcblk0p3 179:3 0 256M 0 part [SWAP]
+ `-mmcblk0p1 179:1 0 256M 0 part /boot/efi
+
+ $ btrfs fi show
+ Label: none uuid: 07892354-ddaa-4443-90ea-f76a06accaba
+ Total devices 1 FS bytes used 1.40GiB
+ devid 1 size 4.00GiB used 3.00GiB path /dev/mmcblk0p4
+
+Copy mmcblk0 to sda
+
+ $ dd if=/dev/mmcblk0 of=/dev/sda
+
+And immediately after the copy completes the change in the device
+superblock is notified which the automount scans using btrfs device scan
+and the new device sda becomes the mounted root device.
+
+ $ lsblk
+ NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
+ sda 8:0 1 14.9G 0 disk
+ |-sda4 8:4 1 4G 0 part /
+ |-sda2 8:2 1 500M 0 part
+ |-sda3 8:3 1 256M 0 part
+ `-sda1 8:1 1 256M 0 part
+ mmcblk0 179:0 0 29.2G 0 disk
+ |-mmcblk0p4 179:4 0 4G 0 part
+ |-mmcblk0p2 179:2 0 500M 0 part /boot
+ |-mmcblk0p3 179:3 0 256M 0 part [SWAP]
+ `-mmcblk0p1 179:1 0 256M 0 part /boot/efi
+
+ $ btrfs fi show /
+ Label: none uuid: 07892354-ddaa-4443-90ea-f76a06accaba
+ Total devices 1 FS bytes used 1.40GiB
+ devid 1 size 4.00GiB used 3.00GiB path /dev/sda4
+
+The bug is quite nasty that you can't either unmount /dev/sda4 or
+/dev/mmcblk0p4. And the problem does not get solved until you take sda
+out of the system on to another system to change its fsid using the
+'btrfstune -u' command.
+
+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: Qu Wenruo <wqu@suse.com>
+---
+ fs/btrfs/volumes.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -641,6 +641,35 @@ static noinline int device_list_add(cons
+ return PTR_ERR(device);
+ }
+
++ /*
++ * We are going to replace the device path for a given devid,
++ * make sure it's the same device if the device is mounted
++ */
++ if (device->bdev) {
++ struct block_device *path_bdev;
++
++ path_bdev = lookup_bdev(path);
++ if (IS_ERR(path_bdev)) {
++ mutex_unlock(&fs_devices->device_list_mutex);
++ return PTR_ERR(path_bdev);
++ }
++
++ if (device->bdev != path_bdev) {
++ bdput(path_bdev);
++ mutex_unlock(&fs_devices->device_list_mutex);
++ btrfs_warn_in_rcu(device->fs_info,
++ "duplicate device fsid:devid for %pU:%llu old:%s new:%s",
++ disk_super->fsid, devid,
++ rcu_str_deref(device->name), path);
++ return -EEXIST;
++ }
++ bdput(path_bdev);
++ btrfs_info_in_rcu(device->fs_info,
++ "device fsid %pU devid %llu moved old:%s new:%s",
++ disk_super->fsid, devid,
++ rcu_str_deref(device->name), path);
++ }
++
+ name = rcu_string_strdup(path, GFP_NOFS);
+ if (!name) {
+ kfree(device);
diff --git a/patches.suse/0001-btrfs-volumes-Use-more-straightforward-way-to-calcul.patch b/patches.suse/0001-btrfs-volumes-Use-more-straightforward-way-to-calcul.patch
new file mode 100644
index 0000000000..587175b6da
--- /dev/null
+++ b/patches.suse/0001-btrfs-volumes-Use-more-straightforward-way-to-calcul.patch
@@ -0,0 +1,48 @@
+From 2d974619a77f106f3d1341686dea95c0eaad601f Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Wed, 23 Oct 2019 21:57:26 +0800
+Patch-mainline: v5.5-rc1
+Git-commit: 2d974619a77f106f3d1341686dea95c0eaad601f
+References: bsc#1151910
+Subject: [PATCH 1/2] btrfs: volumes: Use more straightforward way to calculate
+ map length
+
+The old code goes:
+
+ offset = logical - em->start;
+ length = min_t(u64, em->len - offset, length);
+
+Where @length calculation is dependent on offset, it can take reader
+several more seconds to find it's just the same code as:
+
+ offset = logical - em->start;
+ length = min_t(u64, em->start + em->len - logical, length);
+
+Use above code to make the length calculate independent from other
+variable, thus slightly increase the readability.
+
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+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>
+---
+ fs/btrfs/volumes.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index f534a6a5553e..6a0288d17b7d 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -5412,7 +5412,7 @@ static int __btrfs_map_block_for_discard(struct btrfs_fs_info *fs_info,
+ }
+
+ offset = logical - em->start;
+- length = min_t(u64, em->len - offset, length);
++ length = min_t(u64, em->start + em->len - logical, length);
+
+ stripe_len = map->stripe_len;
+ /*
+--
+2.24.1
+
diff --git a/patches.suse/0002-btrfs-Ensure-we-trim-ranges-across-block-group-bound.patch b/patches.suse/0002-btrfs-Ensure-we-trim-ranges-across-block-group-bound.patch
new file mode 100644
index 0000000000..92a33a9c89
--- /dev/null
+++ b/patches.suse/0002-btrfs-Ensure-we-trim-ranges-across-block-group-bound.patch
@@ -0,0 +1,190 @@
+From 6b7faadd985c990324b5b5bd18cc4ba5c395eb65 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Wed, 23 Oct 2019 21:57:27 +0800
+Patch-mainline: v5.5-rc1
+Git-commit: 6b7faadd985c990324b5b5bd18cc4ba5c395eb65
+References: bsc#1151910
+Subject: [PATCH 2/2] btrfs: Ensure we trim ranges across block group boundary
+
+[BUG]
+When deleting large files (which cross block group boundary) with
+discard mount option, we find some btrfs_discard_extent() calls only
+trimmed part of its space, not the whole range:
+
+ btrfs_discard_extent: type=0x1 start=19626196992 len=2144530432 trimmed=1073741824 ratio=50%
+
+type: bbio->map_type, in above case, it's SINGLE DATA.
+start: Logical address of this trim
+len: Logical length of this trim
+trimmed: Physically trimmed bytes
+ratio: trimmed / len
+
+Thus leaving some unused space not discarded.
+
+[CAUSE]
+When discard mount option is specified, after a transaction is fully
+committed (super block written to disk), we begin to cleanup pinned
+extents in the following call chain:
+
+btrfs_commit_transaction()
+|- btrfs_finish_extent_commit()
+ |- find_first_extent_bit(unpin, 0, &start, &end, EXTENT_DIRTY);
+ |- btrfs_discard_extent()
+
+However, pinned extents are recorded in an extent_io_tree, which can
+merge adjacent extent states.
+
+When a large file gets deleted and it has adjacent file extents across
+block group boundary, we will get a large merged range like this:
+
+ |<--- BG1 --->|<--- BG2 --->|
+ |//////|<-- Range to discard --->|/////|
+
+To discard that range, we have the following calls:
+
+ btrfs_discard_extent()
+ |- btrfs_map_block()
+ | Returned bbio will end at BG1's end. As btrfs_map_block()
+ | never returns result across block group boundary.
+ |- btrfs_issuse_discard()
+ Issue discard for each stripe.
+
+So we will only discard the range in BG1, not the remaining part in BG2.
+
+Furthermore, this bug is not that reliably observed, for above case, if
+there is no other extent in BG2, BG2 will be empty and btrfs will trim
+all space of BG2, covering up the bug.
+
+[FIX]
+- Allow __btrfs_map_block_for_discard() to modify @length parameter
+ btrfs_map_block() uses its @length paramter to notify the caller how
+ many bytes are mapped in current call.
+ With __btrfs_map_block_for_discard() also modifing the @length,
+ btrfs_discard_extent() now understands when to do extra trim.
+
+- Call btrfs_map_block() in a loop until we hit the range end Since we
+ now know how many bytes are mapped each time, we can iterate through
+ each block group boundary and issue correct trim for each range.
+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Tested-by: Nikolay Borisov <nborisov@suse.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/extent-tree.c | 41 +++++++++++++++++++++++++++++++----------
+ fs/btrfs/volumes.c | 6 ++++--
+ 2 files changed, 35 insertions(+), 12 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -2137,8 +2137,10 @@ static int btrfs_issue_discard(struct bl
+ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
+ u64 num_bytes, u64 *actual_bytes)
+ {
+- int ret;
++ int ret = 0;
+ u64 discarded_bytes = 0;
++ u64 end = bytenr + num_bytes;
++ u64 cur = bytenr;
+ struct btrfs_bio *bbio = NULL;
+
+
+@@ -2147,15 +2149,23 @@ int btrfs_discard_extent(struct btrfs_fs
+ * associated to its stripes that don't go away while we are discarding.
+ */
+ btrfs_bio_counter_inc_blocked(fs_info);
+- /* Tell the block device(s) that the sectors can be discarded */
+- ret = btrfs_map_block(fs_info, BTRFS_MAP_DISCARD, bytenr, &num_bytes,
+- &bbio, 0);
+- /* Error condition is -ENOMEM */
+- if (!ret) {
+- struct btrfs_bio_stripe *stripe = bbio->stripes;
++ while (cur < end) {
++ struct btrfs_bio_stripe *stripe;
+ int i;
+
++ num_bytes = end - cur;
++ /* Tell the block device(s) that the sectors can be discarded */
++ ret = btrfs_map_block(fs_info, BTRFS_MAP_DISCARD, cur,
++ &num_bytes, &bbio, 0);
++ /*
++ * Error can be -ENOMEM, -ENOENT (no such chunk mapping) or
++ * -EOPNOTSUPP. For any such error, @num_bytes is not updated,
++ * thus we can't continue anyway.
++ */
++ if (ret < 0)
++ goto out;
+
++ stripe = bbio->stripes;
+ for (i = 0; i < bbio->num_stripes; i++, stripe++) {
+ u64 bytes;
+ if (!stripe->dev->can_discard)
+@@ -2165,10 +2175,19 @@ int btrfs_discard_extent(struct btrfs_fs
+ stripe->physical,
+ stripe->length,
+ &bytes);
+- if (!ret)
++ if (!ret) {
+ discarded_bytes += bytes;
+- else if (ret != -EOPNOTSUPP)
+- break; /* Logic errors or -ENOMEM, or -EIO but I don't know how that could happen JDM */
++ } else if (ret != -EOPNOTSUPP) {
++ /*
++ * Logic errors or -ENOMEM, or -EIO, but
++ * unlikely to happen.
++ *
++ * And since there are two loops, explicitly
++ * go to out to avoid confusion.
++ */
++ btrfs_put_bbio(bbio);
++ goto out;
++ }
+
+ /*
+ * Just in case we get back EOPNOTSUPP for some reason,
+@@ -2178,7 +2197,9 @@ int btrfs_discard_extent(struct btrfs_fs
+ ret = 0;
+ }
+ btrfs_put_bbio(bbio);
++ cur += num_bytes;
+ }
++out:
+ btrfs_bio_counter_dec(fs_info);
+
+ if (actual_bytes)
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -5412,12 +5412,13 @@ void btrfs_put_bbio(struct btrfs_bio *bb
+ * replace.
+ */
+ static int __btrfs_map_block_for_discard(struct btrfs_fs_info *fs_info,
+- u64 logical, u64 length,
++ u64 logical, u64 *length_ret,
+ struct btrfs_bio **bbio_ret)
+ {
+ struct extent_map *em;
+ struct map_lookup *map;
+ struct btrfs_bio *bbio;
++ u64 length = *length_ret;
+ u64 offset;
+ u64 stripe_nr;
+ u64 stripe_nr_end;
+@@ -5451,6 +5452,7 @@ static int __btrfs_map_block_for_discard
+
+ offset = logical - em->start;
+ length = min_t(u64, em->start + em->len - logical, length);
++ *length_ret = length;
+
+ stripe_len = map->stripe_len;
+ /*
+@@ -5762,7 +5764,7 @@ static int __btrfs_map_block(struct btrf
+
+ if (op == BTRFS_MAP_DISCARD)
+ return __btrfs_map_block_for_discard(fs_info, logical,
+- *length, bbio_ret);
++ length, bbio_ret);
+
+ em = get_chunk_map(fs_info, logical, *length);
+ if (IS_ERR(em))
diff --git a/series.conf b/series.conf
index 9b3aa684d3..9ac5dbe645 100644
--- a/series.conf
+++ b/series.conf
@@ -21852,6 +21852,7 @@
patches.suse/crypto-mxc-scc-fix-build-warnings-on-ARM64.patch
patches.suse/gfs2-Get-rid-of-potential-double-freeing-in-gfs2_cre.patch
patches.suse/gfs2-Fix-loop-in-gfs2_rbm_find.patch
+ patches.suse/0001-btrfs-harden-agaist-duplicate-fsid-on-scanned-device.patch
patches.suse/0001-Btrfs-fix-fsync-of-files-with-multiple-hard-links-in.patch
patches.suse/btrfs-fix-error-handling-in-btrfs_cleanup_ordered_extents.patch
patches.suse/0003-btrfs-add-cleanup_ref_head_accounting-helper.patch
@@ -26009,6 +26010,8 @@
patches.suse/mtd-spear_smi-Fix-Write-Burst-mode.patch
patches.suse/mtd-spi-nor-fix-silent-truncation-in-spi_nor_read.patch
patches.suse/btrfs-simplify-inode-locking-for-RWF_NOWAIT.patch
+ patches.suse/0001-btrfs-volumes-Use-more-straightforward-way-to-calcul.patch
+ patches.suse/0002-btrfs-Ensure-we-trim-ranges-across-block-group-bound.patch
patches.suse/s390-mm-properly-clear-page_noexec-bit-when-it-is-not-supported
patches.suse/kvm-svm-serialize-access-to-the-sev-asid-bitmap.patch
patches.suse/kvm-svm-guard-against-deactivate-when-performing-wbinvd-df_flush.patch