summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-vdo/io-submitter.c27
-rw-r--r--drivers/md/dm-vdo/io-submitter.h4
-rw-r--r--drivers/md/dm-vdo/vdo.c16
3 files changed, 34 insertions, 13 deletions
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
@@ -365,6 +365,33 @@ void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical,
}
/**
+ * 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.
* @rotation_interval: Interval to use when rotating between bio-submission threads when enqueuing
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,