]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2023 12:54:12 +0000 (13:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2023 12:54:12 +0000 (13:54 +0100)
added patches:
btrfs-fix-compat_ro-checks-against-remount.patch
btrfs-fix-off-by-one-in-delalloc-search-during-lseek.patch
usb-dwc3-gadget-ignore-end-transfer-delay-on-teardown.patch

queue-6.1/btrfs-fix-compat_ro-checks-against-remount.patch [new file with mode: 0644]
queue-6.1/btrfs-fix-off-by-one-in-delalloc-search-during-lseek.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/usb-dwc3-gadget-ignore-end-transfer-delay-on-teardown.patch [new file with mode: 0644]

diff --git a/queue-6.1/btrfs-fix-compat_ro-checks-against-remount.patch b/queue-6.1/btrfs-fix-compat_ro-checks-against-remount.patch
new file mode 100644 (file)
index 0000000..41aeaa3
--- /dev/null
@@ -0,0 +1,145 @@
+From 2ba48b20049b5a76f34a85f853c9496d1b10533a Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 22 Dec 2022 07:59:17 +0800
+Subject: btrfs: fix compat_ro checks against remount
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 2ba48b20049b5a76f34a85f853c9496d1b10533a upstream.
+
+[BUG]
+Even with commit 81d5d61454c3 ("btrfs: enhance unsupported compat RO
+flags handling"), btrfs can still mount a fs with unsupported compat_ro
+flags read-only, then remount it RW:
+
+  # btrfs ins dump-super /dev/loop0 | grep compat_ro_flags -A 3
+  compat_ro_flags              0x403
+                       ( FREE_SPACE_TREE |
+                         FREE_SPACE_TREE_VALID |
+                         unknown flag: 0x400 )
+
+  # mount /dev/loop0 /mnt/btrfs
+  mount: /mnt/btrfs: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.
+         dmesg(1) may have more information after failed mount system call.
+  ^^^ RW mount failed as expected ^^^
+
+  # dmesg -t | tail -n5
+  loop0: detected capacity change from 0 to 1048576
+  BTRFS: device fsid cb5b82f5-0fdd-4d81-9b4b-78533c324afa devid 1 transid 7 /dev/loop0 scanned by mount (1146)
+  BTRFS info (device loop0): using crc32c (crc32c-intel) checksum algorithm
+  BTRFS info (device loop0): using free space tree
+  BTRFS error (device loop0): cannot mount read-write because of unknown compat_ro features (0x403)
+  BTRFS error (device loop0): open_ctree failed
+
+  # mount /dev/loop0 -o ro /mnt/btrfs
+  # mount -o remount,rw /mnt/btrfs
+  ^^^ RW remount succeeded unexpectedly ^^^
+
+[CAUSE]
+Currently we use btrfs_check_features() to check compat_ro flags against
+our current mount flags.
+
+That function get reused between open_ctree() and btrfs_remount().
+
+But for btrfs_remount(), the super block we passed in still has the old
+mount flags, thus btrfs_check_features() still believes we're mounting
+read-only.
+
+[FIX]
+Replace the existing @sb argument with @is_rw_mount.
+
+As originally we only use @sb to determine if the mount is RW.
+
+Now it's callers' responsibility to determine if the mount is RW, and
+since there are only two callers, the check is pretty simple:
+
+- caller in open_ctree()
+  Just pass !sb_rdonly().
+
+- caller in btrfs_remount()
+  Pass !(*flags & SB_RDONLY), as our check should be against the new
+  flags.
+
+Now we can correctly reject the RW remount:
+
+  # mount /dev/loop0 -o ro /mnt/btrfs
+  # mount -o remount,rw /mnt/btrfs
+  mount: /mnt/btrfs: mount point not mounted or bad option.
+         dmesg(1) may have more information after failed mount system call.
+  # dmesg -t | tail -n 1
+  BTRFS error (device loop0: state M): cannot mount read-write because of unknown compat_ro features (0x403)
+
+Reported-by: Chung-Chiang Cheng <shepjeng@gmail.com>
+Fixes: 81d5d61454c3 ("btrfs: enhance unsupported compat RO flags handling")
+CC: stable@vger.kernel.org # 5.15+
+Reviewed-by: Anand Jain <anand.jain@oracle.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 |    8 +++++---
+ fs/btrfs/disk-io.h |    2 +-
+ fs/btrfs/super.c   |    2 +-
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -3296,6 +3296,8 @@ out:
+ /*
+  * Do various sanity and dependency checks of different features.
+  *
++ * @is_rw_mount:      If the mount is read-write.
++ *
+  * This is the place for less strict checks (like for subpage or artificial
+  * feature dependencies).
+  *
+@@ -3306,7 +3308,7 @@ out:
+  * (space cache related) can modify on-disk format like free space tree and
+  * screw up certain feature dependencies.
+  */
+-int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb)
++int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
+ {
+       struct btrfs_super_block *disk_super = fs_info->super_copy;
+       u64 incompat = btrfs_super_incompat_flags(disk_super);
+@@ -3345,7 +3347,7 @@ int btrfs_check_features(struct btrfs_fs
+       if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
+               incompat |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
+-      if (compat_ro_unsupp && !sb_rdonly(sb)) {
++      if (compat_ro_unsupp && is_rw_mount) {
+               btrfs_err(fs_info,
+       "cannot mount read-write because of unknown compat_ro features (0x%llx)",
+                      compat_ro);
+@@ -3548,7 +3550,7 @@ int __cold open_ctree(struct super_block
+               goto fail_alloc;
+       }
+-      ret = btrfs_check_features(fs_info, sb);
++      ret = btrfs_check_features(fs_info, !sb_rdonly(sb));
+       if (ret < 0) {
+               err = ret;
+               goto fail_alloc;
+--- a/fs/btrfs/disk-io.h
++++ b/fs/btrfs/disk-io.h
+@@ -50,7 +50,7 @@ int __cold open_ctree(struct super_block
+ void __cold close_ctree(struct btrfs_fs_info *fs_info);
+ int btrfs_validate_super(struct btrfs_fs_info *fs_info,
+                        struct btrfs_super_block *sb, int mirror_num);
+-int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb);
++int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
+ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
+ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev);
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2014,7 +2014,7 @@ static int btrfs_remount(struct super_bl
+       if (ret)
+               goto restore;
+-      ret = btrfs_check_features(fs_info, sb);
++      ret = btrfs_check_features(fs_info, !(*flags & SB_RDONLY));
+       if (ret < 0)
+               goto restore;
diff --git a/queue-6.1/btrfs-fix-off-by-one-in-delalloc-search-during-lseek.patch b/queue-6.1/btrfs-fix-off-by-one-in-delalloc-search-during-lseek.patch
new file mode 100644 (file)
index 0000000..5c97547
--- /dev/null
@@ -0,0 +1,74 @@
+From 2f2e84ca60660402bd81d0859703567c59556e6a Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Fri, 23 Dec 2022 18:28:53 +0000
+Subject: btrfs: fix off-by-one in delalloc search during lseek
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 2f2e84ca60660402bd81d0859703567c59556e6a upstream.
+
+During lseek, when searching for delalloc in a range that represents a
+hole and that range has a length of 1 byte, we end up not doing the actual
+delalloc search in the inode's io tree, resulting in not correctly
+reporting the offset with data or a hole. This actually only happens when
+the start offset is 0 because with any other start offset we round it down
+by sector size.
+
+Reproducer:
+
+  $ mkfs.btrfs -f /dev/sdc
+  $ mount /dev/sdc /mnt/sdc
+
+  $ xfs_io -f -c "pwrite -q 0 1" /mnt/sdc/foo
+
+  $ xfs_io -c "seek -d 0" /mnt/sdc/foo
+  Whence   Result
+  DATA    EOF
+
+It should have reported an offset of 0 instead of EOF.
+
+Fix this by updating btrfs_find_delalloc_in_range() and count_range_bits()
+to deal with inclusive ranges properly. These functions are already
+supposed to work with inclusive end offsets, they just got it wrong in a
+couple places due to off-by-one mistakes.
+
+A test case for fstests will be added later.
+
+Reported-by: Joan Bruguera Micó <joanbrugueram@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/20221223020509.457113-1-joanbrugueram@gmail.com/
+Fixes: b6e833567ea1 ("btrfs: make hole and data seeking a lot more efficient")
+CC: stable@vger.kernel.org # 6.1
+Tested-by: Joan Bruguera Micó <joanbrugueram@gmail.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent-io-tree.c |    2 +-
+ fs/btrfs/file.c           |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/extent-io-tree.c
++++ b/fs/btrfs/extent-io-tree.c
+@@ -1507,7 +1507,7 @@ u64 count_range_bits(struct extent_io_tr
+       u64 last = 0;
+       int found = 0;
+-      if (WARN_ON(search_end <= cur_start))
++      if (WARN_ON(search_end < cur_start))
+               return 0;
+       spin_lock(&tree->lock);
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -3671,7 +3671,7 @@ bool btrfs_find_delalloc_in_range(struct
+       u64 prev_delalloc_end = 0;
+       bool ret = false;
+-      while (cur_offset < end) {
++      while (cur_offset <= end) {
+               u64 delalloc_start;
+               u64 delalloc_end;
+               bool delalloc;
index 67ce78e43b3b983f5f6b6e30e0544cebf94d71cf..fad2dc6a7337a6053e7318c2003ec6c265800031 100644 (file)
@@ -2,3 +2,6 @@ arm-renumber-bits-related-to-_tif_work_mask.patch
 btrfs-replace-strncpy-with-strscpy.patch
 cifs-fix-interface-count-calculation-during-refresh.patch
 cifs-refcount-only-the-selected-iface-during-interface-update.patch
+usb-dwc3-gadget-ignore-end-transfer-delay-on-teardown.patch
+btrfs-fix-off-by-one-in-delalloc-search-during-lseek.patch
+btrfs-fix-compat_ro-checks-against-remount.patch
diff --git a/queue-6.1/usb-dwc3-gadget-ignore-end-transfer-delay-on-teardown.patch b/queue-6.1/usb-dwc3-gadget-ignore-end-transfer-delay-on-teardown.patch
new file mode 100644 (file)
index 0000000..31b8d3d
--- /dev/null
@@ -0,0 +1,56 @@
+From c4e3ef5685393c5051b52cf1e94b8891d49793ab Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 8 Dec 2022 16:50:35 -0800
+Subject: usb: dwc3: gadget: Ignore End Transfer delay on teardown
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit c4e3ef5685393c5051b52cf1e94b8891d49793ab upstream.
+
+If we delay sending End Transfer for Setup TRB to be prepared, we need
+to check if the End Transfer was in preparation for a driver
+teardown/soft-disconnect. In those cases, just send the End Transfer
+command without delay.
+
+In the case of soft-disconnect, there's a very small chance the command
+may not go through immediately. But should it happen, the Setup TRB will
+be prepared during the polling of the controller halted state, allowing
+the command to go through then.
+
+In the case of disabling endpoint due to reconfiguration (e.g.
+set_interface(alt-setting) or usb reset), then it's driven by the host.
+Typically the host wouldn't immediately cancel the control request and
+send another control transfer to trigger the End Transfer command
+timeout.
+
+Fixes: 4db0fbb60136 ("usb: dwc3: gadget: Don't delay End Transfer on delayed_status")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/f1617a323e190b9cc408fb8b65456e32b5814113.1670546756.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1717,6 +1717,7 @@ static int __dwc3_stop_active_transfer(s
+       else if (!ret)
+               dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
++      dep->flags &= ~DWC3_EP_DELAY_STOP;
+       return ret;
+ }
+@@ -3722,8 +3723,10 @@ void dwc3_stop_active_transfer(struct dw
+       if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
+               return;
++      if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
++              return;
++
+       if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+-          (dep->flags & DWC3_EP_DELAY_STOP) ||
+           (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+               return;