From: Greg Kroah-Hartman Date: Fri, 9 Oct 2020 14:11:45 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.4.239~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=58506abf734e7cf79a53d11f46236eadd8af1ad0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: arm64-dts-stratix10-add-status-to-qspi-dts-node.patch btrfs-allow-btrfs_truncate_block-to-fallback-to-nocow-for-data-space-reservation.patch btrfs-ensure-we-trim-ranges-across-block-group-boundary.patch btrfs-fix-rwf_nowait-write-not-failling-when-we-need-to-cow.patch btrfs-send-allow-clone-operations-within-the-same-file.patch btrfs-send-fix-emission-of-invalid-clone-operations-within-the-same-file.patch btrfs-volumes-use-more-straightforward-way-to-calculate-map-length.patch i2c-i801-exclude-device-from-suspend-direct-complete-optimization.patch perf-test-session-topology-fix-data-path.patch perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch --- diff --git a/queue-5.4/arm64-dts-stratix10-add-status-to-qspi-dts-node.patch b/queue-5.4/arm64-dts-stratix10-add-status-to-qspi-dts-node.patch new file mode 100644 index 00000000000..16d33ec20ce --- /dev/null +++ b/queue-5.4/arm64-dts-stratix10-add-status-to-qspi-dts-node.patch @@ -0,0 +1,31 @@ +From 263a0269a59c0b4145829462a107fe7f7327105f Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen +Date: Mon, 29 Jun 2020 11:25:43 -0500 +Subject: arm64: dts: stratix10: add status to qspi dts node + +From: Dinh Nguyen + +commit 263a0269a59c0b4145829462a107fe7f7327105f upstream. + +Add status = "okay" to QSPI node. + +Fixes: 0cb140d07fc75 ("arm64: dts: stratix10: Add QSPI support for Stratix10") +Cc: linux-stable # >= v5.6 +Signed-off-by: Dinh Nguyen +[iwamatsu: Drop arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts] +Signed-off-by: Nobuhiro Iwamatsu +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts ++++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +@@ -155,6 +155,7 @@ + }; + + &qspi { ++ status = "okay"; + flash@0 { + #address-cells = <1>; + #size-cells = <1>; diff --git a/queue-5.4/btrfs-allow-btrfs_truncate_block-to-fallback-to-nocow-for-data-space-reservation.patch b/queue-5.4/btrfs-allow-btrfs_truncate_block-to-fallback-to-nocow-for-data-space-reservation.patch new file mode 100644 index 00000000000..2be8aee9447 --- /dev/null +++ b/queue-5.4/btrfs-allow-btrfs_truncate_block-to-fallback-to-nocow-for-data-space-reservation.patch @@ -0,0 +1,189 @@ +From 6d4572a9d71d5fc2affee0258d8582d39859188c Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Wed, 24 Jun 2020 07:23:50 +0800 +Subject: btrfs: allow btrfs_truncate_block() to fallback to nocow for data space reservation + +From: Qu Wenruo + +commit 6d4572a9d71d5fc2affee0258d8582d39859188c upstream. + +[BUG] +When the data space is exhausted, even if the inode has NOCOW attribute, +we will still refuse to truncate unaligned range due to ENOSPC. + +The following script can reproduce it pretty easily: + #!/bin/bash + + dev=/dev/test/test + mnt=/mnt/btrfs + + umount $dev &> /dev/null + umount $mnt &> /dev/null + + mkfs.btrfs -f $dev -b 1G + mount -o nospace_cache $dev $mnt + touch $mnt/foobar + chattr +C $mnt/foobar + + xfs_io -f -c "pwrite -b 4k 0 4k" $mnt/foobar > /dev/null + xfs_io -f -c "pwrite -b 4k 0 1G" $mnt/padding &> /dev/null + sync + + xfs_io -c "fpunch 0 2k" $mnt/foobar + umount $mnt + +Currently this will fail at the fpunch part. + +[CAUSE] +Because btrfs_truncate_block() always reserves space without checking +the NOCOW attribute. + +Since the writeback path follows NOCOW bit, we only need to bother the +space reservation code in btrfs_truncate_block(). + +[FIX] +Make btrfs_truncate_block() follow btrfs_buffered_write() to try to +reserve data space first, and fall back to NOCOW check only when we +don't have enough space. + +Such always-try-reserve is an optimization introduced in +btrfs_buffered_write(), to avoid expensive btrfs_check_can_nocow() call. + +This patch will export check_can_nocow() as btrfs_check_can_nocow(), and +use it in btrfs_truncate_block() to fix the problem. + +Reported-by: Martin Doucha +Reviewed-by: Filipe Manana +Reviewed-by: Anand Jain +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/ctree.h | 2 ++ + fs/btrfs/file.c | 9 +++++---- + fs/btrfs/inode.c | 44 +++++++++++++++++++++++++++++++++++++------- + 3 files changed, 44 insertions(+), 11 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -2956,6 +2956,8 @@ int btrfs_fdatawrite_range(struct inode + loff_t btrfs_remap_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + loff_t len, unsigned int remap_flags); ++int btrfs_check_can_nocow(struct btrfs_inode *inode, loff_t pos, ++ size_t *write_bytes); + + /* tree-defrag.c */ + int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1546,8 +1546,8 @@ lock_and_cleanup_extent_if_need(struct b + return ret; + } + +-static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, +- size_t *write_bytes) ++int btrfs_check_can_nocow(struct btrfs_inode *inode, loff_t pos, ++ size_t *write_bytes) + { + struct btrfs_fs_info *fs_info = inode->root->fs_info; + struct btrfs_root *root = inode->root; +@@ -1647,7 +1647,7 @@ static noinline ssize_t btrfs_buffered_w + if (ret < 0) { + if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | + BTRFS_INODE_PREALLOC)) && +- check_can_nocow(BTRFS_I(inode), pos, ++ btrfs_check_can_nocow(BTRFS_I(inode), pos, + &write_bytes) > 0) { + /* + * For nodata cow case, no need to reserve +@@ -1927,7 +1927,8 @@ static ssize_t btrfs_file_write_iter(str + */ + if (!(BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | + BTRFS_INODE_PREALLOC)) || +- check_can_nocow(BTRFS_I(inode), pos, &nocow_bytes) <= 0) { ++ btrfs_check_can_nocow(BTRFS_I(inode), pos, ++ &nocow_bytes) <= 0) { + inode_unlock(inode); + return -EAGAIN; + } +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -5133,11 +5133,13 @@ int btrfs_truncate_block(struct inode *i + struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; + char *kaddr; ++ bool only_release_metadata = false; + u32 blocksize = fs_info->sectorsize; + pgoff_t index = from >> PAGE_SHIFT; + unsigned offset = from & (blocksize - 1); + struct page *page; + gfp_t mask = btrfs_alloc_write_mask(mapping); ++ size_t write_bytes = blocksize; + int ret = 0; + u64 block_start; + u64 block_end; +@@ -5149,11 +5151,27 @@ int btrfs_truncate_block(struct inode *i + block_start = round_down(from, blocksize); + block_end = block_start + blocksize - 1; + +- ret = btrfs_delalloc_reserve_space(inode, &data_reserved, +- block_start, blocksize); +- if (ret) +- goto out; + ++ ret = btrfs_check_data_free_space(inode, &data_reserved, block_start, ++ blocksize); ++ if (ret < 0) { ++ if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | ++ BTRFS_INODE_PREALLOC)) && ++ btrfs_check_can_nocow(BTRFS_I(inode), block_start, ++ &write_bytes) > 0) { ++ /* For nocow case, no need to reserve data space */ ++ only_release_metadata = true; ++ } else { ++ goto out; ++ } ++ } ++ ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), blocksize); ++ if (ret < 0) { ++ if (!only_release_metadata) ++ btrfs_free_reserved_data_space(inode, data_reserved, ++ block_start, blocksize); ++ goto out; ++ } + again: + page = find_or_create_page(mapping, index, mask); + if (!page) { +@@ -5222,14 +5240,26 @@ again: + set_page_dirty(page); + unlock_extent_cached(io_tree, block_start, block_end, &cached_state); + ++ if (only_release_metadata) ++ set_extent_bit(&BTRFS_I(inode)->io_tree, block_start, ++ block_end, EXTENT_NORESERVE, NULL, NULL, ++ GFP_NOFS); ++ + out_unlock: +- if (ret) +- btrfs_delalloc_release_space(inode, data_reserved, block_start, +- blocksize, true); ++ if (ret) { ++ if (only_release_metadata) ++ btrfs_delalloc_release_metadata(BTRFS_I(inode), ++ blocksize, true); ++ else ++ btrfs_delalloc_release_space(inode, data_reserved, ++ block_start, blocksize, true); ++ } + btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize); + unlock_page(page); + put_page(page); + out: ++ if (only_release_metadata) ++ btrfs_end_write_no_snapshotting(BTRFS_I(inode)->root); + extent_changeset_free(data_reserved); + return ret; + } diff --git a/queue-5.4/btrfs-ensure-we-trim-ranges-across-block-group-boundary.patch b/queue-5.4/btrfs-ensure-we-trim-ranges-across-block-group-boundary.patch new file mode 100644 index 00000000000..90b2c5f1139 --- /dev/null +++ b/queue-5.4/btrfs-ensure-we-trim-ranges-across-block-group-boundary.patch @@ -0,0 +1,194 @@ +From 6b7faadd985c990324b5b5bd18cc4ba5c395eb65 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Wed, 23 Oct 2019 21:57:27 +0800 +Subject: btrfs: Ensure we trim ranges across block group boundary + +From: Qu Wenruo + +commit 6b7faadd985c990324b5b5bd18cc4ba5c395eb65 upstream. + +[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 +Reviewed-by: Nikolay Borisov +Tested-by: Nikolay Borisov +Reviewed-by: Josef Bacik +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1305,8 +1305,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; + + +@@ -1315,15 +1317,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; + struct request_queue *req_q; +@@ -1340,10 +1350,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, +@@ -1353,7 +1372,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 +@@ -5676,12 +5676,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; +@@ -5715,6 +5716,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; + /* +@@ -6129,7 +6131,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); + + ret = btrfs_get_io_geometry(fs_info, op, logical, *length, &geom); + if (ret < 0) diff --git a/queue-5.4/btrfs-fix-rwf_nowait-write-not-failling-when-we-need-to-cow.patch b/queue-5.4/btrfs-fix-rwf_nowait-write-not-failling-when-we-need-to-cow.patch new file mode 100644 index 00000000000..c5383b83547 --- /dev/null +++ b/queue-5.4/btrfs-fix-rwf_nowait-write-not-failling-when-we-need-to-cow.patch @@ -0,0 +1,84 @@ +From 260a63395f90f67d6ab89e4266af9e3dc34a77e9 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 15 Jun 2020 18:49:13 +0100 +Subject: btrfs: fix RWF_NOWAIT write not failling when we need to cow + +From: Filipe Manana + +commit 260a63395f90f67d6ab89e4266af9e3dc34a77e9 upstream. + +If we attempt to do a RWF_NOWAIT write against a file range for which we +can only do NOCOW for a part of it, due to the existence of holes or +shared extents for example, we proceed with the write as if it were +possible to NOCOW the whole range. + +Example: + + $ mkfs.btrfs -f /dev/sdb + $ mount /dev/sdb /mnt + + $ touch /mnt/sdj/bar + $ chattr +C /mnt/sdj/bar + + $ xfs_io -d -c "pwrite -S 0xab -b 256K 0 256K" /mnt/bar + wrote 262144/262144 bytes at offset 0 + 256 KiB, 1 ops; 0.0003 sec (694.444 MiB/sec and 2777.7778 ops/sec) + + $ xfs_io -c "fpunch 64K 64K" /mnt/bar + $ sync + + $ xfs_io -d -c "pwrite -N -V 1 -b 128K -S 0xfe 0 128K" /mnt/bar + wrote 131072/131072 bytes at offset 0 + 128 KiB, 1 ops; 0.0007 sec (160.051 MiB/sec and 1280.4097 ops/sec) + +This last write should fail with -EAGAIN since the file range from 64K to +128K is a hole. On xfs it fails, as expected, but on ext4 it currently +succeeds because apparently it is expensive to check if there are extents +allocated for the whole range, but I'll check with the ext4 people. + +Fix the issue by checking if check_can_nocow() returns a number of +NOCOW'able bytes smaller then the requested number of bytes, and if it +does return -EAGAIN. + +Fixes: edf064e7c6fec3 ("btrfs: nowait aio support") +CC: stable@vger.kernel.org # 4.14+ +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/file.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1919,13 +1919,27 @@ static ssize_t btrfs_file_write_iter(str + pos = iocb->ki_pos; + count = iov_iter_count(from); + if (iocb->ki_flags & IOCB_NOWAIT) { ++ size_t nocow_bytes = count; ++ + /* + * We will allocate space in case nodatacow is not set, + * so bail + */ + if (!(BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | + BTRFS_INODE_PREALLOC)) || +- check_can_nocow(BTRFS_I(inode), pos, &count) <= 0) { ++ check_can_nocow(BTRFS_I(inode), pos, &nocow_bytes) <= 0) { ++ inode_unlock(inode); ++ return -EAGAIN; ++ } ++ ++ /* check_can_nocow() locks the snapshot lock on success */ ++ btrfs_end_write_no_snapshotting(root); ++ /* ++ * There are holes in the range or parts of the range that must ++ * be COWed (shared extents, RO block groups, etc), so just bail ++ * out. ++ */ ++ if (nocow_bytes < count) { + inode_unlock(inode); + return -EAGAIN; + } diff --git a/queue-5.4/btrfs-send-allow-clone-operations-within-the-same-file.patch b/queue-5.4/btrfs-send-allow-clone-operations-within-the-same-file.patch new file mode 100644 index 00000000000..8099b4185a9 --- /dev/null +++ b/queue-5.4/btrfs-send-allow-clone-operations-within-the-same-file.patch @@ -0,0 +1,90 @@ +From 11f2069c113e02971b8db6fda62f9b9cd31a030f Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 30 Oct 2019 12:23:11 +0000 +Subject: Btrfs: send, allow clone operations within the same file + +From: Filipe Manana + +commit 11f2069c113e02971b8db6fda62f9b9cd31a030f upstream. + +For send we currently skip clone operations when the source and +destination files are the same. This is so because clone didn't support +this case in its early days, but support for it was added back in May +2013 by commit a96fbc72884fcb ("Btrfs: allow file data clone within a +file"). This change adds support for it. + +Example: + + $ mkfs.btrfs -f /dev/sdd + $ mount /dev/sdd /mnt/sdd + + $ xfs_io -f -c "pwrite -S 0xab -b 64K 0 64K" /mnt/sdd/foobar + $ xfs_io -c "reflink /mnt/sdd/foobar 0 64K 64K" /mnt/sdd/foobar + + $ btrfs subvolume snapshot -r /mnt/sdd /mnt/sdd/snap + + $ mkfs.btrfs -f /dev/sde + $ mount /dev/sde /mnt/sde + + $ btrfs send /mnt/sdd/snap | btrfs receive /mnt/sde + +Without this change file foobar at the destination has a single 128Kb +extent: + + $ filefrag -v /mnt/sde/snap/foobar + Filesystem type is: 9123683e + File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes) + ext: logical_offset: physical_offset: length: expected: flags: + 0: 0.. 31: 0.. 31: 32: last,unknown_loc,delalloc,eof + /mnt/sde/snap/foobar: 1 extent found + +With this we get a single 64Kb extent that is shared at file offsets 0 +and 64K, just like in the source filesystem: + + $ filefrag -v /mnt/sde/snap/foobar + Filesystem type is: 9123683e + File size of /mnt/sde/snap/foobar is 131072 (32 blocks of 4096 bytes) + ext: logical_offset: physical_offset: length: expected: flags: + 0: 0.. 15: 3328.. 3343: 16: shared + 1: 16.. 31: 3328.. 3343: 16: 3344: last,shared,eof + /mnt/sde/snap/foobar: 2 extents found + +Reviewed-by: Josef Bacik +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/send.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -1257,12 +1257,20 @@ static int __iterate_backrefs(u64 ino, u + */ + if (found->root == bctx->sctx->send_root) { + /* +- * TODO for the moment we don't accept clones from the inode +- * that is currently send. We may change this when +- * BTRFS_IOC_CLONE_RANGE supports cloning from and to the same +- * file. ++ * If the source inode was not yet processed we can't issue a ++ * clone operation, as the source extent does not exist yet at ++ * the destination of the stream. + */ +- if (ino >= bctx->cur_objectid) ++ if (ino > bctx->cur_objectid) ++ return 0; ++ /* ++ * We clone from the inode currently being sent as long as the ++ * source extent is already processed, otherwise we could try ++ * to clone from an extent that does not exist yet at the ++ * destination of the stream. ++ */ ++ if (ino == bctx->cur_objectid && ++ offset >= bctx->sctx->cur_inode_next_write_offset) + return 0; + } + diff --git a/queue-5.4/btrfs-send-fix-emission-of-invalid-clone-operations-within-the-same-file.patch b/queue-5.4/btrfs-send-fix-emission-of-invalid-clone-operations-within-the-same-file.patch new file mode 100644 index 00000000000..432dbc29417 --- /dev/null +++ b/queue-5.4/btrfs-send-fix-emission-of-invalid-clone-operations-within-the-same-file.patch @@ -0,0 +1,93 @@ +From 9722b10148504c4153a74a9c89725af271e490fc Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 29 Jan 2020 17:09:53 +0000 +Subject: Btrfs: send, fix emission of invalid clone operations within the same file + +From: Filipe Manana + +commit 9722b10148504c4153a74a9c89725af271e490fc upstream. + +When doing an incremental send and a file has extents shared with itself +at different file offsets, it's possible for send to emit clone operations +that will fail at the destination because the source range goes beyond the +file's current size. This happens when the file size has increased in the +send snapshot, there is a hole between the shared extents and both shared +extents are at file offsets which are greater the file's size in the +parent snapshot. + +Example: + + $ mkfs.btrfs -f /dev/sdb + $ mount /dev/sdb /mnt/sdb + + $ xfs_io -f -c "pwrite -S 0xf1 0 64K" /mnt/sdb/foobar + $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/base + $ btrfs send -f /tmp/1.snap /mnt/sdb/base + + # Create a 320K extent at file offset 512K. + $ xfs_io -c "pwrite -S 0xab 512K 64K" /mnt/sdb/foobar + $ xfs_io -c "pwrite -S 0xcd 576K 64K" /mnt/sdb/foobar + $ xfs_io -c "pwrite -S 0xef 640K 64K" /mnt/sdb/foobar + $ xfs_io -c "pwrite -S 0x64 704K 64K" /mnt/sdb/foobar + $ xfs_io -c "pwrite -S 0x73 768K 64K" /mnt/sdb/foobar + + # Clone part of that 320K extent into a lower file offset (192K). + # This file offset is greater than the file's size in the parent + # snapshot (64K). Also the clone range is a bit behind the offset of + # the 320K extent so that we leave a hole between the shared extents. + $ xfs_io -c "reflink /mnt/sdb/foobar 448K 192K 192K" /mnt/sdb/foobar + + $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/incr + $ btrfs send -p /mnt/sdb/base -f /tmp/2.snap /mnt/sdb/incr + + $ mkfs.btrfs -f /dev/sdc + $ mount /dev/sdc /mnt/sdc + + $ btrfs receive -f /tmp/1.snap /mnt/sdc + $ btrfs receive -f /tmp/2.snap /mnt/sdc + ERROR: failed to clone extents to foobar: Invalid argument + +The problem is that after processing the extent at file offset 256K, which +refers to the first 128K of the 320K extent created by the buffered write +operations, we have 'cur_inode_next_write_offset' set to 384K, which +corresponds to the end offset of the partially shared extent (256K + 128K) +and to the current file size in the receiver. Then when we process the +extent at offset 512K, we do extent backreference iteration to figure out +if we can clone the extent from some other inode or from the same inode, +and we consider the extent at offset 256K of the same inode as a valid +source for a clone operation, which is not correct because at that point +the current file size in the receiver is 384K, which corresponds to the +end of last processed extent (at file offset 256K), so using a clone +source range from 256K to 256K + 320K is invalid because that goes past +the current size of the file (384K) - this makes the receiver get an +-EINVAL error when attempting the clone operation. + +So fix this by excluding clone sources that have a range that goes beyond +the current file size in the receiver when iterating extent backreferences. + +A test case for fstests follows soon. + +Fixes: 11f2069c113e02 ("Btrfs: send, allow clone operations within the same file") +CC: stable@vger.kernel.org # 5.5+ +Reviewed-by: Josef Bacik +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/send.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -1270,7 +1270,8 @@ static int __iterate_backrefs(u64 ino, u + * destination of the stream. + */ + if (ino == bctx->cur_objectid && +- offset >= bctx->sctx->cur_inode_next_write_offset) ++ offset + bctx->extent_len > ++ bctx->sctx->cur_inode_next_write_offset) + return 0; + } + diff --git a/queue-5.4/btrfs-volumes-use-more-straightforward-way-to-calculate-map-length.patch b/queue-5.4/btrfs-volumes-use-more-straightforward-way-to-calculate-map-length.patch new file mode 100644 index 00000000000..c08a945b4a2 --- /dev/null +++ b/queue-5.4/btrfs-volumes-use-more-straightforward-way-to-calculate-map-length.patch @@ -0,0 +1,46 @@ +From 2d974619a77f106f3d1341686dea95c0eaad601f Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Wed, 23 Oct 2019 21:57:26 +0800 +Subject: btrfs: volumes: Use more straightforward way to calculate map length + +From: Qu Wenruo + +commit 2d974619a77f106f3d1341686dea95c0eaad601f upstream. + +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 +Reviewed-by: Josef Bacik +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/volumes.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -5714,7 +5714,7 @@ static int __btrfs_map_block_for_discard + } + + 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; + /* diff --git a/queue-5.4/i2c-i801-exclude-device-from-suspend-direct-complete-optimization.patch b/queue-5.4/i2c-i801-exclude-device-from-suspend-direct-complete-optimization.patch new file mode 100644 index 00000000000..38567505521 --- /dev/null +++ b/queue-5.4/i2c-i801-exclude-device-from-suspend-direct-complete-optimization.patch @@ -0,0 +1,40 @@ +From 845b89127bc5458d0152a4d63f165c62a22fcb70 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Thu, 10 Sep 2020 11:57:08 +0200 +Subject: i2c: i801: Exclude device from suspend direct complete optimization +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jean Delvare + +commit 845b89127bc5458d0152a4d63f165c62a22fcb70 upstream. + +By default, PCI drivers with runtime PM enabled will skip the calls +to suspend and resume on system PM. For this driver, we don't want +that, as we need to perform additional steps for system PM to work +properly on all systems. So instruct the PM core to not skip these +calls. + +Fixes: a9c8088c7988 ("i2c: i801: Don't restore config registers on runtime PM") +Reported-by: Volker Rümelin +Signed-off-by: Jean Delvare +Cc: stable@vger.kernel.org +Signed-off-by: Wolfram Sang +[iwamatsu: Use DPM_FLAG_NEVER_SKIP instead of DPM_FLAG_NO_DIRECT_COMPLETE] +Signed-off-by: Nobuhiro Iwamatsu (CIP) +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-i801.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -1891,6 +1891,7 @@ static int i801_probe(struct pci_dev *de + + pci_set_drvdata(dev, priv); + ++ dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NEVER_SKIP); + pm_runtime_set_autosuspend_delay(&dev->dev, 1000); + pm_runtime_use_autosuspend(&dev->dev); + pm_runtime_put_autosuspend(&dev->dev); diff --git a/queue-5.4/perf-test-session-topology-fix-data-path.patch b/queue-5.4/perf-test-session-topology-fix-data-path.patch new file mode 100644 index 00000000000..8caa78ac9f1 --- /dev/null +++ b/queue-5.4/perf-test-session-topology-fix-data-path.patch @@ -0,0 +1,98 @@ +From dbd660e6b2884b864d2642d930a163d3bcebe4be Mon Sep 17 00:00:00 2001 +From: Tommi Rantala +Date: Thu, 23 Apr 2020 14:53:40 +0300 +Subject: perf test session topology: Fix data path + +From: Tommi Rantala + +commit dbd660e6b2884b864d2642d930a163d3bcebe4be upstream. + +Commit 2d4f27999b88 ("perf data: Add global path holder") missed path +conversion in tests/topology.c, causing the "Session topology" testcase +to "hang" (waits forever for input from stdin) when doing "ssh $VM perf +test". + +Can be reproduced by running "cat | perf test topo", and crashed by +replacing cat with true: + + $ true | perf test -v topo + 40: Session topology : + --- start --- + test child forked, pid 3638 + templ file: /tmp/perf-test-QPvAch + incompatible file format + incompatible file format (rerun with -v to learn more) + free(): invalid pointer + test child interrupted + ---- end ---- + Session topology: FAILED! + +Committer testing: + +Reproduced the above result before the patch and after it is back +working: + + # true | perf test -v topo + 41: Session topology : + --- start --- + test child forked, pid 19374 + templ file: /tmp/perf-test-YOTEQg + CPU 0, core 0, socket 0 + CPU 1, core 1, socket 0 + CPU 2, core 2, socket 0 + CPU 3, core 3, socket 0 + CPU 4, core 0, socket 0 + CPU 5, core 1, socket 0 + CPU 6, core 2, socket 0 + CPU 7, core 3, socket 0 + test child finished with 0 + ---- end ---- + Session topology: Ok + # + +Fixes: 2d4f27999b88 ("perf data: Add global path holder") +Signed-off-by: Tommi Rantala +Tested-by: Arnaldo Carvalho de Melo +Acked-by: Jiri Olsa +Cc: Alexander Shishkin +Cc: Mamatha Inamdar +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Ravi Bangoria +Link: http://lore.kernel.org/lkml/20200423115341.562782-1-tommi.t.rantala@nokia.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/tests/topology.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/tools/perf/tests/topology.c ++++ b/tools/perf/tests/topology.c +@@ -33,10 +33,8 @@ static int session_write_header(char *pa + { + struct perf_session *session; + struct perf_data data = { +- .file = { +- .path = path, +- }, +- .mode = PERF_DATA_MODE_WRITE, ++ .path = path, ++ .mode = PERF_DATA_MODE_WRITE, + }; + + session = perf_session__new(&data, false, NULL); +@@ -63,10 +61,8 @@ static int check_cpu_topology(char *path + { + struct perf_session *session; + struct perf_data data = { +- .file = { +- .path = path, +- }, +- .mode = PERF_DATA_MODE_READ, ++ .path = path, ++ .mode = PERF_DATA_MODE_READ, + }; + int i; + diff --git a/queue-5.4/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch b/queue-5.4/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch new file mode 100644 index 00000000000..6f440610d01 --- /dev/null +++ b/queue-5.4/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch @@ -0,0 +1,53 @@ +From 29b4f5f188571c112713c35cc87eefb46efee612 Mon Sep 17 00:00:00 2001 +From: Tommi Rantala +Date: Thu, 5 Mar 2020 10:37:12 +0200 +Subject: perf top: Fix stdio interface input handling with glibc 2.28+ + +From: Tommi Rantala + +commit 29b4f5f188571c112713c35cc87eefb46efee612 upstream. + +Since glibc 2.28 when running 'perf top --stdio', input handling no +longer works, but hitting any key always just prints the "Mapped keys" +help text. + +To fix it, call clearerr() in the display_thread() loop to clear any EOF +sticky errors, as instructed in the glibc NEWS file +(https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS): + + * All stdio functions now treat end-of-file as a sticky condition. If you + read from a file until EOF, and then the file is enlarged by another + process, you must call clearerr or another function with the same effect + (e.g. fseek, rewind) before you can read the additional data. This + corrects a longstanding C99 conformance bug. It is most likely to affect + programs that use stdio to read interactive input from a terminal. + (Bug #1190.) + +Signed-off-by: Tommi Rantala +Tested-by: Arnaldo Carvalho de Melo +Cc: Alexander Shishkin +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: http://lore.kernel.org/lkml/20200305083714.9381-2-tommi.t.rantala@nokia.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/builtin-top.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/tools/perf/builtin-top.c ++++ b/tools/perf/builtin-top.c +@@ -683,7 +683,9 @@ repeat: + delay_msecs = top->delay_secs * MSEC_PER_SEC; + set_term_quiet_input(&save); + /* trash return*/ +- getc(stdin); ++ clearerr(stdin); ++ if (poll(&stdin_poll, 1, 0) > 0) ++ getc(stdin); + + while (!done) { + perf_top__print_sym_table(top); diff --git a/queue-5.4/series b/queue-5.4/series index 768dd47d563..403568fc7f5 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -19,3 +19,13 @@ bpf-prevent-.btf-section-elimination.patch platform-x86-intel-vbtn-switch-to-an-allow-list-for-sw_tablet_mode-reporting.patch platform-x86-thinkpad_acpi-re-initialize-acpi-buffer-size-when-reuse.patch driver-core-fix-probe_count-imbalance-in-really_probe.patch +perf-test-session-topology-fix-data-path.patch +perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch +i2c-i801-exclude-device-from-suspend-direct-complete-optimization.patch +arm64-dts-stratix10-add-status-to-qspi-dts-node.patch +btrfs-send-allow-clone-operations-within-the-same-file.patch +btrfs-send-fix-emission-of-invalid-clone-operations-within-the-same-file.patch +btrfs-volumes-use-more-straightforward-way-to-calculate-map-length.patch +btrfs-ensure-we-trim-ranges-across-block-group-boundary.patch +btrfs-fix-rwf_nowait-write-not-failling-when-we-need-to-cow.patch +btrfs-allow-btrfs_truncate_block-to-fallback-to-nocow-for-data-space-reservation.patch