diff options
author | George Amanakis <[email protected]> | 2020-05-06 13:32:28 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2020-05-06 10:32:28 -0700 |
commit | 1b664952ae34d28c0408c20947f8aa5420c4ab63 (patch) | |
tree | b802421507dee5ff43acb4c3fd550a2770e74036 /module/zfs/spa.c | |
parent | ddc7a2dd3b099c280b4f3ed978f16fa6bd7012c0 (diff) |
Enable splitting mirrors with indirect vdevs
When a top-level vdev is removed from a pool it is converted to an
indirect vdev. Until now splitting such mirrored pools was not possible
with zpool split. This patch enables handling of indirect vdevs and
splitting of those pools with zpool split.
Reviewed-by: Matthew Ahrens <[email protected]>
Reviewed by: Brian Behlendorf <[email protected]>
Signed-off-by: George Amanakis <[email protected]>
Closes #10283
Diffstat (limited to 'module/zfs/spa.c')
-rw-r--r-- | module/zfs/spa.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/module/zfs/spa.c b/module/zfs/spa.c index bd1e091ca..73d63f849 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -7297,7 +7297,8 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config, vdev_t *vd = rvd->vdev_child[c]; /* don't count the holes & logs as children */ - if (vd->vdev_islog || !vdev_is_concrete(vd)) { + if (vd->vdev_islog || (vd->vdev_ops != &vdev_indirect_ops && + !vdev_is_concrete(vd))) { if (lastlog == 0) lastlog = c; continue; @@ -7333,6 +7334,11 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config, } } + /* deal with indirect vdevs */ + if (spa->spa_root_vdev->vdev_child[c]->vdev_ops == + &vdev_indirect_ops) + continue; + /* which disk is going to be split? */ if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_GUID, &glist[c]) != 0) { @@ -7460,7 +7466,7 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config, offsetof(vdev_t, vdev_trim_node)); for (c = 0; c < children; c++) { - if (vml[c] != NULL) { + if (vml[c] != NULL && vml[c]->vdev_ops != &vdev_indirect_ops) { mutex_enter(&vml[c]->vdev_initialize_lock); vdev_initialize_stop(vml[c], VDEV_INITIALIZE_ACTIVE, &vd_initialize_list); @@ -7521,7 +7527,7 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config, if (error != 0) dmu_tx_abort(tx); for (c = 0; c < children; c++) { - if (vml[c] != NULL) { + if (vml[c] != NULL && vml[c]->vdev_ops != &vdev_indirect_ops) { vdev_t *tvd = vml[c]->vdev_top; /* |