Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
#include <sys/space_map.h> | #include <sys/space_map.h> | ||||
#include <sys/space_reftree.h> | #include <sys/space_reftree.h> | ||||
#include <sys/zio.h> | #include <sys/zio.h> | ||||
#include <sys/zap.h> | #include <sys/zap.h> | ||||
#include <sys/fs/zfs.h> | #include <sys/fs/zfs.h> | ||||
#include <sys/arc.h> | #include <sys/arc.h> | ||||
#include <sys/zil.h> | #include <sys/zil.h> | ||||
#include <sys/dsl_scan.h> | #include <sys/dsl_scan.h> | ||||
#include <sys/vdev_raidz.h> | |||||
#include <sys/abd.h> | #include <sys/abd.h> | ||||
#include <sys/trim_map.h> | #include <sys/trim_map.h> | ||||
SYSCTL_DECL(_vfs_zfs); | SYSCTL_DECL(_vfs_zfs); | ||||
SYSCTL_NODE(_vfs_zfs, OID_AUTO, vdev, CTLFLAG_RW, 0, "ZFS VDEV"); | SYSCTL_NODE(_vfs_zfs, OID_AUTO, vdev, CTLFLAG_RW, 0, "ZFS VDEV"); | ||||
/* | /* | ||||
* Virtual device management. | * Virtual device management. | ||||
▲ Show 20 Lines • Show All 519 Lines • ▼ Show 20 Lines | |||||
* different for each case. | * different for each case. | ||||
*/ | */ | ||||
int | int | ||||
vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, | vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, | ||||
int alloctype) | int alloctype) | ||||
{ | { | ||||
vdev_ops_t *ops; | vdev_ops_t *ops; | ||||
char *type; | char *type; | ||||
uint64_t guid = 0, islog, nparity; | uint64_t guid = 0, islog; | ||||
vdev_t *vd; | vdev_t *vd; | ||||
vdev_indirect_config_t *vic; | vdev_indirect_config_t *vic; | ||||
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); | ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); | ||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0) | if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0) | ||||
return (SET_ERROR(EINVAL)); | return (SET_ERROR(EINVAL)); | ||||
Show All 36 Lines | vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, | ||||
islog = 0; | islog = 0; | ||||
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &islog); | (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &islog); | ||||
if (islog && spa_version(spa) < SPA_VERSION_SLOGS) | if (islog && spa_version(spa) < SPA_VERSION_SLOGS) | ||||
return (SET_ERROR(ENOTSUP)); | return (SET_ERROR(ENOTSUP)); | ||||
if (ops == &vdev_hole_ops && spa_version(spa) < SPA_VERSION_HOLES) | if (ops == &vdev_hole_ops && spa_version(spa) < SPA_VERSION_HOLES) | ||||
return (SET_ERROR(ENOTSUP)); | return (SET_ERROR(ENOTSUP)); | ||||
/* | void *tsd = NULL; | ||||
* Set the nparity property for RAID-Z vdevs. | int nparity = 0; | ||||
*/ | |||||
nparity = -1ULL; | |||||
if (ops == &vdev_raidz_ops) { | if (ops == &vdev_raidz_ops) { | ||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY, | vdev_raidz_t *rz = tsd = vdev_raidz_get_tsd(spa, nv); | ||||
&nparity) == 0) { | if (rz == NULL) | ||||
if (nparity == 0 || nparity > VDEV_RAIDZ_MAXPARITY) | |||||
return (SET_ERROR(EINVAL)); | return (SET_ERROR(EINVAL)); | ||||
/* | nparity = rz->vd_nparity; | ||||
* Previous versions could only support 1 or 2 parity | |||||
* device. | |||||
*/ | |||||
if (nparity > 1 && | |||||
spa_version(spa) < SPA_VERSION_RAIDZ2) | |||||
return (SET_ERROR(ENOTSUP)); | |||||
if (nparity > 2 && | |||||
spa_version(spa) < SPA_VERSION_RAIDZ3) | |||||
return (SET_ERROR(ENOTSUP)); | |||||
} else { | |||||
/* | |||||
* We require the parity to be specified for SPAs that | |||||
* support multiple parity levels. | |||||
*/ | |||||
if (spa_version(spa) >= SPA_VERSION_RAIDZ2) | |||||
return (SET_ERROR(EINVAL)); | |||||
/* | |||||
* Otherwise, we default to 1 parity device for RAID-Z. | |||||
*/ | |||||
nparity = 1; | |||||
} | } | ||||
} else { | |||||
nparity = 0; | |||||
} | |||||
ASSERT(nparity != -1ULL); | |||||
vd = vdev_alloc_common(spa, id, guid, ops); | vd = vdev_alloc_common(spa, id, guid, ops); | ||||
vic = &vd->vdev_indirect_config; | vic = &vd->vdev_indirect_config; | ||||
vd->vdev_islog = islog; | vd->vdev_islog = islog; | ||||
vd->vdev_nparity = nparity; | vd->vdev_nparity = nparity; | ||||
vd->vdev_tsd = tsd; | |||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &vd->vdev_path) == 0) | if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &vd->vdev_path) == 0) | ||||
vd->vdev_path = spa_strdup(vd->vdev_path); | vd->vdev_path = spa_strdup(vd->vdev_path); | ||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &vd->vdev_devid) == 0) | if (nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &vd->vdev_devid) == 0) | ||||
vd->vdev_devid = spa_strdup(vd->vdev_devid); | vd->vdev_devid = spa_strdup(vd->vdev_devid); | ||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PHYS_PATH, | if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PHYS_PATH, | ||||
&vd->vdev_physpath) == 0) | &vd->vdev_physpath) == 0) | ||||
vd->vdev_physpath = spa_strdup(vd->vdev_physpath); | vd->vdev_physpath = spa_strdup(vd->vdev_physpath); | ||||
▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | vdev_free(vdev_t *vd) | ||||
* Free all children. | * Free all children. | ||||
*/ | */ | ||||
for (int c = 0; c < vd->vdev_children; c++) | for (int c = 0; c < vd->vdev_children; c++) | ||||
vdev_free(vd->vdev_child[c]); | vdev_free(vd->vdev_child[c]); | ||||
ASSERT(vd->vdev_child == NULL); | ASSERT(vd->vdev_child == NULL); | ||||
ASSERT(vd->vdev_guid_sum == vd->vdev_guid); | ASSERT(vd->vdev_guid_sum == vd->vdev_guid); | ||||
if (vd->vdev_ops == &vdev_raidz_ops) { | |||||
vdev_raidz_t *rz = vd->vdev_tsd; | |||||
kmem_free(rz, sizeof(*rz)); | |||||
} | |||||
/* | /* | ||||
* Discard allocation state. | * Discard allocation state. | ||||
*/ | */ | ||||
if (vd->vdev_mg != NULL) { | if (vd->vdev_mg != NULL) { | ||||
vdev_metaslab_fini(vd); | vdev_metaslab_fini(vd); | ||||
metaslab_group_destroy(vd->vdev_mg); | metaslab_group_destroy(vd->vdev_mg); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,290 Lines • ▼ Show 20 Lines | vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) | ||||
boolean_t wasoffline; | boolean_t wasoffline; | ||||
vdev_state_t oldstate; | vdev_state_t oldstate; | ||||
spa_vdev_state_enter(spa, SCL_NONE); | spa_vdev_state_enter(spa, SCL_NONE); | ||||
if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) | if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) | ||||
return (spa_vdev_state_exit(spa, NULL, ENODEV)); | return (spa_vdev_state_exit(spa, NULL, ENODEV)); | ||||
#if 0 | |||||
if (!vd->vdev_ops->vdev_op_leaf) | if (!vd->vdev_ops->vdev_op_leaf) | ||||
return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); | return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); | ||||
#endif | |||||
wasoffline = (vd->vdev_offline || vd->vdev_tmpoffline); | wasoffline = (vd->vdev_offline || vd->vdev_tmpoffline); | ||||
oldstate = vd->vdev_state; | oldstate = vd->vdev_state; | ||||
tvd = vd->vdev_top; | tvd = vd->vdev_top; | ||||
vd->vdev_offline = B_FALSE; | vd->vdev_offline = B_FALSE; | ||||
vd->vdev_tmpoffline = B_FALSE; | vd->vdev_tmpoffline = B_FALSE; | ||||
vd->vdev_checkremove = !!(flags & ZFS_ONLINE_CHECKREMOVE); | vd->vdev_checkremove = !!(flags & ZFS_ONLINE_CHECKREMOVE); | ||||
▲ Show 20 Lines • Show All 1,065 Lines • Show Last 20 Lines |