[PATCH 1/2] block: allow write streams on partitions
From: Keoseong Park <hidden>
Date: 2026-09-11 06:47:30
Also in:
lkml
Subsystem:
block layer, the rest · Maintainers:
Jens Axboe, Linus Torvalds
bdev_max_write_streams() returns 0 for partitions, so nothing on top of a partition can use write streams. Passing the disk's streams through would not be correct either: two partitions sharing a stream would put unrelated data into the same reclaim unit. Give each partition its own subset of the disk's write streams, kept in a per-partition map in struct block_device. bdev_max_write_streams() reports the partition's count, so existing users work with partition-relative stream numbers (1..count), and blk_partition_remap() translates them to disk streams like it remaps sectors. Only REQ_OP_WRITE bios are translated, as that is the only operation that consumes a write stream. A write with a stream beyond the partition's count fails the bio; blkdev_direct_IO() rejects those before submission, so this only catches in-kernel submitters. Nothing assigns streams to partitions yet, so there is no functional change. The idea of translating the stream in blk_partition_remap() is from an earlier patch by Christoph Hellwig, which assigned a contiguous range of streams to each partition instead of a map. Link: https://lore.kernel.org/all/20241119121632.1225556-16-hch@lst.de/ (local) Signed-off-by: Keoseong Park <redacted> --- block/bdev.c | 1 + block/blk-core.c | 10 +++++++++- include/linux/blk_types.h | 3 +++ include/linux/blkdev.h | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c
index cd8323083740..7306a4ef0a86 100644
--- a/block/bdev.c
+++ b/block/bdev.c@@ -438,6 +438,7 @@ static void bdev_free_inode(struct inode *inode) free_percpu(bdev->bd_stats); kfree(bdev->bd_meta_info); + kfree(bdev->bd_write_stream_map); security_bdev_free(bdev); if (!bdev_is_partition(bdev)) {
diff --git a/block/blk-core.c b/block/blk-core.c
index 196bccf27f58..3b6f09b3943f 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c@@ -616,7 +616,8 @@ static inline int bio_check_eod(struct bio *bio) } /* - * Remap block n of partition p to block n+start(p) of the disk. + * Remap block n of partition p to block n+start(p) of the disk, and the + * write streams of partition p to the disk write streams reserved for them. */ static int blk_partition_remap(struct bio *bio) {
@@ -630,6 +631,13 @@ static int blk_partition_remap(struct bio *bio) bio->bi_iter.bi_sector - p->bd_start_sect); } + if (bio->bi_write_stream && bio_op(bio) == REQ_OP_WRITE) { + if (unlikely(bio->bi_write_stream > p->bd_nr_write_streams)) + return -EINVAL; + + bio->bi_write_stream = + p->bd_write_stream_map[bio->bi_write_stream - 1]; + } bio_set_flag(bio, BIO_REMAPPED); return 0; }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 98e21b4cbf32..0bbfa2708099 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h@@ -71,6 +71,9 @@ struct block_device { struct partition_meta_info *bd_meta_info; int bd_writers; + /* partition write stream s is disk stream bd_write_stream_map[s - 1] */ + u8 bd_nr_write_streams; + u8 *bd_write_stream_map; #ifdef CONFIG_SECURITY void *bd_security; #endif
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4f7905c3412b..686ed60a0bb7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h@@ -1303,7 +1303,7 @@ static inline unsigned int bdev_max_segments(struct block_device *bdev) static inline unsigned short bdev_max_write_streams(struct block_device *bdev) { if (bdev_is_partition(bdev)) - return 0; + return bdev->bd_nr_write_streams; return bdev_limits(bdev)->max_write_streams; }
--
2.43.0