]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/spa.c
Illumos 4370, 4371
[mirror_zfs.git] / module / zfs / spa.c
index fabf161699be388024d72af3a2b9437617038a59..5bf59315a678715d75b578813d6db870d691bcb5 100644 (file)
@@ -1872,7 +1872,7 @@ static int
 spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
     const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
 {
-       if (bp != NULL) {
+       if (!BP_IS_HOLE(bp)) {
                zio_t *rio = arg;
                size_t size = BP_GET_PSIZE(bp);
                void *data = zio_data_buf_alloc(size);
@@ -2328,6 +2328,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
        if (spa_version(spa) >= SPA_VERSION_FEATURES) {
                boolean_t missing_feat_read = B_FALSE;
                nvlist_t *unsup_feat, *enabled_feat;
+               spa_feature_t i;
 
                if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ,
                    &spa->spa_feat_for_read_obj) != 0) {
@@ -2398,6 +2399,33 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                        return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT,
                            ENOTSUP));
                }
+
+               /*
+                * Load refcounts for ZFS features from disk into an in-memory
+                * cache during SPA initialization.
+                */
+               for (i = 0; i < SPA_FEATURES; i++) {
+                       uint64_t refcount;
+
+                       error = feature_get_refcount_from_disk(spa,
+                           &spa_feature_table[i], &refcount);
+                       if (error == 0) {
+                               spa->spa_feat_refcount_cache[i] = refcount;
+                       } else if (error == ENOTSUP) {
+                               spa->spa_feat_refcount_cache[i] =
+                                   SPA_FEATURE_DISABLED;
+                       } else {
+                               return (spa_vdev_err(rvd,
+                                   VDEV_AUX_CORRUPT_DATA, EIO));
+                       }
+               }
+       }
+
+       if (spa_feature_is_active(spa, SPA_FEATURE_ENABLED_TXG)) {
+               if (spa_dir_prop(spa, DMU_POOL_FEATURE_ENABLED_TXG,
+                   &spa->spa_feat_enabled_txg_obj) != 0) {
+                       return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+               }
        }
 
        spa->spa_is_initializing = B_TRUE;
@@ -5820,7 +5848,7 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
 
        /*
         * Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration
-        * information.  This avoids the dbuf_will_dirty() path and
+        * information.  This avoids the dmu_buf_will_dirty() path and
         * saves us a pre-read to get data we don't actually care about.
         */
        bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE);