#include <sys/arc.h>
#include <sys/zil.h>
#include <sys/dsl_scan.h>
+#include <sys/zvol.h>
/*
* Virtual device management.
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);
}
vd->vdev_ashift = MAX(ashift, vd->vdev_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;
}