Commit 9d9c28aa authored by Bruce Johnston's avatar Bruce Johnston Committed by Mikulas Patocka
Browse files

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: default avatarBruce Johnston <bjohnsto@redhat.com>
Reviewed-by: default avatarMatthew Sakai <msakai@redhat.com>
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
parent b5d1f45c
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -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.
+4 −0
Original line number Diff line number Diff line
@@ -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 */
+3 −13
Original line number Diff line number Diff line
@@ -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,