]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dm vdo: add synchronous metadata I/O submission helper
authorBruce Johnston <bjohnsto@redhat.com>
Tue, 24 Mar 2026 18:06:50 +0000 (14:06 -0400)
committerMikulas Patocka <mpatocka@redhat.com>
Thu, 26 Mar 2026 17:19:05 +0000 (18:19 +0100)
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 <bjohnsto@redhat.com>
Reviewed-by: Matthew Sakai <msakai@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
drivers/md/dm-vdo/io-submitter.c
drivers/md/dm-vdo/io-submitter.h
drivers/md/dm-vdo/vdo.c

index 0e9932929fee70b5ad0814d4da53195489022a0e..0916c86095432b791cb1c5087b2b08d3b921cbdd 100644 (file)
@@ -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.
index 3088f11055fdd1c42aee86c9005af34d9afe07da..0f320a60e9e8423ffc8143fe25d3cbb9ac061ccb 100644 (file)
@@ -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 */
index 09a1a97b5c3128cedd739ed21adaae2aa50a6bd2..bc7afbca035db83de3c85c266f152c350d1d012d 100644 (file)
@@ -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,