From: Bruce Johnston Date: Tue, 24 Mar 2026 18:06:50 +0000 (-0400) Subject: dm vdo: add synchronous metadata I/O submission helper X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d9c28aa867ae3ffdd967a8caeb4e3fb6d4003cd;p=thirdparty%2Fkernel%2Fstable.git dm vdo: add synchronous metadata I/O submission helper Add vdo_submit_metadata_vio_wait(), a synchronous I/O submission helper that blocks until completion. This is needed for I/O during early initialization before work queues are available. Refactor read_geometry_block() to use it. Signed-off-by: Bruce Johnston Reviewed-by: Matthew Sakai Signed-off-by: Mikulas Patocka --- diff --git a/drivers/md/dm-vdo/io-submitter.c b/drivers/md/dm-vdo/io-submitter.c index 0e9932929fee..0916c8609543 100644 --- a/drivers/md/dm-vdo/io-submitter.c +++ b/drivers/md/dm-vdo/io-submitter.c @@ -364,6 +364,33 @@ void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical, vdo_launch_completion_with_priority(completion, get_metadata_priority(vio)); } +/** + * vdo_submit_metadata_vio_wait() - Submit I/O for a metadata vio and wait for completion. + * @vio: the vio for which to issue I/O + * @physical: the physical block number to read or write + * @operation: the type of I/O to perform + * + * The function operates similarly to __submit_metadata_vio except that it will + * block until the work is done. It can be used to do i/o before work queues + * and thread completions are set up. + * + * Return: VDO_SUCCESS or an error. + */ +int vdo_submit_metadata_vio_wait(struct vio *vio, + physical_block_number_t physical, + blk_opf_t operation) +{ + int result; + + result = vio_reset_bio(vio, vio->data, NULL, operation | REQ_META, physical); + if (result != VDO_SUCCESS) + return result; + + bio_set_dev(vio->bio, vdo_get_backing_device(vio->completion.vdo)); + submit_bio_wait(vio->bio); + return blk_status_to_errno(vio->bio->bi_status); +} + /** * vdo_make_io_submitter() - Create an io_submitter structure. * @thread_count: Number of bio-submission threads to set up. diff --git a/drivers/md/dm-vdo/io-submitter.h b/drivers/md/dm-vdo/io-submitter.h index 3088f11055fd..0f320a60e9e8 100644 --- a/drivers/md/dm-vdo/io-submitter.h +++ b/drivers/md/dm-vdo/io-submitter.h @@ -56,4 +56,8 @@ static inline void vdo_submit_flush_vio(struct vio *vio, bio_end_io_t callback, REQ_OP_WRITE | REQ_PREFLUSH, NULL, 0); } +int vdo_submit_metadata_vio_wait(struct vio *vio, + physical_block_number_t physical, + blk_opf_t operation); + #endif /* VDO_IO_SUBMITTER_H */ diff --git a/drivers/md/dm-vdo/vdo.c b/drivers/md/dm-vdo/vdo.c index 09a1a97b5c31..bc7afbca035d 100644 --- a/drivers/md/dm-vdo/vdo.c +++ b/drivers/md/dm-vdo/vdo.c @@ -295,8 +295,6 @@ static int initialize_super_block(struct vdo *vdo, struct vdo_super_block *super */ static int __must_check read_geometry_block(struct vdo *vdo) { - struct vio *vio = &vdo->geometry_block.vio; - u8 *block = vdo->geometry_block.buffer; int result; /* @@ -304,20 +302,12 @@ static int __must_check read_geometry_block(struct vdo *vdo) * bio_offset field is 0, so the fact that vio_reset_bio() will subtract that offset from * the supplied pbn is not a problem. */ - result = vio_reset_bio(vio, (char *)block, NULL, REQ_OP_READ, - VDO_GEOMETRY_BLOCK_LOCATION); + result = vdo_submit_metadata_vio_wait(&vdo->geometry_block.vio, + VDO_GEOMETRY_BLOCK_LOCATION, REQ_OP_READ); if (result != VDO_SUCCESS) return result; - bio_set_dev(vio->bio, vdo_get_backing_device(vdo)); - submit_bio_wait(vio->bio); - result = blk_status_to_errno(vio->bio->bi_status); - if (result != 0) { - vdo_log_error_strerror(result, "synchronous read failed"); - return -EIO; - } - - return vdo_parse_geometry_block(block, &vdo->geometry); + return vdo_parse_geometry_block(vdo->geometry_block.buffer, &vdo->geometry); } static bool get_zone_thread_name(const thread_id_t thread_ids[], zone_count_t count,