Wrap smp_processor_id in kpreempt_[dis|en]able
[zfs.git] / module / zfs / vdev.c
index 92f67ba..0c8ce1b 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) {
@@ -492,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 ||
@@ -669,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;
 
@@ -1305,13 +1310,18 @@ vdev_open(vdev_t *vd)
  * contents.  This needs to be done before vdev_load() so that we don't
  * inadvertently do repair I/Os to the wrong device.
  *
+ * If 'strict' is false ignore the spa guid check. This is necessary because
+ * if the machine crashed during a re-guid the new guid might have been written
+ * to all of the vdev labels, but not the cached config. The strict check
+ * will be performed when the pool is opened again using the mos config.
+ *
  * This function will only return failure if one of the vdevs indicates that it
  * has since been destroyed or exported.  This is only possible if
  * /etc/zfs/zpool.cache was readonly at the time.  Otherwise, the vdev state
  * will be updated but the function will return 0.
  */
 int
-vdev_validate(vdev_t *vd)
+vdev_validate(vdev_t *vd, boolean_t strict)
 {
        spa_t *spa = vd->vdev_spa;
        nvlist_t *label;
@@ -1320,7 +1330,7 @@ vdev_validate(vdev_t *vd)
        int c;
 
        for (c = 0; c < vd->vdev_children; c++)
-               if (vdev_validate(vd->vdev_child[c]) != 0)
+               if (vdev_validate(vd->vdev_child[c], strict) != 0)
                        return (EBADF);
 
        /*
@@ -1350,8 +1360,9 @@ vdev_validate(vdev_t *vd)
                        return (0);
                }
 
-               if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID,
-                   &guid) != 0 || guid != spa_guid(spa)) {
+               if (strict && (nvlist_lookup_uint64(label,
+                   ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
+                   guid != spa_guid(spa))) {
                        vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN,
                            VDEV_AUX_CORRUPT_DATA);
                        nvlist_free(label);
@@ -1514,7 +1525,7 @@ vdev_reopen(vdev_t *vd)
                    !l2arc_vdev_present(vd))
                        l2arc_add_vdev(spa, vd);
        } else {
-               (void) vdev_validate(vd);
+               (void) vdev_validate(vd, B_TRUE);
        }
 
        /*
@@ -3053,13 +3064,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) {
@@ -3080,6 +3095,7 @@ vdev_is_bootable(vdev_t *vd)
                if (!vdev_is_bootable(vd->vdev_child[c]))
                        return (B_FALSE);
        }
+#endif /* __sun__ || __sun */
        return (B_TRUE);
 }
 
@@ -3174,4 +3190,7 @@ 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