Merge tag 'regulator-fix-v6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-block.git] / drivers / md / dm-thin-metadata.c
index 9dd0409848abe0d889cd67f704deb02b25f4471f..6022189c13887bbe81c918effb83217c3886fd8c 100644 (file)
@@ -603,6 +603,8 @@ static int __format_metadata(struct dm_pool_metadata *pmd)
        r = dm_tm_create_with_sm(pmd->bm, THIN_SUPERBLOCK_LOCATION,
                                 &pmd->tm, &pmd->metadata_sm);
        if (r < 0) {
+               pmd->tm = NULL;
+               pmd->metadata_sm = NULL;
                DMERR("tm_create_with_sm failed");
                return r;
        }
@@ -611,6 +613,7 @@ static int __format_metadata(struct dm_pool_metadata *pmd)
        if (IS_ERR(pmd->data_sm)) {
                DMERR("sm_disk_create failed");
                r = PTR_ERR(pmd->data_sm);
+               pmd->data_sm = NULL;
                goto bad_cleanup_tm;
        }
 
@@ -641,11 +644,15 @@ static int __format_metadata(struct dm_pool_metadata *pmd)
 
 bad_cleanup_nb_tm:
        dm_tm_destroy(pmd->nb_tm);
+       pmd->nb_tm = NULL;
 bad_cleanup_data_sm:
        dm_sm_destroy(pmd->data_sm);
+       pmd->data_sm = NULL;
 bad_cleanup_tm:
        dm_tm_destroy(pmd->tm);
+       pmd->tm = NULL;
        dm_sm_destroy(pmd->metadata_sm);
+       pmd->metadata_sm = NULL;
 
        return r;
 }
@@ -711,6 +718,8 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
                               sizeof(disk_super->metadata_space_map_root),
                               &pmd->tm, &pmd->metadata_sm);
        if (r < 0) {
+               pmd->tm = NULL;
+               pmd->metadata_sm = NULL;
                DMERR("tm_open_with_sm failed");
                goto bad_unlock_sblock;
        }
@@ -720,6 +729,7 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
        if (IS_ERR(pmd->data_sm)) {
                DMERR("sm_disk_open failed");
                r = PTR_ERR(pmd->data_sm);
+               pmd->data_sm = NULL;
                goto bad_cleanup_tm;
        }
 
@@ -746,9 +756,12 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
 
 bad_cleanup_data_sm:
        dm_sm_destroy(pmd->data_sm);
+       pmd->data_sm = NULL;
 bad_cleanup_tm:
        dm_tm_destroy(pmd->tm);
+       pmd->tm = NULL;
        dm_sm_destroy(pmd->metadata_sm);
+       pmd->metadata_sm = NULL;
 bad_unlock_sblock:
        dm_bm_unlock(sblock);
 
@@ -795,9 +808,13 @@ static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd,
                                              bool destroy_bm)
 {
        dm_sm_destroy(pmd->data_sm);
+       pmd->data_sm = NULL;
        dm_sm_destroy(pmd->metadata_sm);
+       pmd->metadata_sm = NULL;
        dm_tm_destroy(pmd->nb_tm);
+       pmd->nb_tm = NULL;
        dm_tm_destroy(pmd->tm);
+       pmd->tm = NULL;
        if (destroy_bm)
                dm_block_manager_destroy(pmd->bm);
 }
@@ -1005,8 +1022,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
                               __func__, r);
        }
        pmd_write_unlock(pmd);
-       if (!pmd->fail_io)
-               __destroy_persistent_data_objects(pmd, true);
+       __destroy_persistent_data_objects(pmd, true);
 
        kfree(pmd);
        return 0;
@@ -1881,53 +1897,29 @@ static void __set_abort_with_changes_flags(struct dm_pool_metadata *pmd)
 int dm_pool_abort_metadata(struct dm_pool_metadata *pmd)
 {
        int r = -EINVAL;
-       struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
 
        /* fail_io is double-checked with pmd->root_lock held below */
        if (unlikely(pmd->fail_io))
                return r;
 
-       /*
-        * Replacement block manager (new_bm) is created and old_bm destroyed outside of
-        * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
-        * shrinker associated with the block manager's bufio client vs pmd root_lock).
-        * - must take shrinker_rwsem without holding pmd->root_lock
-        */
-       new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
-                                        THIN_MAX_CONCURRENT_LOCKS);
-
        pmd_write_lock(pmd);
        if (pmd->fail_io) {
                pmd_write_unlock(pmd);
-               goto out;
+               return r;
        }
-
        __set_abort_with_changes_flags(pmd);
+
+       /* destroy data_sm/metadata_sm/nb_tm/tm */
        __destroy_persistent_data_objects(pmd, false);
-       old_bm = pmd->bm;
-       if (IS_ERR(new_bm)) {
-               DMERR("could not create block manager during abort");
-               pmd->bm = NULL;
-               r = PTR_ERR(new_bm);
-               goto out_unlock;
-       }
 
-       pmd->bm = new_bm;
+       /* reset bm */
+       dm_block_manager_reset(pmd->bm);
+
+       /* rebuild data_sm/metadata_sm/nb_tm/tm */
        r = __open_or_format_metadata(pmd, false);
-       if (r) {
-               pmd->bm = NULL;
-               goto out_unlock;
-       }
-       new_bm = NULL;
-out_unlock:
        if (r)
                pmd->fail_io = true;
        pmd_write_unlock(pmd);
-       dm_block_manager_destroy(old_bm);
-out:
-       if (new_bm && !IS_ERR(new_bm))
-               dm_block_manager_destroy(new_bm);
-
        return r;
 }