]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/spa_misc.c
OpenZFS 9102 - zfs should be able to initialize storage devices
[mirror_zfs.git] / module / zfs / spa_misc.c
index 343b01dd6aacfd580b858a9eaf4c9b56c8d96e3b..dfac92d458d3ea9f5a24d642aa47e05da3fe89e3 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/zap.h>
 #include <sys/zil.h>
 #include <sys/vdev_impl.h>
+#include <sys/vdev_initialize.h>
 #include <sys/vdev_file.h>
 #include <sys/vdev_raidz.h>
 #include <sys/metaslab.h>
@@ -81,7 +82,7 @@
  *     definition they must have an existing reference, and will never need
  *     to lookup a spa_t by name.
  *
- * spa_refcount (per-spa refcount_t protected by mutex)
+ * spa_refcount (per-spa zfs_refcount_t protected by mutex)
  *
  *     This reference count keep track of any active users of the spa_t.  The
  *     spa_t cannot be destroyed or freed while this is non-zero.  Internally,
  * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
  * Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
  * locking is, always, based on spa_namespace_lock and spa_config_lock[].
- *
- * spa_rename() is also implemented within this file since it requires
- * manipulation of the namespace.
  */
 
 static avl_tree_t spa_namespace_avl;
@@ -315,7 +313,7 @@ unsigned long zfs_deadman_ziotime_ms = 300000ULL;
  * Check time in milliseconds. This defines the frequency at which we check
  * for hung I/O.
  */
-unsigned long  zfs_deadman_checktime_ms = 60000ULL;
+unsigned long zfs_deadman_checktime_ms = 60000ULL;
 
 /*
  * By default the deadman is enabled.
@@ -434,7 +432,7 @@ spa_config_lock_init(spa_t *spa)
                spa_config_lock_t *scl = &spa->spa_config_lock[i];
                mutex_init(&scl->scl_lock, NULL, MUTEX_DEFAULT, NULL);
                cv_init(&scl->scl_cv, NULL, CV_DEFAULT, NULL);
-               refcount_create_untracked(&scl->scl_count);
+               zfs_refcount_create_untracked(&scl->scl_count);
                scl->scl_writer = NULL;
                scl->scl_write_wanted = 0;
        }
@@ -447,7 +445,7 @@ spa_config_lock_destroy(spa_t *spa)
                spa_config_lock_t *scl = &spa->spa_config_lock[i];
                mutex_destroy(&scl->scl_lock);
                cv_destroy(&scl->scl_cv);
-               refcount_destroy(&scl->scl_count);
+               zfs_refcount_destroy(&scl->scl_count);
                ASSERT(scl->scl_writer == NULL);
                ASSERT(scl->scl_write_wanted == 0);
        }
@@ -470,7 +468,7 @@ spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw)
                        }
                } else {
                        ASSERT(scl->scl_writer != curthread);
-                       if (!refcount_is_zero(&scl->scl_count)) {
+                       if (!zfs_refcount_is_zero(&scl->scl_count)) {
                                mutex_exit(&scl->scl_lock);
                                spa_config_exit(spa, locks & ((1 << i) - 1),
                                    tag);
@@ -478,7 +476,7 @@ spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw)
                        }
                        scl->scl_writer = curthread;
                }
-               (void) refcount_add(&scl->scl_count, tag);
+               (void) zfs_refcount_add(&scl->scl_count, tag);
                mutex_exit(&scl->scl_lock);
        }
        return (1);
@@ -504,14 +502,14 @@ spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw)
                        }
                } else {
                        ASSERT(scl->scl_writer != curthread);
-                       while (!refcount_is_zero(&scl->scl_count)) {
+                       while (!zfs_refcount_is_zero(&scl->scl_count)) {
                                scl->scl_write_wanted++;
                                cv_wait(&scl->scl_cv, &scl->scl_lock);
                                scl->scl_write_wanted--;
                        }
                        scl->scl_writer = curthread;
                }
-               (void) refcount_add(&scl->scl_count, tag);
+               (void) zfs_refcount_add(&scl->scl_count, tag);
                mutex_exit(&scl->scl_lock);
        }
        ASSERT3U(wlocks_held, <=, locks);
@@ -525,8 +523,8 @@ spa_config_exit(spa_t *spa, int locks, void *tag)
                if (!(locks & (1 << i)))
                        continue;
                mutex_enter(&scl->scl_lock);
-               ASSERT(!refcount_is_zero(&scl->scl_count));
-               if (refcount_remove(&scl->scl_count, tag) == 0) {
+               ASSERT(!zfs_refcount_is_zero(&scl->scl_count));
+               if (zfs_refcount_remove(&scl->scl_count, tag) == 0) {
                        ASSERT(scl->scl_writer == NULL ||
                            scl->scl_writer == curthread);
                        scl->scl_writer = NULL; /* OK in either case */
@@ -545,7 +543,8 @@ spa_config_held(spa_t *spa, int locks, krw_t rw)
                spa_config_lock_t *scl = &spa->spa_config_lock[i];
                if (!(locks & (1 << i)))
                        continue;
-               if ((rw == RW_READER && !refcount_is_zero(&scl->scl_count)) ||
+               if ((rw == RW_READER &&
+                   !zfs_refcount_is_zero(&scl->scl_count)) ||
                    (rw == RW_WRITER && scl->scl_writer == curthread))
                        locks_held |= 1 << i;
        }
@@ -663,7 +662,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
        spa->spa_deadman_ziotime = MSEC2NSEC(zfs_deadman_ziotime_ms);
        spa_set_deadman_failmode(spa, zfs_deadman_failmode);
 
-       refcount_create(&spa->spa_refcount);
+       zfs_refcount_create(&spa->spa_refcount);
        spa_config_lock_init(spa);
        spa_stats_init(spa);
 
@@ -746,7 +745,7 @@ spa_remove(spa_t *spa)
 
        ASSERT(MUTEX_HELD(&spa_namespace_lock));
        ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
-       ASSERT3U(refcount_count(&spa->spa_refcount), ==, 0);
+       ASSERT3U(zfs_refcount_count(&spa->spa_refcount), ==, 0);
 
        nvlist_free(spa->spa_config_splitting);
 
@@ -779,7 +778,7 @@ spa_remove(spa_t *spa)
        nvlist_free(spa->spa_feat_stats);
        spa_config_set(spa, NULL);
 
-       refcount_destroy(&spa->spa_refcount);
+       zfs_refcount_destroy(&spa->spa_refcount);
 
        spa_stats_destroy(spa);
        spa_config_lock_destroy(spa);
@@ -839,9 +838,9 @@ spa_next(spa_t *prev)
 void
 spa_open_ref(spa_t *spa, void *tag)
 {
-       ASSERT(refcount_count(&spa->spa_refcount) >= spa->spa_minref ||
+       ASSERT(zfs_refcount_count(&spa->spa_refcount) >= spa->spa_minref ||
            MUTEX_HELD(&spa_namespace_lock));
-       (void) refcount_add(&spa->spa_refcount, tag);
+       (void) zfs_refcount_add(&spa->spa_refcount, tag);
 }
 
 /*
@@ -851,9 +850,9 @@ spa_open_ref(spa_t *spa, void *tag)
 void
 spa_close(spa_t *spa, void *tag)
 {
-       ASSERT(refcount_count(&spa->spa_refcount) > spa->spa_minref ||
+       ASSERT(zfs_refcount_count(&spa->spa_refcount) > spa->spa_minref ||
            MUTEX_HELD(&spa_namespace_lock));
-       (void) refcount_remove(&spa->spa_refcount, tag);
+       (void) zfs_refcount_remove(&spa->spa_refcount, tag);
 }
 
 /*
@@ -867,7 +866,7 @@ spa_close(spa_t *spa, void *tag)
 void
 spa_async_close(spa_t *spa, void *tag)
 {
-       (void) refcount_remove(&spa->spa_refcount, tag);
+       (void) zfs_refcount_remove(&spa->spa_refcount, tag);
 }
 
 /*
@@ -880,7 +879,7 @@ spa_refcount_zero(spa_t *spa)
 {
        ASSERT(MUTEX_HELD(&spa_namespace_lock));
 
-       return (refcount_count(&spa->spa_refcount) == spa->spa_minref);
+       return (zfs_refcount_count(&spa->spa_refcount) == spa->spa_minref);
 }
 
 /*
@@ -1196,6 +1195,12 @@ spa_vdev_config_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error, char *tag)
 
        if (vd != NULL) {
                ASSERT(!vd->vdev_detached || vd->vdev_dtl_sm == NULL);
+               if (vd->vdev_ops->vdev_op_leaf) {
+                       mutex_enter(&vd->vdev_initialize_lock);
+                       vdev_initialize_stop(vd, VDEV_INITIALIZE_CANCELED);
+                       mutex_exit(&vd->vdev_initialize_lock);
+               }
+
                spa_config_enter(spa, SCL_ALL, spa, RW_WRITER);
                vdev_free(vd);
                spa_config_exit(spa, SCL_ALL, spa);
@@ -1334,56 +1339,6 @@ spa_deactivate_mos_feature(spa_t *spa, const char *feature)
                vdev_config_dirty(spa->spa_root_vdev);
 }
 
-/*
- * Rename a spa_t.
- */
-int
-spa_rename(const char *name, const char *newname)
-{
-       spa_t *spa;
-       int err;
-
-       /*
-        * Lookup the spa_t and grab the config lock for writing.  We need to
-        * actually open the pool so that we can sync out the necessary labels.
-        * It's OK to call spa_open() with the namespace lock held because we
-        * allow recursive calls for other reasons.
-        */
-       mutex_enter(&spa_namespace_lock);
-       if ((err = spa_open(name, &spa, FTAG)) != 0) {
-               mutex_exit(&spa_namespace_lock);
-               return (err);
-       }
-
-       spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
-
-       avl_remove(&spa_namespace_avl, spa);
-       (void) strlcpy(spa->spa_name, newname, sizeof (spa->spa_name));
-       avl_add(&spa_namespace_avl, spa);
-
-       /*
-        * Sync all labels to disk with the new names by marking the root vdev
-        * dirty and waiting for it to sync.  It will pick up the new pool name
-        * during the sync.
-        */
-       vdev_config_dirty(spa->spa_root_vdev);
-
-       spa_config_exit(spa, SCL_ALL, FTAG);
-
-       txg_wait_synced(spa->spa_dsl_pool, 0);
-
-       /*
-        * Sync the updated config cache.
-        */
-       spa_write_cachefile(spa, B_FALSE, B_TRUE);
-
-       spa_close(spa, FTAG);
-
-       mutex_exit(&spa_namespace_lock);
-
-       return (0);
-}
-
 /*
  * Return the spa_t associated with given pool_guid, if it exists.  If
  * device_guid is non-zero, determine whether the pool exists *and* contains
@@ -2099,7 +2054,7 @@ spa_init(int mode)
 #endif
 
        fm_init();
-       refcount_init();
+       zfs_refcount_init();
        unique_init();
        range_tree_init();
        metaslab_alloc_trace_init();
@@ -2138,7 +2093,7 @@ spa_fini(void)
        metaslab_alloc_trace_fini();
        range_tree_fini();
        unique_fini();
-       refcount_fini();
+       zfs_refcount_fini();
        fm_fini();
        scan_fini();
        qat_fini();
@@ -2632,7 +2587,6 @@ EXPORT_SYMBOL(spa_maxblocksize);
 EXPORT_SYMBOL(spa_maxdnodesize);
 
 /* Miscellaneous support routines */
-EXPORT_SYMBOL(spa_rename);
 EXPORT_SYMBOL(spa_guid_exists);
 EXPORT_SYMBOL(spa_strdup);
 EXPORT_SYMBOL(spa_strfree);