Skip to contentSkip to conversation

FAILED: patch "[PATCH] block: set QUEUE_FLAG_DYING unconditionally in" failed to apply to 6.1-stable tree

PATCH New [email protected] 2 participants 5 messages Sep 3 – Sep 8

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 7e9a46004b471eaf69b082c473d865316a4158e0
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090327-engross-lapped-120b@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 7e9a46004b471eaf69b082c473d865316a4158e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=83=A1=E8=BF=9E=E5=8B=A4?= <[email protected]>
Date: Wed, 12 Aug 2026 11:59:04 +0000
Subject: [PATCH] block: set QUEUE_FLAG_DYING unconditionally in
blk_mark_disk_dead()

Disks created via blk_mq_alloc_disk_for_queue() (e.g. SCSI SD disks) do not have GD_OWNS_QUEUE set. Currently __blk_mark_disk_dead() only sets QUEUE_FLAG_DYING when GD_OWNS_QUEUE is set, so for such disks blk_queue_enter() and __bio_queue_enter() cannot detect the dying state via blk_queue_dying() and remain blocked waiting for I/O that will never complete after surprise removal.

blk_mark_disk_dead() is the explicit "surprise removal" API -- the caller has already decided the disk is dead. Setting QUEUE_FLAG_DYING unconditionally here is appropriate: any in-flight I/O from other threads should get -ENODEV immediately from blk_queue_enter() regardless of GD_OWNS_QUEUE ownership.

For disks that already have GD_OWNS_QUEUE set, __blk_mark_disk_dead() will set the flag again which is harmless.

block/genhd.c +1 -0
index df2c3c69b467..7b089e2d52c4 100644
@@ -681,6 +681,7 @@ static bool __blk_mark_disk_dead(struct gendisk *disk)
  */
 void blk_mark_disk_dead(struct gendisk *disk)
 {
+	blk_queue_flag_set(QUEUE_FLAG_DYING, disk->queue);
 	__blk_mark_disk_dead(disk);
 	blk_report_disk_dead(disk, true);
 }
maintainer
#1 lore raw

PATCH 1/4 block: simplify the disk_force_media_change interface

From: Christoph Hellwig <[email protected]>

[ Upstream commit ab6860f62bfe329e11e5b5b7295b673c9c3a62d0 ]

Hard code the events to DISK_EVENT_MEDIA_CHANGE as that is the only useful use case, and drop the superfluous return value.

Message-Id: <[email protected]>

Stable-dep-of: 7e9a46004b47 ("block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()")

---
 block/disk-events.c    | 15 ++++-----------
 drivers/block/loop.c   |  6 +++---
 include/linux/blkdev.h |  2 +-
 3 files changed, 8 insertions(+), 15 deletions(-)
block/disk-events.c +4 -11
index 450c2cbe23d56..c25b67c190a6c 100644
@@ -294,25 +294,18 @@ EXPORT_SYMBOL(bdev_check_media_change);
  * @disk: the disk which will raise the event
  * @events: the events to raise
  *
- * Generate uevents for the disk. If DISK_EVENT_MEDIA_CHANGE is present,
- * attempt to free all dentries and inodes and invalidates all block
+ * Should be called when the media changes for @disk.  Generates a uevent
+ * and attempts to free all dentries and inodes and invalidates all block
  * device page cache entries in that case.
- *
- * Returns %true if DISK_EVENT_MEDIA_CHANGE was raised, or %false if not.
  */
-bool disk_force_media_change(struct gendisk *disk, unsigned int events)
+void disk_force_media_change(struct gendisk *disk)
 {
-	disk_event_uevent(disk, events);
-
-	if (!(events & DISK_EVENT_MEDIA_CHANGE))
-		return false;
-
+	disk_event_uevent(disk, DISK_EVENT_MEDIA_CHANGE);
 	inc_diskseq(disk);
 	if (__invalidate_device(disk->part0, true))
 		pr_warn("VFS: busy inodes on changed media %s\n",
 			disk->disk_name);
 	set_bit(GD_NEED_PART_SCAN, &disk->state);
-	return true;
 }
 EXPORT_SYMBOL_GPL(disk_force_media_change);
 
drivers/block/loop.c +3 -3
index e3e5d533a7eca..a12a67947c682 100644
@@ -598,7 +598,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
 		goto out_err;
 
 	/* and ... switch */
-	disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
+	disk_force_media_change(lo->lo_disk);
 	blk_mq_freeze_queue(lo->lo_queue);
 	mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
 	lo->lo_backing_file = file;
@@ -1063,7 +1063,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
 	/* suppress uevents while reconfiguring the device */
 	dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1);
 
-	disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
+	disk_force_media_change(lo->lo_disk);
 	set_disk_ro(lo->lo_disk, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0);
 
 	lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO;
@@ -1167,7 +1167,7 @@ static void __loop_clr_fd(struct loop_device *lo, bool release)
 	if (!release)
 		blk_mq_unfreeze_queue(lo->lo_queue);
 
-	disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
+	disk_force_media_change(lo->lo_disk);
 
 	if (lo->lo_flags & LO_FLAGS_PARTSCAN) {
 		int err;
include/linux/blkdev.h +1 -1
index de013fc37ef83..e57b6e77b3757 100644
@@ -773,7 +773,7 @@ static inline int bdev_read_only(struct block_device *bdev)
 }
 
 bool set_capacity_and_notify(struct gendisk *disk, sector_t size);
-bool disk_force_media_change(struct gendisk *disk, unsigned int events);
+void disk_force_media_change(struct gendisk *disk);
 
 void add_disk_randomness(struct gendisk *disk) __latent_entropy;
 void rand_initialize_disk(struct gendisk *disk);
Signature · 1 line
2.53.0
maintainer
#2 lore raw

PATCH 2/4 dasd: also call __invalidate_device when setting the device offline

From: Christoph Hellwig <[email protected]>

[ Upstream commit 2527fd38772fea30c1d1cbf94839a0bbf4122133 ]

Don't just write out the data, but also invalidate all caches when setting the device offline. Stop canceling the offlining when writeback fails as there is no way to recover from that anyway.

Message-Id: <[email protected]>

Stable-dep-of: 7e9a46004b47 ("block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()")

---
 drivers/s390/block/dasd.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/s390/block/dasd.c +2 -3
index 4250671e4400d..591b6cd934aaa 100644
@@ -3628,9 +3628,8 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
 		 * empty
 		 */
 		if (device->block) {
-			rc = fsync_bdev(device->block->bdev);
-			if (rc != 0)
-				goto interrupted;
+			fsync_bdev(device->block->bdev);
+			__invalidate_device(device->block->bdev, true);
 		}
 		dasd_schedule_device_bh(device);
 		rc = wait_event_interruptible(shutdown_waitq,
Signature · 1 line
2.53.0
maintainer
#3 lore raw

PATCH 3/4 block: drop the "busy inodes on changed media" log message

In reply to Sasha Levin

From: Christoph Hellwig <[email protected]>

[ Upstream commit 127a5093c79d9cdea9e6edc016ab346e6dd16c23 ]

This message isn't exactly helpful, and file systems already print way more useful messages when shut down while active.

Message-Id: <[email protected]>

Stable-dep-of: 7e9a46004b47 ("block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()")

---
 block/disk-events.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
block/disk-events.c +2 -6
index c25b67c190a6c..d44f6b6aca3d8 100644
@@ -281,9 +281,7 @@ bool bdev_check_media_change(struct block_device *bdev)
 	if (!(events & DISK_EVENT_MEDIA_CHANGE))
 		return false;
 
-	if (__invalidate_device(bdev, true))
-		pr_warn("VFS: busy inodes on changed media %s\n",
-			bdev->bd_disk->disk_name);
+	__invalidate_device(bdev, true);
 	set_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state);
 	return true;
 }
@@ -302,9 +300,7 @@ void disk_force_media_change(struct gendisk *disk)
 {
 	disk_event_uevent(disk, DISK_EVENT_MEDIA_CHANGE);
 	inc_diskseq(disk);
-	if (__invalidate_device(disk->part0, true))
-		pr_warn("VFS: busy inodes on changed media %s\n",
-			disk->disk_name);
+	__invalidate_device(disk->part0, true);
 	set_bit(GD_NEED_PART_SCAN, &disk->state);
 }
 EXPORT_SYMBOL_GPL(disk_force_media_change);
Signature · 1 line
2.53.0
maintainer
#4 lore raw

PATCH 4/4 block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()

In reply to Sasha Levin

From: 胡连勤 <[email protected]>

[ Upstream commit 7e9a46004b471eaf69b082c473d865316a4158e0 ]

Disks created via blk_mq_alloc_disk_for_queue() (e.g. SCSI SD disks) do not have GD_OWNS_QUEUE set. Currently __blk_mark_disk_dead() only sets QUEUE_FLAG_DYING when GD_OWNS_QUEUE is set, so for such disks blk_queue_enter() and __bio_queue_enter() cannot detect the dying state via blk_queue_dying() and remain blocked waiting for I/O that will never complete after surprise removal.

blk_mark_disk_dead() is the explicit "surprise removal" API -- the caller has already decided the disk is dead. Setting QUEUE_FLAG_DYING unconditionally here is appropriate: any in-flight I/O from other threads should get -ENODEV immediately from blk_queue_enter() regardless of GD_OWNS_QUEUE ownership.

For disks that already have GD_OWNS_QUEUE set, __blk_mark_disk_dead() will set the flag again which is harmless.

Fixes 6f8191fdf41d ("block: simplify disk shutdown")
[ adapted the newer helper-based implementation to the existing 6.1 function body. ]
---
 block/genhd.c | 1 +
 1 file changed, 1 insertion(+)
block/genhd.c +1 -0
index c058a01c1b3a1..753dfa846e3ea 100644
@@ -585,6 +585,7 @@ EXPORT_SYMBOL(device_add_disk);
  */
 void blk_mark_disk_dead(struct gendisk *disk)
 {
+	blk_queue_flag_set(QUEUE_FLAG_DYING, disk->queue);
 	set_bit(GD_DEAD, &disk->state);
 	blk_queue_start_drain(disk->queue);
 }
Signature · 1 line
2.53.0