Patch "dm vdo vio-pool: allow variable-sized metadata vios" has been added to the 6.12-stable tree
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 7 lines · Sasha Levin
This is a note to let you know that I've just added the patch titled
dm vdo vio-pool: allow variable-sized metadata vios
to the 6.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
Quoted 6 lines
The filename of the patch is:
dm-vdo-vio-pool-allow-variable-sized-metadata-vios.patch
and it can be found in the queue-6.12 subdirectory.If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
There is no reason to pull this patch into 6.12 since there are no features in 6.12 that would use it.
Matt
Quoted 199 lines
commit
ac663217ac4eeab508db348a67511d45ccd9846fAuthor: Ken Raeburn <[email protected]> Date: Fri Jan 31 21:18:05 2025 -0500dm vdo vio-pool: allow variable-sized metadata vios
[ Upstream commit
f979da512553a41a657f2c1198277e84d66f8ce3]With larger-sized metadata vio pools, vdo will sometimes need to issue I/O with a smaller size than the allocated size. Since
vio_reset_biois where the bvec array and I/O size are initialized, this reset interface must now specify what I/O size to use.Signed-off-by Ken Raeburn <[email protected]>Signed-off-by Matthew Sakai <[email protected]>Signed-off-by Mikulas Patocka <[email protected]>Signed-off-by Sasha Levin <[email protected]>drivers/md/dm-vdo/io-submitter.c +4
-2@@ -327,6 +327,7 @@ void vdo_submit_data_vio(struct data_vio *data_vio)* @error_handler: the handler for submission or I/O errors (may be NULL) * @operation: the type of I/O to perform * @data: the buffer to read or write (may be NULL) +* @size: the I/O amount in bytes * * The vio is enqueued on a vdo bio queue so that bio submission (which may block) does not block * other vdo threads. @@ -338,7 +339,7 @@ void vdo_submit_data_vio(struct data_vio *data_vio)*/ void __submit_metadata_vio (struct vio *vio,physical_block_number_t physical,bio_end_io_t callback,vdo_action_fn error_handler, -blk_opf_t operation,char *data) +blk_opf_t operation,char *data,int size) {int result;struct vdo_completion *completion = &vio->completion;@@ -349,7 +350,8 @@ void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical,vdo_reset_completion (completion); completion->error_handler = error_handler; - result =vio_reset_bio (vio, data, callback, operation |REQ_META , physical); + result =vio_reset_bio_with_size (vio, data, size, callback, operation |REQ_META , + physical);if (result !=VDO_SUCCESS ) {continue_vio (vio, result);return ;drivers/md/dm-vdo/io-submitter.h +15
-3@@ -8,6 +8,7 @@#include <linux/bio.h> +#include "constants.h" #include "types.h" struct io_submitter ;@@ -26,14 +27,25 @@ void vdo_submit_data_vio(struct data_vio *data_vio);void __submit_metadata_vio (struct vio *vio,physical_block_number_t physical,bio_end_io_t callback,vdo_action_fn error_handler, -blk_opf_t operation,char *data); +blk_opf_t operation,char *data,int size);static inline void vdo_submit_metadata_vio (struct vio *vio,physical_block_number_t physical,bio_end_io_t callback,vdo_action_fn error_handler,blk_opf_t operation) {__submit_metadata_vio (vio, physical, callback, error_handler, - operation, vio->data); + operation, vio->data, vio->block_count *VDO_BLOCK_SIZE ); +} + +static inline void vdo_submit_metadata_vio_with_size (struct vio *vio, +physical_block_number_t physical, +bio_end_io_t callback, +vdo_action_fn error_handler, +blk_opf_t operation, +int size) +{ +__submit_metadata_vio (vio, physical, callback, error_handler, + operation, vio->data, size); } static inline void vdo_submit_flush_vio(struct vio *vio, bio_end_io_t callback,@@ -41,7 +53,7 @@ static inline void vdo_submit_flush_vio(struct vio *vio, bio_end_io_t callback, {/* FIXME: Can we just use REQ_OP_FLUSH? */ __submit_metadata_vio (vio,0 , callback, error_handler, -REQ_OP_WRITE |REQ_PREFLUSH ,NULL ); +REQ_OP_WRITE |REQ_PREFLUSH ,NULL ,0 ); }#endif /* VDO_IO_SUBMITTER_H */ drivers/md/dm-vdo/types.h +3
-0@@ -376,6 +376,9 @@ struct vio {/* The size of this vio in blocks */ unsigned int block_count; +/* The amount of data to be read or written, in bytes */ +unsigned int io_size; +/* The data being read or written. */ char *data;drivers/md/dm-vdo/vio.c +22
-14@@ -188,14 +188,23 @@ void vdo_set_bio_properties(struct bio *bio, struct vio *vio, bio_end_io_t callb/* * Prepares the bio to perform IO with the specified buffer. May only be used on a VDO-allocated -* bio, as it assumes the bio wraps a 4k buffer that is 4k aligned, but there does not have to be a -* vio associated with the bio. +* bio, as it assumes the bio wraps a 4k-multiple buffer that is 4k aligned, but there does not +* have to be a vio associated with the bio. */ int vio_reset_bio (struct vio *vio,char *data,bio_end_io_t callback,blk_opf_t bi_opf,physical_block_number_t pbn) { -int bvec_count, offset, len, i; +return vio_reset_bio_with_size (vio, data, vio->block_count *VDO_BLOCK_SIZE , + callback, bi_opf, pbn); +} + +int vio_reset_bio_with_size (struct vio *vio,char *data,int size,bio_end_io_t callback, +blk_opf_t bi_opf,physical_block_number_t pbn) +{ +int bvec_count, offset, i;struct bio *bio = vio->bio; +int vio_size = vio->block_count *VDO_BLOCK_SIZE ; +int remaining;bio_reset (bio, bio->bi_bdev, bi_opf);vdo_set_bio_properties (bio, vio, callback, bi_opf, pbn);@@ -204,22 +213,21 @@ int vio_reset_bio(struct vio *vio, char *data, bio_end_io_t callback, bio->bi_io_vec = bio->bi_inline_vecs; bio->bi_max_vecs = vio->block_count +1 ; - len =VDO_BLOCK_SIZE * vio->block_count; +if (VDO_ASSERT (size <= vio_size,"specified size %d is not greater than allocated %d" , + size, vio_size) !=VDO_SUCCESS ) + size = vio_size; + vio->io_size = size; offset =offset_in_page (data); - bvec_count =DIV_ROUND_UP (offset + len,PAGE_SIZE ); + bvec_count =DIV_ROUND_UP (offset + size,PAGE_SIZE ); + remaining = size; -/* -* If we knew that data was always on one page, or contiguous pages, we wouldn't need the -* loop. But if we're using vmalloc, it's not impossible that the data is in different -* pages that can't be merged in bio_add_page... -*/ -for (i =0 ; (i < bvec_count) && (len >0 ); i++) { +for (i =0 ; (i < bvec_count) && (remaining >0 ); i++) {struct page *page;int bytes_added;int bytes =PAGE_SIZE - offset; -if (bytes > len) - bytes = len; +if (bytes > remaining) + bytes = remaining; page =is_vmalloc_addr (data) ?vmalloc_to_page (data) :virt_to_page (data); bytes_added =bio_add_page (bio, page, bytes, offset);@@ -231,7 +239,7 @@ int vio_reset_bio(struct vio *vio, char *data, bio_end_io_t callback, } data += bytes; - len -= bytes; + remaining -= bytes; offset =0 ; }drivers/md/dm-vdo/vio.h +2
-0@@ -123,6 +123,8 @@ void vdo_set_bio_properties(struct bio *bio, struct vio *vio, bio_end_io_t callbint vio_reset_bio (struct vio *vio,char *data,bio_end_io_t callback,blk_opf_t bi_opf,physical_block_number_t pbn); +int vio_reset_bio_with_size (struct vio *vio,char *data,int size,bio_end_io_t callback, +blk_opf_t bi_opf,physical_block_number_t pbn); void update_vio_error_stats(struct vio *vio, const char *format, ...) __printf(2, 3);