]> Pileus Git - ~andy/linux/commitdiff
dm thin metadata: factor out __write_initial_superblock
authorJoe Thornber <ejt@redhat.com>
Fri, 27 Jul 2012 14:08:10 +0000 (15:08 +0100)
committerAlasdair G Kergon <agk@redhat.com>
Fri, 27 Jul 2012 14:08:10 +0000 (15:08 +0100)
Factor out __write_initial_superblock and also pull some other initial
creation code out of dm_pool_metadata_open.

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>
drivers/md/dm-thin-metadata.c

index ce487aada0d885494d50634a4614e63879f97fa3..5ead655706d490d249c62dd29a55b9e1d89feaf4 100644 (file)
@@ -422,6 +422,41 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd)
        pmd->details_info.value_type.equal = NULL;
 }
 
+static int __write_initial_superblock(struct dm_pool_metadata *pmd)
+{
+       int r;
+       struct dm_block *sblock;
+       struct thin_disk_superblock *disk_super;
+       sector_t bdev_size = i_size_read(pmd->bdev->bd_inode) >> SECTOR_SHIFT;
+
+       if (bdev_size > THIN_METADATA_MAX_SECTORS)
+               bdev_size = THIN_METADATA_MAX_SECTORS;
+
+       r = superblock_lock_zero(pmd, &sblock);
+       if (r)
+               return r;
+
+       disk_super = dm_block_data(sblock);
+       disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC);
+       disk_super->version = cpu_to_le32(THIN_VERSION);
+       disk_super->time = 0;
+       disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
+       disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT);
+       disk_super->data_block_size = cpu_to_le32(pmd->data_block_size);
+
+       r = dm_bm_unlock(sblock);
+       if (r)
+               return r;
+
+       pmd->flags = 0;
+       r = dm_pool_commit_metadata(pmd);
+       if (r < 0)
+               DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
+                     __func__, r);
+
+       return r;
+}
+
 static int __open_or_format_metadata(struct dm_pool_metadata *pmd,
                                     struct dm_block_manager *bm,
                                     dm_block_t nr_blocks, int create)
@@ -495,6 +530,23 @@ static int __open_or_format_metadata(struct dm_pool_metadata *pmd,
        pmd->trans_id = 0;
        pmd->flags = 0;
 
+       if (!create)
+               return 0;
+
+       r = dm_btree_empty(&pmd->info, &pmd->root);
+       if (r < 0)
+               goto bad_data_sm;
+
+       r = dm_btree_empty(&pmd->details_info, &pmd->details_root);
+       if (r < 0) {
+               DMERR("couldn't create devices root");
+               goto bad_data_sm;
+       }
+
+       r = __write_initial_superblock(pmd);
+       if (r)
+               goto bad_data_sm;
+
        return 0;
 
 bad_data_sm:
@@ -695,11 +747,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
                                               sector_t data_block_size)
 {
        int r;
-       struct thin_disk_superblock *disk_super;
        struct dm_pool_metadata *pmd;
-       sector_t bdev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
        int create;
-       struct dm_block *sblock;
 
        pmd = kmalloc(sizeof(*pmd), GFP_KERNEL);
        if (!pmd) {
@@ -711,6 +760,7 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
        pmd->time = 0;
        INIT_LIST_HEAD(&pmd->thin_devices);
        pmd->bdev = bdev;
+       pmd->data_block_size = data_block_size;
 
        r = __create_persistent_data_objects(pmd, 0, &create);
        if (r) {
@@ -720,57 +770,14 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
 
        if (!create) {
                r = __begin_transaction(pmd);
-               if (r < 0)
-                       goto bad;
-               return pmd;
-       }
-
-       /*
-        * Create.
-        */
-       r = superblock_lock_zero(pmd, &sblock);
-       if (r)
-               goto bad;
-
-       if (bdev_size > THIN_METADATA_MAX_SECTORS)
-               bdev_size = THIN_METADATA_MAX_SECTORS;
-
-       disk_super = dm_block_data(sblock);
-       disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC);
-       disk_super->version = cpu_to_le32(THIN_VERSION);
-       disk_super->time = 0;
-       disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
-       disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT);
-       disk_super->data_block_size = cpu_to_le32(data_block_size);
-
-       r = dm_bm_unlock(sblock);
-       if (r < 0)
-               goto bad;
-
-       r = dm_btree_empty(&pmd->info, &pmd->root);
-       if (r < 0)
-               goto bad;
-
-       r = dm_btree_empty(&pmd->details_info, &pmd->details_root);
-       if (r < 0) {
-               DMERR("couldn't create devices root");
-               goto bad;
-       }
-
-       pmd->flags = 0;
-       r = dm_pool_commit_metadata(pmd);
-       if (r < 0) {
-               DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
-                     __func__, r);
-               goto bad;
+               if (r < 0) {
+                       if (dm_pool_metadata_close(pmd) < 0)
+                               DMWARN("%s: dm_pool_metadata_close() failed.", __func__);
+                       return ERR_PTR(r);
+               }
        }
 
        return pmd;
-
-bad:
-       if (dm_pool_metadata_close(pmd) < 0)
-               DMWARN("%s: dm_pool_metadata_close() failed.", __func__);
-       return ERR_PTR(r);
 }
 
 int dm_pool_metadata_close(struct dm_pool_metadata *pmd)