| 852 | } |
| 853 | |
| 854 | void |
| 855 | space_map_truncate(space_map_t *sm, int blocksize, dmu_tx_t *tx) |
| 856 | { |
| 857 | objset_t *os = sm->sm_os; |
| 858 | spa_t *spa = dmu_objset_spa(os); |
| 859 | dmu_object_info_t doi; |
| 860 | |
| 861 | ASSERT(dsl_pool_sync_context(dmu_objset_pool(os))); |
| 862 | ASSERT(dmu_tx_is_syncing(tx)); |
| 863 | VERIFY3U(dmu_tx_get_txg(tx), <=, spa_final_dirty_txg(spa)); |
| 864 | |
| 865 | dmu_object_info_from_db(sm->sm_dbuf, &doi); |
| 866 | |
| 867 | /* |
| 868 | * If the space map has the wrong bonus size (because |
| 869 | * SPA_FEATURE_SPACEMAP_HISTOGRAM has recently been enabled), or |
| 870 | * the wrong block size (because space_map_blksz has changed), |
| 871 | * free and re-allocate its object with the updated sizes. |
| 872 | * |
| 873 | * Otherwise, just truncate the current object. |
| 874 | */ |
| 875 | if ((spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM) && |
| 876 | doi.doi_bonus_size != sizeof (space_map_phys_t)) || |
| 877 | doi.doi_data_block_size != blocksize || |
| 878 | doi.doi_metadata_block_size != 1 << space_map_ibs) { |
| 879 | zfs_dbgmsg("txg %llu, spa %s, sm %px, reallocating " |
| 880 | "object[%llu]: old bonus %u, old blocksz %u", |
| 881 | dmu_tx_get_txg(tx), spa_name(spa), sm, sm->sm_object, |
| 882 | doi.doi_bonus_size, doi.doi_data_block_size); |
| 883 | |
| 884 | space_map_free(sm, tx); |
| 885 | dmu_buf_rele(sm->sm_dbuf, sm); |
| 886 | |
| 887 | sm->sm_object = space_map_alloc(sm->sm_os, blocksize, tx); |
| 888 | VERIFY0(space_map_open_impl(sm)); |
| 889 | } else { |
| 890 | VERIFY0(dmu_free_range(os, space_map_object(sm), 0, -1ULL, tx)); |
| 891 | |
| 892 | /* |
| 893 | * If the spacemap is reallocated, its histogram |
| 894 | * will be reset. Do the same in the common case so that |
| 895 | * bugs related to the uncommon case do not go unnoticed. |
| 896 | */ |
| 897 | bzero(sm->sm_phys->smp_histogram, |
| 898 | sizeof (sm->sm_phys->smp_histogram)); |
| 899 | } |
| 900 | |
| 901 | dmu_buf_will_dirty(sm->sm_dbuf, tx); |
| 902 | sm->sm_phys->smp_length = 0; |
| 903 | sm->sm_phys->smp_alloc = 0; |
| 904 | } |
| 905 | |
| 906 | uint64_t |
| 907 | space_map_alloc(objset_t *os, int blocksize, dmu_tx_t *tx) |
no test coverage detected