Illumos #1748: desire support for reguid in zfs
[zfs.git] / module / zfs / vdev.c
index 604a673..18d2d5c 100644 (file)
@@ -21,6 +21,8 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -291,6 +293,7 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
        if (spa->spa_root_vdev == NULL) {
                ASSERT(ops == &vdev_root_ops);
                spa->spa_root_vdev = vd;
+               spa->spa_load_guid = spa_generate_guid(NULL);
        }
 
        if (guid == 0 && ops != &vdev_hole_ops) {
@@ -317,6 +320,8 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
        vd->vdev_state = VDEV_STATE_CLOSED;
        vd->vdev_ishole = (ops == &vdev_hole_ops);
 
+       list_link_init(&vd->vdev_config_dirty_node);
+       list_link_init(&vd->vdev_state_dirty_node);
        mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL);
        mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL);
        mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL);
@@ -490,7 +495,7 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
                    &vd->vdev_removing);
        }
 
-       if (parent && !parent->vdev_parent) {
+       if (parent && !parent->vdev_parent && alloctype != VDEV_ALLOC_ATTACH) {
                ASSERT(alloctype == VDEV_ALLOC_LOAD ||
                    alloctype == VDEV_ALLOC_ADD ||
                    alloctype == VDEV_ALLOC_SPLIT ||
@@ -667,6 +672,8 @@ vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
        svd->vdev_ms_shift = 0;
        svd->vdev_ms_count = 0;
 
+       if (tvd->vdev_mg)
+               ASSERT3P(tvd->vdev_mg, ==, svd->vdev_mg);
        tvd->vdev_mg = svd->vdev_mg;
        tvd->vdev_ms = svd->vdev_ms;
 
@@ -831,7 +838,7 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg)
 
        ASSERT(oldc <= newc);
 
-       mspp = kmem_zalloc(newc * sizeof (*mspp), KM_SLEEP);
+       mspp = kmem_zalloc(newc * sizeof (*mspp), KM_SLEEP | KM_NODEBUG);
 
        if (oldc != 0) {
                bcopy(vd->vdev_ms, mspp, oldc * sizeof (*mspp));
@@ -1067,6 +1074,15 @@ vdev_open_child(void *arg)
 boolean_t
 vdev_uses_zvols(vdev_t *vd)
 {
+/*
+ * Stacking zpools on top of zvols is unsupported until we implement a method
+ * for determining if an arbitrary block device is a zvol without using the
+ * path.  Solaris would check the 'zvol' path component but this does not
+ * exist in the Linux port, so we really should do something like stat the
+ * file and check the major number.  This is complicated by the fact that
+ * we need to do this portably in user or kernel space.
+ */
+#if 0
        int c;
 
        if (vd->vdev_path && strncmp(vd->vdev_path, ZVOL_DIR,
@@ -1075,6 +1091,7 @@ vdev_uses_zvols(vdev_t *vd)
        for (c = 0; c < vd->vdev_children; c++)
                if (vdev_uses_zvols(vd->vdev_child[c]))
                        return (B_TRUE);
+#endif
        return (B_FALSE);
 }
 
@@ -1412,8 +1429,8 @@ vdev_validate(vdev_t *vd)
 void
 vdev_close(vdev_t *vd)
 {
-       spa_t *spa = vd->vdev_spa;
        vdev_t *pvd = vd->vdev_parent;
+       ASSERTV(spa_t *spa = vd->vdev_spa);
 
        ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
 
@@ -1795,8 +1812,7 @@ vdev_dtl_sync(vdev_t *vd, uint64_t txg)
 
        if (vd->vdev_detached) {
                if (smo->smo_object != 0) {
-                       int err = dmu_object_free(mos, smo->smo_object, tx);
-                       ASSERT3U(err, ==, 0);
+                       VERIFY(0 == dmu_object_free(mos, smo->smo_object, tx));
                        smo->smo_object = 0;
                }
                dmu_tx_commit(tx);
@@ -2034,7 +2050,7 @@ vdev_sync_done(vdev_t *vd, uint64_t txg)
 
        ASSERT(!vd->vdev_ishole);
 
-       while (msp = txg_list_remove(&vd->vdev_ms_list, TXG_CLEAN(txg)))
+       while ((msp = txg_list_remove(&vd->vdev_ms_list, TXG_CLEAN(txg))))
                metaslab_sync_done(msp, txg);
 
        if (reassess)
@@ -2387,7 +2403,7 @@ vdev_clear(spa_t *spa, vdev_t *vd)
                if (vd->vdev_aux == NULL && !vdev_is_dead(vd))
                        spa_async_request(spa, SPA_ASYNC_RESILVER);
 
-               spa_event_notify(spa, vd, ESC_ZFS_VDEV_CLEAR);
+               spa_event_notify(spa, vd, FM_EREPORT_ZFS_DEVICE_CLEAR);
        }
 
        /*
@@ -3042,13 +3058,17 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
 
 /*
  * Check the vdev configuration to ensure that it's capable of supporting
- * a root pool. Currently, we do not support RAID-Z or partial configuration.
- * In addition, only a single top-level vdev is allowed and none of the leaves
- * can be wholedisks.
+ * a root pool.
  */
 boolean_t
 vdev_is_bootable(vdev_t *vd)
 {
+#if defined(__sun__) || defined(__sun)
+       /*
+        * Currently, we do not support RAID-Z or partial configuration.
+        * In addition, only a single top-level vdev is allowed and none of the
+        * leaves can be wholedisks.
+        */
        int c;
 
        if (!vd->vdev_ops->vdev_op_leaf) {
@@ -3069,6 +3089,7 @@ vdev_is_bootable(vdev_t *vd)
                if (!vdev_is_bootable(vd->vdev_child[c]))
                        return (B_FALSE);
        }
+#endif /* __sun__ || __sun */
        return (B_TRUE);
 }
 
@@ -3084,7 +3105,8 @@ vdev_load_log_state(vdev_t *nvd, vdev_t *ovd)
        int c;
 
        ASSERT(nvd->vdev_top->vdev_islog);
-       ASSERT(spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
+       ASSERT(spa_config_held(nvd->vdev_spa,
+           SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
        ASSERT3U(nvd->vdev_guid, ==, ovd->vdev_guid);
 
        for (c = 0; c < nvd->vdev_children; c++)
@@ -3155,3 +3177,14 @@ vdev_split(vdev_t *vd)
        }
        vdev_propagate_state(cvd);
 }
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(vdev_fault);
+EXPORT_SYMBOL(vdev_degrade);
+EXPORT_SYMBOL(vdev_online);
+EXPORT_SYMBOL(vdev_offline);
+EXPORT_SYMBOL(vdev_clear);
+
+module_param(zfs_scrub_limit, int, 0644);
+MODULE_PARM_DESC(zfs_scrub_limit, "Max scrub/resilver I/O per leaf vdev");
+#endif