summaryrefslogtreecommitdiff
path: root/drivers/md/dm-thin-metadata.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2012-07-27 18:08:09 +0400
committerAlasdair G Kergon <agk@redhat.com>2012-07-27 18:08:09 +0400
commit384ef0e62e409e52c80adef5b1ff83075377c19e (patch)
tree734db218c323e88a303f64218661286f94f9e52a /drivers/md/dm-thin-metadata.c
parenteb04cf634fc2d5e3bc8fe88fbf434eda4921d875 (diff)
downloadlinux-384ef0e62e409e52c80adef5b1ff83075377c19e.tar.xz
dm persistent data: tidy transaction manager creation fns
Tidy the transaction manager creation functions. They no longer lock the superblock. Superblock locking is pulled out to the caller. Also export dm_bm_write_lock_zero. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-thin-metadata.c')
-rw-r--r--drivers/md/dm-thin-metadata.c42
1 files changed, 27 insertions, 15 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,
struct dm_block *sblock;
if (create) {
- r = dm_tm_create_with_sm(bm, THIN_SUPERBLOCK_LOCATION,
- &sb_validator, &tm, &sm, &sblock);
+ r = dm_tm_create_with_sm(bm, THIN_SUPERBLOCK_LOCATION, &tm, &sm);
if (r < 0) {
DMERR("tm_create_with_sm failed");
return r;
@@ -428,38 +427,51 @@ static int init_pmd(struct dm_pool_metadata *pmd,
data_sm = dm_sm_disk_create(tm, nr_blocks);
if (IS_ERR(data_sm)) {
DMERR("sm_disk_create failed");
- dm_tm_unlock(tm, sblock);
r = PTR_ERR(data_sm);
goto bad;
}
+
+ /*
+ * We cycle the superblock to let the validator do its stuff.
+ */
+ r = dm_bm_write_lock_zero(bm, THIN_SUPERBLOCK_LOCATION, &sb_validator, &sblock);
+ if (r < 0) {
+ DMERR("couldn't lock superblock");
+ goto bad;
+ }
+
+ dm_bm_unlock(sblock);
+
} else {
- struct thin_disk_superblock *disk_super = NULL;
- size_t space_map_root_offset =
- offsetof(struct thin_disk_superblock, metadata_space_map_root);
+ struct thin_disk_superblock *disk_super;
+
+ r = dm_bm_read_lock(bm, THIN_SUPERBLOCK_LOCATION, &sb_validator, &sblock);
+ if (r < 0) {
+ DMERR("couldn't read superblock");
+ return r;
+ }
+ disk_super = dm_block_data(sblock);
r = dm_tm_open_with_sm(bm, THIN_SUPERBLOCK_LOCATION,
- &sb_validator, space_map_root_offset,
- SPACE_MAP_ROOT_SIZE, &tm, &sm, &sblock);
+ disk_super->metadata_space_map_root,
+ sizeof(disk_super->metadata_space_map_root),
+ &tm, &sm);
if (r < 0) {
DMERR("tm_open_with_sm failed");
+ dm_bm_unlock(sblock);
return r;
}
- disk_super = dm_block_data(sblock);
data_sm = dm_sm_disk_open(tm, disk_super->data_space_map_root,
sizeof(disk_super->data_space_map_root));
if (IS_ERR(data_sm)) {
DMERR("sm_disk_open failed");
+ dm_bm_unlock(sblock);
r = PTR_ERR(data_sm);
goto bad;
}
- }
-
- r = dm_tm_unlock(tm, sblock);
- if (r < 0) {
- DMERR("couldn't unlock superblock");
- goto bad_data_sm;
+ dm_bm_unlock(sblock);
}
pmd->bm = bm;