diff options
| -rw-r--r-- | drivers/md/dm-thin-metadata.c | 42 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-block-manager.c | 1 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-transaction-manager.c | 47 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-transaction-manager.h | 11 |
4 files changed, 46 insertions, 55 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index c8f36227fd7b..4aadeae3af67 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
| @@ -418,8 +418,7 @@ static int init_pmd(struct dm_pool_metadata *pmd, | |||
| 418 | struct dm_block *sblock; | 418 | struct dm_block *sblock; |
| 419 | 419 | ||
| 420 | if (create) { | 420 | if (create) { |
| 421 | r = dm_tm_create_with_sm(bm, THIN_SUPERBLOCK_LOCATION, | 421 | r = dm_tm_create_with_sm(bm, THIN_SUPERBLOCK_LOCATION, &tm, &sm); |
| 422 | &sb_validator, &tm, &sm, &sblock); | ||
| 423 | if (r < 0) { | 422 | if (r < 0) { |
| 424 | DMERR("tm_create_with_sm failed"); | 423 | DMERR("tm_create_with_sm failed"); |
| 425 | return r; | 424 | return r; |
| @@ -428,38 +427,51 @@ static int init_pmd(struct dm_pool_metadata *pmd, | |||
| 428 | data_sm = dm_sm_disk_create(tm, nr_blocks); | 427 | data_sm = dm_sm_disk_create(tm, nr_blocks); |
| 429 | if (IS_ERR(data_sm)) { | 428 | if (IS_ERR(data_sm)) { |
| 430 | DMERR("sm_disk_create failed"); | 429 | DMERR("sm_disk_create failed"); |
| 431 | dm_tm_unlock(tm, sblock); | ||
| 432 | r = PTR_ERR(data_sm); | 430 | r = PTR_ERR(data_sm); |
| 433 | goto bad; | 431 | goto bad; |
| 434 | } | 432 | } |
| 433 | |||
| 434 | /* | ||
| 435 | * We cycle the superblock to let the validator do its stuff. | ||
| 436 | */ | ||
| 437 | r = dm_bm_write_lock_zero(bm, THIN_SUPERBLOCK_LOCATION, &sb_validator, &sblock); | ||
| 438 | if (r < 0) { | ||
| 439 | DMERR("couldn't lock superblock"); | ||
| 440 | goto bad; | ||
| 441 | } | ||
| 442 | |||
| 443 | dm_bm_unlock(sblock); | ||
| 444 | |||
| 435 | } else { | 445 | } else { |
| 436 | struct thin_disk_superblock *disk_super = NULL; | 446 | struct thin_disk_superblock *disk_super; |
| 437 | size_t space_map_root_offset = | 447 | |
| 438 | offsetof(struct thin_disk_superblock, metadata_space_map_root); | 448 | r = dm_bm_read_lock(bm, THIN_SUPERBLOCK_LOCATION, &sb_validator, &sblock); |
| 449 | if (r < 0) { | ||
| 450 | DMERR("couldn't read superblock"); | ||
| 451 | return r; | ||
| 452 | } | ||
| 439 | 453 | ||
| 454 | disk_super = dm_block_data(sblock); | ||
| 440 | r = dm_tm_open_with_sm(bm, THIN_SUPERBLOCK_LOCATION, | 455 | r = dm_tm_open_with_sm(bm, THIN_SUPERBLOCK_LOCATION, |
| 441 | &sb_validator, space_map_root_offset, | 456 | disk_super->metadata_space_map_root, |
| 442 | SPACE_MAP_ROOT_SIZE, &tm, &sm, &sblock); | 457 | sizeof(disk_super->metadata_space_map_root), |
| 458 | &tm, &sm); | ||
| 443 | if (r < 0) { | 459 | if (r < 0) { |
| 444 | DMERR("tm_open_with_sm failed"); | 460 | DMERR("tm_open_with_sm failed"); |
| 461 | dm_bm_unlock(sblock); | ||
| 445 | return r; | 462 | return r; |
| 446 | } | 463 | } |
| 447 | 464 | ||
| 448 | disk_super = dm_block_data(sblock); | ||
| 449 | data_sm = dm_sm_disk_open(tm, disk_super->data_space_map_root, | 465 | data_sm = dm_sm_disk_open(tm, disk_super->data_space_map_root, |
| 450 | sizeof(disk_super->data_space_map_root)); | 466 | sizeof(disk_super->data_space_map_root)); |
| 451 | if (IS_ERR(data_sm)) { | 467 | if (IS_ERR(data_sm)) { |
| 452 | DMERR("sm_disk_open failed"); | 468 | DMERR("sm_disk_open failed"); |
| 469 | dm_bm_unlock(sblock); | ||
| 453 | r = PTR_ERR(data_sm); | 470 | r = PTR_ERR(data_sm); |
| 454 | goto bad; | 471 | goto bad; |
| 455 | } | 472 | } |
| 456 | } | ||
| 457 | |||
| 458 | 473 | ||
| 459 | r = dm_tm_unlock(tm, sblock); | 474 | dm_bm_unlock(sblock); |
| 460 | if (r < 0) { | ||
| 461 | DMERR("couldn't unlock superblock"); | ||
| 462 | goto bad_data_sm; | ||
| 463 | } | 475 | } |
| 464 | 476 | ||
| 465 | pmd->bm = bm; | 477 | pmd->bm = bm; |
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c index c70ad6e303d3..4b5c504f47af 100644 --- a/drivers/md/persistent-data/dm-block-manager.c +++ b/drivers/md/persistent-data/dm-block-manager.c | |||
| @@ -565,6 +565,7 @@ int dm_bm_write_lock_zero(struct dm_block_manager *bm, | |||
| 565 | 565 | ||
| 566 | return 0; | 566 | return 0; |
| 567 | } | 567 | } |
| 568 | EXPORT_SYMBOL_GPL(dm_bm_write_lock_zero); | ||
| 568 | 569 | ||
| 569 | int dm_bm_unlock(struct dm_block *b) | 570 | int dm_bm_unlock(struct dm_block *b) |
| 570 | { | 571 | { |
diff --git a/drivers/md/persistent-data/dm-transaction-manager.c b/drivers/md/persistent-data/dm-transaction-manager.c index 86c3705052a4..b4f05830af07 100644 --- a/drivers/md/persistent-data/dm-transaction-manager.c +++ b/drivers/md/persistent-data/dm-transaction-manager.c | |||
| @@ -310,12 +310,10 @@ struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm) | |||
| 310 | 310 | ||
| 311 | static int dm_tm_create_internal(struct dm_block_manager *bm, | 311 | static int dm_tm_create_internal(struct dm_block_manager *bm, |
| 312 | dm_block_t sb_location, | 312 | dm_block_t sb_location, |
| 313 | struct dm_block_validator *sb_validator, | ||
| 314 | size_t root_offset, size_t root_max_len, | ||
| 315 | struct dm_transaction_manager **tm, | 313 | struct dm_transaction_manager **tm, |
| 316 | struct dm_space_map **sm, | 314 | struct dm_space_map **sm, |
| 317 | struct dm_block **sblock, | 315 | int create, |
| 318 | int create) | 316 | void *sm_root, size_t sm_len) |
| 319 | { | 317 | { |
| 320 | int r; | 318 | int r; |
| 321 | 319 | ||
| @@ -330,64 +328,43 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, | |||
| 330 | } | 328 | } |
| 331 | 329 | ||
| 332 | if (create) { | 330 | if (create) { |
| 333 | r = dm_bm_write_lock_zero(dm_tm_get_bm(*tm), sb_location, | ||
| 334 | sb_validator, sblock); | ||
| 335 | if (r < 0) { | ||
| 336 | DMERR("couldn't lock superblock"); | ||
| 337 | goto bad1; | ||
| 338 | } | ||
| 339 | |||
| 340 | r = dm_sm_metadata_create(*sm, *tm, dm_bm_nr_blocks(bm), | 331 | r = dm_sm_metadata_create(*sm, *tm, dm_bm_nr_blocks(bm), |
| 341 | sb_location); | 332 | sb_location); |
| 342 | if (r) { | 333 | if (r) { |
| 343 | DMERR("couldn't create metadata space map"); | 334 | DMERR("couldn't create metadata space map"); |
| 344 | goto bad2; | 335 | goto bad; |
| 345 | } | 336 | } |
| 346 | 337 | ||
| 347 | } else { | 338 | } else { |
| 348 | r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location, | 339 | r = dm_sm_metadata_open(*sm, *tm, sm_root, sm_len); |
| 349 | sb_validator, sblock); | ||
| 350 | if (r < 0) { | ||
| 351 | DMERR("couldn't lock superblock"); | ||
| 352 | goto bad1; | ||
| 353 | } | ||
| 354 | |||
| 355 | r = dm_sm_metadata_open(*sm, *tm, | ||
| 356 | dm_block_data(*sblock) + root_offset, | ||
| 357 | root_max_len); | ||
| 358 | if (r) { | 340 | if (r) { |
| 359 | DMERR("couldn't open metadata space map"); | 341 | DMERR("couldn't open metadata space map"); |
| 360 | goto bad2; | 342 | goto bad; |
| 361 | } | 343 | } |
| 362 | } | 344 | } |
| 363 | 345 | ||
| 364 | return 0; | 346 | return 0; |
| 365 | 347 | ||
| 366 | bad2: | 348 | bad: |
| 367 | dm_tm_unlock(*tm, *sblock); | ||
| 368 | bad1: | ||
| 369 | dm_tm_destroy(*tm); | 349 | dm_tm_destroy(*tm); |
| 350 | dm_sm_destroy(*sm); | ||
| 370 | return r; | 351 | return r; |
| 371 | } | 352 | } |
| 372 | 353 | ||
| 373 | int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, | 354 | int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, |
| 374 | struct dm_block_validator *sb_validator, | ||
| 375 | struct dm_transaction_manager **tm, | 355 | struct dm_transaction_manager **tm, |
| 376 | struct dm_space_map **sm, struct dm_block **sblock) | 356 | struct dm_space_map **sm) |
| 377 | { | 357 | { |
| 378 | return dm_tm_create_internal(bm, sb_location, sb_validator, | 358 | return dm_tm_create_internal(bm, sb_location, tm, sm, 1, NULL, 0); |
| 379 | 0, 0, tm, sm, sblock, 1); | ||
| 380 | } | 359 | } |
| 381 | EXPORT_SYMBOL_GPL(dm_tm_create_with_sm); | 360 | EXPORT_SYMBOL_GPL(dm_tm_create_with_sm); |
| 382 | 361 | ||
| 383 | int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, | 362 | int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, |
| 384 | struct dm_block_validator *sb_validator, | 363 | void *sm_root, size_t root_len, |
| 385 | size_t root_offset, size_t root_max_len, | ||
| 386 | struct dm_transaction_manager **tm, | 364 | struct dm_transaction_manager **tm, |
| 387 | struct dm_space_map **sm, struct dm_block **sblock) | 365 | struct dm_space_map **sm) |
| 388 | { | 366 | { |
| 389 | return dm_tm_create_internal(bm, sb_location, sb_validator, root_offset, | 367 | return dm_tm_create_internal(bm, sb_location, tm, sm, 0, sm_root, root_len); |
| 390 | root_max_len, tm, sm, sblock, 0); | ||
| 391 | } | 368 | } |
| 392 | EXPORT_SYMBOL_GPL(dm_tm_open_with_sm); | 369 | EXPORT_SYMBOL_GPL(dm_tm_open_with_sm); |
| 393 | 370 | ||
diff --git a/drivers/md/persistent-data/dm-transaction-manager.h b/drivers/md/persistent-data/dm-transaction-manager.h index 6da784871db4..b5b139076ca5 100644 --- a/drivers/md/persistent-data/dm-transaction-manager.h +++ b/drivers/md/persistent-data/dm-transaction-manager.h | |||
| @@ -115,16 +115,17 @@ struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm); | |||
| 115 | * | 115 | * |
| 116 | * Returns a tm that has an open transaction to write the new disk sm. | 116 | * Returns a tm that has an open transaction to write the new disk sm. |
| 117 | * Caller should store the new sm root and commit. | 117 | * Caller should store the new sm root and commit. |
| 118 | * | ||
| 119 | * The superblock location is passed so the metadata space map knows it | ||
| 120 | * shouldn't be used. | ||
| 118 | */ | 121 | */ |
| 119 | int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, | 122 | int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, |
| 120 | struct dm_block_validator *sb_validator, | ||
| 121 | struct dm_transaction_manager **tm, | 123 | struct dm_transaction_manager **tm, |
| 122 | struct dm_space_map **sm, struct dm_block **sblock); | 124 | struct dm_space_map **sm); |
| 123 | 125 | ||
| 124 | int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, | 126 | int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location, |
| 125 | struct dm_block_validator *sb_validator, | 127 | void *sm_root, size_t root_len, |
| 126 | size_t root_offset, size_t root_max_len, | ||
| 127 | struct dm_transaction_manager **tm, | 128 | struct dm_transaction_manager **tm, |
| 128 | struct dm_space_map **sm, struct dm_block **sblock); | 129 | struct dm_space_map **sm); |
| 129 | 130 | ||
| 130 | #endif /* _LINUX_DM_TRANSACTION_MANAGER_H */ | 131 | #endif /* _LINUX_DM_TRANSACTION_MANAGER_H */ |
