Skip to content

Commit b5d1f45

Browse files
bjohnstoMikulas Patocka
authored andcommitted
dm vdo: add geometry block structure
Introduce a vdo_geometry_block structure, containing a vio and buffer, mirroring the existing vdo_super_block structure. Both are now initialized at VDO startup and freed at shutdown, establishing the infrastructure needed to read and write the geometry block using the same mechanisms as the super block. Refactor read_geometry_block() to use the new structure. 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 427bf2c commit b5d1f45

2 files changed

Lines changed: 66 additions & 45 deletions

File tree

drivers/md/dm-vdo/vdo.c

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,37 @@ static int __must_check initialize_thread_config(struct thread_count_config coun
255255
return VDO_SUCCESS;
256256
}
257257

258+
static int initialize_geometry_block(struct vdo *vdo,
259+
struct vdo_geometry_block *geometry_block)
260+
{
261+
int result;
262+
263+
result = vdo_allocate(VDO_BLOCK_SIZE, "encoded geometry block",
264+
(char **) &vdo->geometry_block.buffer);
265+
if (result != VDO_SUCCESS)
266+
return result;
267+
268+
return allocate_vio_components(vdo, VIO_TYPE_GEOMETRY,
269+
VIO_PRIORITY_METADATA, NULL, 1,
270+
(char *) geometry_block->buffer,
271+
&vdo->geometry_block.vio);
272+
}
273+
274+
static int initialize_super_block(struct vdo *vdo, struct vdo_super_block *super_block)
275+
{
276+
int result;
277+
278+
result = vdo_allocate(VDO_BLOCK_SIZE, "encoded super block",
279+
(char **) &vdo->super_block.buffer);
280+
if (result != VDO_SUCCESS)
281+
return result;
282+
283+
return allocate_vio_components(vdo, VIO_TYPE_SUPER_BLOCK,
284+
VIO_PRIORITY_METADATA, NULL, 1,
285+
(char *) super_block->buffer,
286+
&vdo->super_block.vio);
287+
}
288+
258289
/**
259290
* read_geometry_block() - Synchronously read the geometry block from a vdo's underlying block
260291
* device.
@@ -264,47 +295,29 @@ static int __must_check initialize_thread_config(struct thread_count_config coun
264295
*/
265296
static int __must_check read_geometry_block(struct vdo *vdo)
266297
{
267-
struct vio *vio;
268-
char *block;
298+
struct vio *vio = &vdo->geometry_block.vio;
299+
u8 *block = vdo->geometry_block.buffer;
269300
int result;
270301

271-
result = vdo_allocate(VDO_BLOCK_SIZE, __func__, &block);
272-
if (result != VDO_SUCCESS)
273-
return result;
274-
275-
result = create_metadata_vio(vdo, VIO_TYPE_GEOMETRY, VIO_PRIORITY_HIGH, NULL,
276-
block, &vio);
277-
if (result != VDO_SUCCESS) {
278-
vdo_free(block);
279-
return result;
280-
}
281-
282302
/*
283303
* This is only safe because, having not already loaded the geometry, the vdo's geometry's
284304
* bio_offset field is 0, so the fact that vio_reset_bio() will subtract that offset from
285305
* the supplied pbn is not a problem.
286306
*/
287-
result = vio_reset_bio(vio, block, NULL, REQ_OP_READ,
307+
result = vio_reset_bio(vio, (char *)block, NULL, REQ_OP_READ,
288308
VDO_GEOMETRY_BLOCK_LOCATION);
289-
if (result != VDO_SUCCESS) {
290-
free_vio(vdo_forget(vio));
291-
vdo_free(block);
309+
if (result != VDO_SUCCESS)
292310
return result;
293-
}
294311

295312
bio_set_dev(vio->bio, vdo_get_backing_device(vdo));
296313
submit_bio_wait(vio->bio);
297314
result = blk_status_to_errno(vio->bio->bi_status);
298-
free_vio(vdo_forget(vio));
299315
if (result != 0) {
300316
vdo_log_error_strerror(result, "synchronous read failed");
301-
vdo_free(block);
302317
return -EIO;
303318
}
304319

305-
result = vdo_parse_geometry_block((u8 *) block, &vdo->geometry);
306-
vdo_free(block);
307-
return result;
320+
return vdo_parse_geometry_block(block, &vdo->geometry);
308321
}
309322

310323
static bool get_zone_thread_name(const thread_id_t thread_ids[], zone_count_t count,
@@ -474,6 +487,19 @@ static int initialize_vdo(struct vdo *vdo, struct device_config *config,
474487
vdo_initialize_completion(&vdo->admin.completion, vdo, VDO_ADMIN_COMPLETION);
475488
init_completion(&vdo->admin.callback_sync);
476489
mutex_init(&vdo->stats_mutex);
490+
491+
result = initialize_geometry_block(vdo, &vdo->geometry_block);
492+
if (result != VDO_SUCCESS) {
493+
*reason = "Could not initialize geometry block";
494+
return result;
495+
}
496+
497+
result = initialize_super_block(vdo, &vdo->super_block);
498+
if (result != VDO_SUCCESS) {
499+
*reason = "Could not initialize super block";
500+
return result;
501+
}
502+
477503
result = read_geometry_block(vdo);
478504
if (result != VDO_SUCCESS) {
479505
*reason = "Could not load geometry block";
@@ -646,6 +672,12 @@ static void free_listeners(struct vdo_thread *thread)
646672
}
647673
}
648674

675+
static void uninitialize_geometry_block(struct vdo_geometry_block *geometry_block)
676+
{
677+
free_vio_components(&geometry_block->vio);
678+
vdo_free(geometry_block->buffer);
679+
}
680+
649681
static void uninitialize_super_block(struct vdo_super_block *super_block)
650682
{
651683
free_vio_components(&super_block->vio);
@@ -693,6 +725,7 @@ void vdo_destroy(struct vdo *vdo)
693725
vdo_uninitialize_layout(&vdo->next_layout);
694726
if (vdo->partition_copier)
695727
dm_kcopyd_client_destroy(vdo_forget(vdo->partition_copier));
728+
uninitialize_geometry_block(&vdo->geometry_block);
696729
uninitialize_super_block(&vdo->super_block);
697730
vdo_free_block_map(vdo_forget(vdo->block_map));
698731
vdo_free_hash_zones(vdo_forget(vdo->hash_zones));
@@ -718,20 +751,6 @@ void vdo_destroy(struct vdo *vdo)
718751
vdo_free(vdo);
719752
}
720753

721-
static int initialize_super_block(struct vdo *vdo, struct vdo_super_block *super_block)
722-
{
723-
int result;
724-
725-
result = vdo_allocate(VDO_BLOCK_SIZE, "encoded super block", &vdo->super_block.buffer);
726-
if (result != VDO_SUCCESS)
727-
return result;
728-
729-
return allocate_vio_components(vdo, VIO_TYPE_SUPER_BLOCK,
730-
VIO_PRIORITY_METADATA, NULL, 1,
731-
(char *) super_block->buffer,
732-
&vdo->super_block.vio);
733-
}
734-
735754
/**
736755
* finish_reading_super_block() - Continue after loading the super block.
737756
* @completion: The super block vio.
@@ -775,14 +794,6 @@ static void read_super_block_endio(struct bio *bio)
775794
*/
776795
void vdo_load_super_block(struct vdo *vdo, struct vdo_completion *parent)
777796
{
778-
int result;
779-
780-
result = initialize_super_block(vdo, &vdo->super_block);
781-
if (result != VDO_SUCCESS) {
782-
vdo_continue_completion(parent, result);
783-
return;
784-
}
785-
786797
vdo->super_block.vio.completion.parent = parent;
787798
vdo_submit_metadata_vio(&vdo->super_block.vio,
788799
vdo_get_data_region_start(vdo->geometry),

drivers/md/dm-vdo/vdo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ struct thread_config {
144144

145145
struct thread_count_config;
146146

147+
struct vdo_geometry_block {
148+
/* The vio for reading and writing the geometry block to disk */
149+
struct vio vio;
150+
/* A buffer to hold the geometry block */
151+
u8 *buffer;
152+
};
153+
147154
struct vdo_super_block {
148155
/* The vio for reading and writing the super block to disk */
149156
struct vio vio;
@@ -186,6 +193,9 @@ struct vdo {
186193
/* The thread mapping */
187194
struct thread_config thread_config;
188195

196+
/* The geometry block */
197+
struct vdo_geometry_block geometry_block;
198+
189199
/* The super block */
190200
struct vdo_super_block super_block;
191201

0 commit comments

Comments
 (0)