Set RPM_DEFINE_COMMON options
[zfs.git] / module / zfs / vdev.c
index 205a1d1..afff4d4 100644 (file)
@@ -42,6 +42,7 @@
 #include <sys/arc.h>
 #include <sys/zil.h>
 #include <sys/dsl_scan.h>
+#include <sys/zvol.h>
 
 /*
  * Virtual device management.
@@ -904,6 +905,8 @@ vdev_metaslab_fini(vdev_t *vd)
                kmem_free(vd->vdev_ms, count * sizeof (metaslab_t *));
                vd->vdev_ms = NULL;
        }
+
+       ASSERT3U(vd->vdev_pending_fastwrite, ==, 0);
 }
 
 typedef struct vdev_probe_stats {
@@ -1072,27 +1075,20 @@ vdev_open_child(void *arg)
        vd->vdev_open_thread = NULL;
 }
 
-boolean_t
+static 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,
-           strlen(ZVOL_DIR)) == 0)
+#ifdef _KERNEL
+       if (zvol_is_zvol(vd->vdev_path))
                return (B_TRUE);
+#endif
+
        for (c = 0; c < vd->vdev_children; c++)
                if (vdev_uses_zvols(vd->vdev_child[c]))
                        return (B_TRUE);
-#endif
+
        return (B_FALSE);
 }
 
@@ -1262,20 +1258,24 @@ vdev_open(vdev_t *vd)
        if (vd->vdev_asize == 0) {
                /*
                 * This is the first-ever open, so use the computed values.
-                * For testing purposes, a higher ashift can be requested.
+                * For compatibility, a different ashift can be requested.
                 */
                vd->vdev_asize = asize;
                vd->vdev_max_asize = max_asize;
-               vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
+               if (vd->vdev_ashift == 0)
+                       vd->vdev_ashift = ashift;
        } else {
                /*
-                * Make sure the alignment requirement hasn't increased.
+                * Detect if the alignment requirement has increased.
+                * We don't want to make the pool unavailable, just
+                * post an event instead.
                 */
-               if (ashift > vd->vdev_top->vdev_ashift) {
-                       vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
-                           VDEV_AUX_BAD_LABEL);
-                       return (EINVAL);
+               if (ashift > vd->vdev_top->vdev_ashift &&
+                   vd->vdev_ops->vdev_op_leaf) {
+                       zfs_ereport_post(FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT,
+                           spa, vd, NULL, 0, 0);
                }
+
                vd->vdev_max_asize = max_asize;
        }
 
@@ -1349,8 +1349,10 @@ vdev_validate(vdev_t *vd, boolean_t strict)
        if (vd->vdev_ops->vdev_op_leaf && vdev_readable(vd)) {
                uint64_t aux_guid = 0;
                nvlist_t *nvl;
+               uint64_t txg = spa_last_synced_txg(spa) != 0 ?
+                   spa_last_synced_txg(spa) : -1ULL;
 
-               if ((label = vdev_label_read_config(vd)) == NULL) {
+               if ((label = vdev_label_read_config(vd, txg)) == NULL) {
                        vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
                            VDEV_AUX_BAD_LABEL);
                        return (0);
@@ -1994,14 +1996,14 @@ vdev_validate_aux(vdev_t *vd)
        if (!vdev_readable(vd))
                return (0);
 
-       if ((label = vdev_label_read_config(vd)) == NULL) {
+       if ((label = vdev_label_read_config(vd, -1ULL)) == NULL) {
                vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
                    VDEV_AUX_CORRUPT_DATA);
                return (-1);
        }
 
        if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, &version) != 0 ||
-           version > SPA_VERSION ||
+           !SPA_VERSION_IS_SUPPORTED(version) ||
            nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid) != 0 ||
            guid != vd->vdev_guid ||
            nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, &state) != 0) {