Skip to content

Commit 9d9c28a

Browse files
bjohnstoMikulas Patocka
authored andcommitted
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 <bjohnsto@redhat.com> Reviewed-by: Matthew Sakai <msakai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
1 parent b5d1f45 commit 9d9c28a

3 files changed

Lines changed: 34 additions & 13 deletions

File tree

drivers/md/dm-vdo/io-submitter.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,33 @@ void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical,
364364
vdo_launch_completion_with_priority(completion, get_metadata_priority(vio));
365365
}
366366

367+
/**
368+
* vdo_submit_metadata_vio_wait() - Submit I/O for a metadata vio and wait for completion.
369+
* @vio: the vio for which to issue I/O
370+
* @physical: the physical block number to read or write
371+
* @operation: the type of I/O to perform
372+
*
373+
* The function operates similarly to __submit_metadata_vio except that it will
374+
* block until the work is done. It can be used to do i/o before work queues
375+
* and thread completions are set up.
376+
*
377+
* Return: VDO_SUCCESS or an error.
378+
*/
379+
int vdo_submit_metadata_vio_wait(struct vio *vio,
380+
physical_block_number_t physical,
381+
blk_opf_t operation)
382+
{
383+
int result;
384+
385+
result = vio_reset_bio(vio, vio->data, NULL, operation | REQ_META, physical);
386+
if (result != VDO_SUCCESS)
387+
return result;
388+
389+
bio_set_dev(vio->bio, vdo_get_backing_device(vio->completion.vdo));
390+
submit_bio_wait(vio->bio);
391+
return blk_status_to_errno(vio->bio->bi_status);
392+
}
393+
367394
/**
368395
* vdo_make_io_submitter() - Create an io_submitter structure.
369396
* @thread_count: Number of bio-submission threads to set up.

drivers/md/dm-vdo/io-submitter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,8 @@ static inline void vdo_submit_flush_vio(struct vio *vio, bio_end_io_t callback,
5656
REQ_OP_WRITE | REQ_PREFLUSH, NULL, 0);
5757
}
5858

59+
int vdo_submit_metadata_vio_wait(struct vio *vio,
60+
physical_block_number_t physical,
61+
blk_opf_t operation);
62+
5963
#endif /* VDO_IO_SUBMITTER_H */

drivers/md/dm-vdo/vdo.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -295,29 +295,19 @@ static int initialize_super_block(struct vdo *vdo, struct vdo_super_block *super
295295
*/
296296
static int __must_check read_geometry_block(struct vdo *vdo)
297297
{
298-
struct vio *vio = &vdo->geometry_block.vio;
299-
u8 *block = vdo->geometry_block.buffer;
300298
int result;
301299

302300
/*
303301
* This is only safe because, having not already loaded the geometry, the vdo's geometry's
304302
* bio_offset field is 0, so the fact that vio_reset_bio() will subtract that offset from
305303
* the supplied pbn is not a problem.
306304
*/
307-
result = vio_reset_bio(vio, (char *)block, NULL, REQ_OP_READ,
308-
VDO_GEOMETRY_BLOCK_LOCATION);
305+
result = vdo_submit_metadata_vio_wait(&vdo->geometry_block.vio,
306+
VDO_GEOMETRY_BLOCK_LOCATION, REQ_OP_READ);
309307
if (result != VDO_SUCCESS)
310308
return result;
311309

312-
bio_set_dev(vio->bio, vdo_get_backing_device(vdo));
313-
submit_bio_wait(vio->bio);
314-
result = blk_status_to_errno(vio->bio->bi_status);
315-
if (result != 0) {
316-
vdo_log_error_strerror(result, "synchronous read failed");
317-
return -EIO;
318-
}
319-
320-
return vdo_parse_geometry_block(block, &vdo->geometry);
310+
return vdo_parse_geometry_block(vdo->geometry_block.buffer, &vdo->geometry);
321311
}
322312

323313
static bool get_zone_thread_name(const thread_id_t thread_ids[], zone_count_t count,

0 commit comments

Comments
 (0)