--- /dev/null
+From 2a5898c4aac67494c2f0f7fe38373c95c371c930 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 21 May 2025 17:41:18 +0100
+Subject: btrfs: abort transaction during log replay if walk_log_tree() failed
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 2a5898c4aac67494c2f0f7fe38373c95c371c930 upstream.
+
+If we failed walking a log tree during replay, we have a missing
+transaction abort to prevent committing a transaction where we didn't
+fully replay all the changes from a log tree and therefore can leave the
+respective subvolume tree in some inconsistent state. So add the missing
+transaction abort.
+
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@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/tree-log.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -7252,11 +7252,14 @@ again:
+
+ wc.replay_dest->log_root = log;
+ ret = btrfs_record_root_in_trans(trans, wc.replay_dest);
+- if (ret)
++ if (ret) {
+ /* The loop needs to continue due to the root refs */
+ btrfs_abort_transaction(trans, ret);
+- else
++ } else {
+ ret = walk_log_tree(trans, log, &wc);
++ if (ret)
++ btrfs_abort_transaction(trans, ret);
++ }
+
+ if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
+ ret = fixup_inode_link_counts(trans, wc.replay_dest,
--- /dev/null
+From 4289b494ac553e74e86fed1c66b2bf9530bc1082 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 25 Jul 2025 20:33:25 +0930
+Subject: btrfs: do not allow relocation of partially dropped subvolumes
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 4289b494ac553e74e86fed1c66b2bf9530bc1082 upstream.
+
+[BUG]
+There is an internal report that balance triggered transaction abort,
+with the following call trace:
+
+ item 85 key (594509824 169 0) itemoff 12599 itemsize 33
+ extent refs 1 gen 197740 flags 2
+ ref#0: tree block backref root 7
+ item 86 key (594558976 169 0) itemoff 12566 itemsize 33
+ extent refs 1 gen 197522 flags 2
+ ref#0: tree block backref root 7
+ ...
+ BTRFS error (device loop0): extent item not found for insert, bytenr 594526208 num_bytes 16384 parent 449921024 root_objectid 934 owner 1 offset 0
+ BTRFS error (device loop0): failed to run delayed ref for logical 594526208 num_bytes 16384 type 182 action 1 ref_mod 1: -117
+ ------------[ cut here ]------------
+ BTRFS: Transaction aborted (error -117)
+ WARNING: CPU: 1 PID: 6963 at ../fs/btrfs/extent-tree.c:2168 btrfs_run_delayed_refs+0xfa/0x110 [btrfs]
+
+And btrfs check doesn't report anything wrong related to the extent
+tree.
+
+[CAUSE]
+The cause is a little complex, firstly the extent tree indeed doesn't
+have the backref for 594526208.
+
+The extent tree only have the following two backrefs around that bytenr
+on-disk:
+
+ item 65 key (594509824 METADATA_ITEM 0) itemoff 13880 itemsize 33
+ refs 1 gen 197740 flags TREE_BLOCK
+ tree block skinny level 0
+ (176 0x7) tree block backref root CSUM_TREE
+ item 66 key (594558976 METADATA_ITEM 0) itemoff 13847 itemsize 33
+ refs 1 gen 197522 flags TREE_BLOCK
+ tree block skinny level 0
+ (176 0x7) tree block backref root CSUM_TREE
+
+But the such missing backref item is not an corruption on disk, as the
+offending delayed ref belongs to subvolume 934, and that subvolume is
+being dropped:
+
+ item 0 key (934 ROOT_ITEM 198229) itemoff 15844 itemsize 439
+ generation 198229 root_dirid 256 bytenr 10741039104 byte_limit 0 bytes_used 345571328
+ last_snapshot 198229 flags 0x1000000000001(RDONLY) refs 0
+ drop_progress key (206324 EXTENT_DATA 2711650304) drop_level 2
+ level 2 generation_v2 198229
+
+And that offending tree block 594526208 is inside the dropped range of
+that subvolume. That explains why there is no backref item for that
+bytenr and why btrfs check is not reporting anything wrong.
+
+But this also shows another problem, as btrfs will do all the orphan
+subvolume cleanup at a read-write mount.
+
+So half-dropped subvolume should not exist after an RW mount, and
+balance itself is also exclusive to subvolume cleanup, meaning we
+shouldn't hit a subvolume half-dropped during relocation.
+
+The root cause is, there is no orphan item for this subvolume.
+In fact there are 5 subvolumes from around 2021 that have the same
+problem.
+
+It looks like the original report has some older kernels running, and
+caused those zombie subvolumes.
+
+Thankfully upstream commit 8d488a8c7ba2 ("btrfs: fix subvolume/snapshot
+deletion not triggered on mount") has long fixed the bug.
+
+[ENHANCEMENT]
+For repairing such old fs, btrfs-progs will be enhanced.
+
+Considering how delayed the problem will show up (at run delayed ref
+time) and at that time we have to abort transaction already, it is too
+late.
+
+Instead here we reject any half-dropped subvolume for reloc tree at the
+earliest time, preventing confusion and extra time wasted on debugging
+similar bugs.
+
+CC: stable@vger.kernel.org # 5.15+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/relocation.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -751,6 +751,25 @@ static struct btrfs_root *create_reloc_r
+ if (root->root_key.objectid == objectid) {
+ u64 commit_root_gen;
+
++ /*
++ * Relocation will wait for cleaner thread, and any half-dropped
++ * subvolume will be fully cleaned up at mount time.
++ * So here we shouldn't hit a subvolume with non-zero drop_progress.
++ *
++ * If this isn't the case, error out since it can make us attempt to
++ * drop references for extents that were already dropped before.
++ */
++ if (unlikely(btrfs_disk_key_objectid(&root->root_item.drop_progress))) {
++ struct btrfs_key cpu_key;
++
++ btrfs_disk_key_to_cpu(&cpu_key, &root->root_item.drop_progress);
++ btrfs_err(fs_info,
++ "cannot relocate partially dropped subvolume %llu, drop progress key (%llu %u %llu)",
++ objectid, cpu_key.objectid, cpu_key.type, cpu_key.offset);
++ ret = -EUCLEAN;
++ goto fail;
++ }
++
+ /* called by btrfs_init_reloc_root */
+ ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
+ BTRFS_TREE_RELOC_OBJECTID);
--- /dev/null
+From 0a32e4f0025a74c70dcab4478e9b29c22f5ecf2f Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 30 Jul 2025 19:18:37 +0100
+Subject: btrfs: fix log tree replay failure due to file with 0 links and extents
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 0a32e4f0025a74c70dcab4478e9b29c22f5ecf2f upstream.
+
+If we log a new inode (not persisted in a past transaction) that has 0
+links and extents, then log another inode with an higher inode number, we
+end up with failing to replay the log tree with -EINVAL. The steps for
+this are:
+
+1) create new file A
+2) write some data to file A
+3) open an fd on file A
+4) unlink file A
+5) fsync file A using the previously open fd
+6) create file B (has higher inode number than file A)
+7) fsync file B
+8) power fail before current transaction commits
+
+Now when attempting to mount the fs, the log replay will fail with
+-ENOENT at replay_one_extent() when attempting to replay the first
+extent of file A. The failure comes when trying to open the inode for
+file A in the subvolume tree, since it doesn't exist.
+
+Before commit 5f61b961599a ("btrfs: fix inode lookup error handling
+during log replay"), the returned error was -EIO instead of -ENOENT,
+since we converted any errors when attempting to read an inode during
+log replay to -EIO.
+
+The reason for this is that the log replay procedure fails to ignore
+the current inode when we are at the stage LOG_WALK_REPLAY_ALL, our
+current inode has 0 links and last inode we processed in the previous
+stage has a non 0 link count. In other words, the issue is that at
+replay_one_extent() we only update wc->ignore_cur_inode if the current
+replay stage is LOG_WALK_REPLAY_INODES.
+
+Fix this by updating wc->ignore_cur_inode whenever we find an inode item
+regardless of the current replay stage. This is a simple solution and easy
+to backport, but later we can do other alternatives like avoid logging
+extents or inode items other than the inode item for inodes with a link
+count of 0.
+
+The problem with the wc->ignore_cur_inode logic has been around since
+commit f2d72f42d5fa ("Btrfs: fix warning when replaying log after fsync
+of a tmpfile") but it only became frequent to hit since the more recent
+commit 5e85262e542d ("btrfs: fix fsync of files with no hard links not
+persisting deletion"), because we stopped skipping inodes with a link
+count of 0 when logging, while before the problem would only be triggered
+if trying to replay a log tree created with an older kernel which has a
+logged inode with 0 links.
+
+A test case for fstests will be submitted soon.
+
+Reported-by: Peter Jung <ptr1337@cachyos.org>
+Link: https://lore.kernel.org/linux-btrfs/fce139db-4458-4788-bb97-c29acf6cb1df@cachyos.org/
+Reported-by: burneddi <burneddi@protonmail.com>
+Link: https://lore.kernel.org/linux-btrfs/lh4W-Lwc0Mbk-QvBhhQyZxf6VbM3E8VtIvU3fPIQgweP_Q1n7wtlUZQc33sYlCKYd-o6rryJQfhHaNAOWWRKxpAXhM8NZPojzsJPyHMf2qY=@protonmail.com/#t
+Reported-by: Russell Haley <yumpusamongus@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/598ecc75-eb80-41b3-83c2-f2317fbb9864@gmail.com/
+Fixes: f2d72f42d5fa ("Btrfs: fix warning when replaying log after fsync of a tmpfile")
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Boris Burkov <boris@bur.io>
+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/tree-log.c | 48 ++++++++++++++++++++++++++++++------------------
+ 1 file changed, 30 insertions(+), 18 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -298,8 +298,7 @@ struct walk_control {
+
+ /*
+ * Ignore any items from the inode currently being processed. Needs
+- * to be set every time we find a BTRFS_INODE_ITEM_KEY and we are in
+- * the LOG_WALK_REPLAY_INODES stage.
++ * to be set every time we find a BTRFS_INODE_ITEM_KEY.
+ */
+ bool ignore_cur_inode;
+
+@@ -2427,23 +2426,30 @@ static int replay_one_buffer(struct btrf
+
+ nritems = btrfs_header_nritems(eb);
+ for (i = 0; i < nritems; i++) {
+- btrfs_item_key_to_cpu(eb, &key, i);
++ struct btrfs_inode_item *inode_item;
+
+- /* inode keys are done during the first stage */
+- if (key.type == BTRFS_INODE_ITEM_KEY &&
+- wc->stage == LOG_WALK_REPLAY_INODES) {
+- struct btrfs_inode_item *inode_item;
+- u32 mode;
++ btrfs_item_key_to_cpu(eb, &key, i);
+
+- inode_item = btrfs_item_ptr(eb, i,
+- struct btrfs_inode_item);
++ if (key.type == BTRFS_INODE_ITEM_KEY) {
++ inode_item = btrfs_item_ptr(eb, i, struct btrfs_inode_item);
+ /*
+- * If we have a tmpfile (O_TMPFILE) that got fsync'ed
+- * and never got linked before the fsync, skip it, as
+- * replaying it is pointless since it would be deleted
+- * later. We skip logging tmpfiles, but it's always
+- * possible we are replaying a log created with a kernel
+- * that used to log tmpfiles.
++ * An inode with no links is either:
++ *
++ * 1) A tmpfile (O_TMPFILE) that got fsync'ed and never
++ * got linked before the fsync, skip it, as replaying
++ * it is pointless since it would be deleted later.
++ * We skip logging tmpfiles, but it's always possible
++ * we are replaying a log created with a kernel that
++ * used to log tmpfiles;
++ *
++ * 2) A non-tmpfile which got its last link deleted
++ * while holding an open fd on it and later got
++ * fsynced through that fd. We always log the
++ * parent inodes when inode->last_unlink_trans is
++ * set to the current transaction, so ignore all the
++ * inode items for this inode. We will delete the
++ * inode when processing the parent directory with
++ * replay_dir_deletes().
+ */
+ if (btrfs_inode_nlink(eb, inode_item) == 0) {
+ wc->ignore_cur_inode = true;
+@@ -2451,8 +2457,14 @@ static int replay_one_buffer(struct btrf
+ } else {
+ wc->ignore_cur_inode = false;
+ }
+- ret = replay_xattr_deletes(wc->trans, root, log,
+- path, key.objectid);
++ }
++
++ /* Inode keys are done during the first stage. */
++ if (key.type == BTRFS_INODE_ITEM_KEY &&
++ wc->stage == LOG_WALK_REPLAY_INODES) {
++ u32 mode;
++
++ ret = replay_xattr_deletes(wc->trans, root, log, path, key.objectid);
+ if (ret)
+ break;
+ mode = btrfs_inode_mode(eb, inode_item);
--- /dev/null
+From 3061801420469610c8fa6080a950e56770773ef1 Mon Sep 17 00:00:00 2001
+From: Naohiro Aota <naohiro.aota@wdc.com>
+Date: Sun, 29 Jun 2025 23:07:42 +0900
+Subject: btrfs: zoned: do not remove unwritten non-data block group
+
+From: Naohiro Aota <naohiro.aota@wdc.com>
+
+commit 3061801420469610c8fa6080a950e56770773ef1 upstream.
+
+There are some reports of "unable to find chunk map for logical 2147483648
+length 16384" error message appears in dmesg. This means some IOs are
+occurring after a block group is removed.
+
+When a metadata tree node is cleaned on a zoned setup, we keep that node
+still dirty and write it out not to create a write hole. However, this can
+make a block group's used bytes == 0 while there is a dirty region left.
+
+Such an unused block group is moved into the unused_bg list and processed
+for removal. When the removal succeeds, the block group is removed from the
+transaction->dirty_bgs list, so the unused dirty nodes in the block group
+are not sent at the transaction commit time. It will be written at some
+later time e.g, sync or umount, and causes "unable to find chunk map"
+errors.
+
+This can happen relatively easy on SMR whose zone size is 256MB. However,
+calling do_zone_finish() on such block group returns -EAGAIN and keep that
+block group intact, which is why the issue is hidden until now.
+
+Fixes: afba2bc036b0 ("btrfs: zoned: implement active zone tracking")
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/block-group.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -46,6 +46,19 @@ static u64 get_restripe_target(struct bt
+ return target;
+ }
+
++static inline bool has_unwritten_metadata(struct btrfs_block_group *block_group)
++{
++ /* The meta_write_pointer is available only on the zoned setup. */
++ if (!btrfs_is_zoned(block_group->fs_info))
++ return false;
++
++ if (block_group->flags & BTRFS_BLOCK_GROUP_DATA)
++ return false;
++
++ return block_group->start + block_group->alloc_offset >
++ block_group->meta_write_pointer;
++}
++
+ /*
+ * @flags: available profiles in extended format (see ctree.h)
+ *
+@@ -1091,6 +1104,15 @@ int btrfs_remove_block_group(struct btrf
+ goto out;
+
+ spin_lock(&block_group->lock);
++ /*
++ * Hitting this WARN means we removed a block group with an unwritten
++ * region. It will cause "unable to find chunk map for logical" errors.
++ */
++ if (WARN_ON(has_unwritten_metadata(block_group)))
++ btrfs_warn(fs_info,
++ "block group %llu is removed before metadata write out",
++ block_group->start);
++
+ set_bit(BLOCK_GROUP_FLAG_REMOVED, &block_group->runtime_flags);
+
+ /*
+@@ -1414,8 +1436,9 @@ void btrfs_delete_unused_bgs(struct btrf
+ * needing to allocate extents from the block group.
+ */
+ used = btrfs_space_info_used(space_info, true);
+- if (space_info->total_bytes - block_group->length < used &&
+- block_group->zone_unusable < block_group->length) {
++ if ((space_info->total_bytes - block_group->length < used &&
++ block_group->zone_unusable < block_group->length) ||
++ has_unwritten_metadata(block_group)) {
+ /*
+ * Add a reference for the list, compensate for the ref
+ * drop under the "next" label for the
--- /dev/null
+From 55f7c65b2f69c7e4cb7aa7c1654a228ccf734fd8 Mon Sep 17 00:00:00 2001
+From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Date: Tue, 20 May 2025 09:20:47 +0200
+Subject: btrfs: zoned: use filesystem size not disk size for reclaim decision
+
+From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+
+commit 55f7c65b2f69c7e4cb7aa7c1654a228ccf734fd8 upstream.
+
+When deciding if a zoned filesystem is reaching the threshold to reclaim
+data block groups, look at the size of the filesystem not to potentially
+total available size of all drives in the filesystem.
+
+Especially if a filesystem was created with mkfs' -b option, constraining
+it to only a portion of the block device, the numbers won't match and
+potentially garbage collection is kicking in too late.
+
+Fixes: 3687fcb0752a ("btrfs: zoned: make auto-reclaim less aggressive")
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/zoned.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -2229,8 +2229,8 @@ bool btrfs_zoned_should_reclaim(struct b
+ {
+ struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+ struct btrfs_device *device;
++ u64 total = btrfs_super_total_bytes(fs_info->super_copy);
+ u64 used = 0;
+- u64 total = 0;
+ u64 factor;
+
+ ASSERT(btrfs_is_zoned(fs_info));
+@@ -2243,7 +2243,6 @@ bool btrfs_zoned_should_reclaim(struct b
+ if (!device->bdev)
+ continue;
+
+- total += device->disk_total_bytes;
+ used += device->bytes_used;
+ }
+ mutex_unlock(&fs_devices->device_list_mutex);
--- /dev/null
+From 64690a90cd7c6db16d3af8616be1f4bf8d492850 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 17 Jul 2025 16:12:50 +0200
+Subject: cdc-acm: fix race between initial clearing halt and open
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 64690a90cd7c6db16d3af8616be1f4bf8d492850 upstream.
+
+On the devices that need their endpoints to get an
+initial clear_halt, this needs to be done before
+the devices can be opened. That means it needs to be
+before the devices are registered.
+
+Fixes: 15bf722e6f6c0 ("cdc-acm: Add support of ATOL FPrint fiscal printers")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20250717141259.2345605-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1496,6 +1496,12 @@ skip_countries:
+ goto err_remove_files;
+ }
+
++ if (quirks & CLEAR_HALT_CONDITIONS) {
++ /* errors intentionally ignored */
++ usb_clear_halt(usb_dev, acm->in);
++ usb_clear_halt(usb_dev, acm->out);
++ }
++
+ tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
+ &control_interface->dev);
+ if (IS_ERR(tty_dev)) {
+@@ -1503,11 +1509,6 @@ skip_countries:
+ goto err_release_data_interface;
+ }
+
+- if (quirks & CLEAR_HALT_CONDITIONS) {
+- usb_clear_halt(usb_dev, acm->in);
+- usb_clear_halt(usb_dev, acm->out);
+- }
+-
+ dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
+
+ return 0;
--- /dev/null
+From 35b6fc51c666fc96355be5cd633ed0fe4ccf68b2 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Tue, 22 Jul 2025 16:53:16 +0100
+Subject: comedi: fix race between polling and detaching
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 35b6fc51c666fc96355be5cd633ed0fe4ccf68b2 upstream.
+
+syzbot reports a use-after-free in comedi in the below link, which is
+due to comedi gladly removing the allocated async area even though poll
+requests are still active on the wait_queue_head inside of it. This can
+cause a use-after-free when the poll entries are later triggered or
+removed, as the memory for the wait_queue_head has been freed. We need
+to check there are no tasks queued on any of the subdevices' wait queues
+before allowing the device to be detached by the `COMEDI_DEVCONFIG`
+ioctl.
+
+Tasks will read-lock `dev->attach_lock` before adding themselves to the
+subdevice wait queue, so fix the problem in the `COMEDI_DEVCONFIG` ioctl
+handler by write-locking `dev->attach_lock` before checking that all of
+the subdevices are safe to be deleted. This includes testing for any
+sleepers on the subdevices' wait queues. It remains locked until the
+device has been detached. This requires the `comedi_device_detach()`
+function to be refactored slightly, moving the bulk of it into new
+function `comedi_device_detach_locked()`.
+
+Note that the refactor of `comedi_device_detach()` results in
+`comedi_device_cancel_all()` now being called while `dev->attach_lock`
+is write-locked, which wasn't the case previously, but that does not
+matter.
+
+Thanks to Jens Axboe for diagnosing the problem and co-developing this
+patch.
+
+Cc: stable <stable@kernel.org>
+Fixes: 2f3fdcd7ce93 ("staging: comedi: add rw_semaphore to protect against device detachment")
+Link: https://lore.kernel.org/all/687bd5fe.a70a0220.693ce.0091.GAE@google.com/
+Reported-by: syzbot+01523a0ae5600aef5895@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=01523a0ae5600aef5895
+Co-developed-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Tested-by: Jens Axboe <axboe@kernel.dk>
+Link: https://lore.kernel.org/r/20250722155316.27432-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/comedi/comedi_fops.c | 33 +++++++++++++++++++++++++--------
+ drivers/comedi/comedi_internal.h | 1 +
+ drivers/comedi/drivers.c | 13 ++++++++++---
+ 3 files changed, 36 insertions(+), 11 deletions(-)
+
+--- a/drivers/comedi/comedi_fops.c
++++ b/drivers/comedi/comedi_fops.c
+@@ -783,6 +783,7 @@ static int is_device_busy(struct comedi_
+ struct comedi_subdevice *s;
+ int i;
+
++ lockdep_assert_held_write(&dev->attach_lock);
+ lockdep_assert_held(&dev->mutex);
+ if (!dev->attached)
+ return 0;
+@@ -791,7 +792,16 @@ static int is_device_busy(struct comedi_
+ s = &dev->subdevices[i];
+ if (s->busy)
+ return 1;
+- if (s->async && comedi_buf_is_mmapped(s))
++ if (!s->async)
++ continue;
++ if (comedi_buf_is_mmapped(s))
++ return 1;
++ /*
++ * There may be tasks still waiting on the subdevice's wait
++ * queue, although they should already be about to be removed
++ * from it since the subdevice has no active async command.
++ */
++ if (wq_has_sleeper(&s->async->wait_head))
+ return 1;
+ }
+
+@@ -821,15 +831,22 @@ static int do_devconfig_ioctl(struct com
+ return -EPERM;
+
+ if (!arg) {
+- if (is_device_busy(dev))
+- return -EBUSY;
+- if (dev->attached) {
+- struct module *driver_module = dev->driver->module;
++ int rc = 0;
+
+- comedi_device_detach(dev);
+- module_put(driver_module);
++ if (dev->attached) {
++ down_write(&dev->attach_lock);
++ if (is_device_busy(dev)) {
++ rc = -EBUSY;
++ } else {
++ struct module *driver_module =
++ dev->driver->module;
++
++ comedi_device_detach_locked(dev);
++ module_put(driver_module);
++ }
++ up_write(&dev->attach_lock);
+ }
+- return 0;
++ return rc;
+ }
+
+ if (copy_from_user(&it, arg, sizeof(it)))
+--- a/drivers/comedi/comedi_internal.h
++++ b/drivers/comedi/comedi_internal.h
+@@ -50,6 +50,7 @@ extern struct mutex comedi_drivers_list_
+ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
++void comedi_device_detach_locked(struct comedi_device *dev);
+ void comedi_device_detach(struct comedi_device *dev);
+ int comedi_device_attach(struct comedi_device *dev,
+ struct comedi_devconfig *it);
+--- a/drivers/comedi/drivers.c
++++ b/drivers/comedi/drivers.c
+@@ -158,7 +158,7 @@ static void comedi_device_detach_cleanup
+ int i;
+ struct comedi_subdevice *s;
+
+- lockdep_assert_held(&dev->attach_lock);
++ lockdep_assert_held_write(&dev->attach_lock);
+ lockdep_assert_held(&dev->mutex);
+ if (dev->subdevices) {
+ for (i = 0; i < dev->n_subdevices; i++) {
+@@ -195,16 +195,23 @@ static void comedi_device_detach_cleanup
+ comedi_clear_hw_dev(dev);
+ }
+
+-void comedi_device_detach(struct comedi_device *dev)
++void comedi_device_detach_locked(struct comedi_device *dev)
+ {
++ lockdep_assert_held_write(&dev->attach_lock);
+ lockdep_assert_held(&dev->mutex);
+ comedi_device_cancel_all(dev);
+- down_write(&dev->attach_lock);
+ dev->attached = false;
+ dev->detach_count++;
+ if (dev->driver)
+ dev->driver->detach(dev);
+ comedi_device_detach_cleanup(dev);
++}
++
++void comedi_device_detach(struct comedi_device *dev)
++{
++ lockdep_assert_held(&dev->mutex);
++ down_write(&dev->attach_lock);
++ comedi_device_detach_locked(dev);
+ up_write(&dev->attach_lock);
+ }
+
usb-core-config-prevent-oob-read-in-ss-endpoint-companion-parsing.patch
misc-rtsx-usb-ensure-mmc-child-device-is-active-when-card-is-present.patch
usb-typec-ucsi-update-power_supply-on-power-role-change.patch
+comedi-fix-race-between-polling-and-detaching.patch
+thunderbolt-fix-copy-paste-error-in-match_service_id.patch
+cdc-acm-fix-race-between-initial-clearing-halt-and-open.patch
+btrfs-zoned-use-filesystem-size-not-disk-size-for-reclaim-decision.patch
+btrfs-abort-transaction-during-log-replay-if-walk_log_tree-failed.patch
+btrfs-zoned-do-not-remove-unwritten-non-data-block-group.patch
+btrfs-fix-log-tree-replay-failure-due-to-file-with-0-links-and-extents.patch
+btrfs-do-not-allow-relocation-of-partially-dropped-subvolumes.patch
--- /dev/null
+From 5cc1f66cb23cccc704e3def27ad31ed479e934a5 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sun, 20 Jul 2025 22:01:36 -0700
+Subject: thunderbolt: Fix copy+paste error in match_service_id()
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 5cc1f66cb23cccc704e3def27ad31ed479e934a5 upstream.
+
+The second instance of TBSVC_MATCH_PROTOCOL_VERSION seems to have been
+intended to be TBSVC_MATCH_PROTOCOL_REVISION.
+
+Fixes: d1ff70241a27 ("thunderbolt: Add support for XDomain discovery protocol")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Link: https://lore.kernel.org/r/20250721050136.30004-1-ebiggers@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/domain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thunderbolt/domain.c
++++ b/drivers/thunderbolt/domain.c
+@@ -36,7 +36,7 @@ static bool match_service_id(const struc
+ return false;
+ }
+
+- if (id->match_flags & TBSVC_MATCH_PROTOCOL_VERSION) {
++ if (id->match_flags & TBSVC_MATCH_PROTOCOL_REVISION) {
+ if (id->protocol_revision != svc->prtcrevs)
+ return false;
+ }