summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorGeorge Amanakis <[email protected]>2020-05-06 13:32:28 -0400
committerGitHub <[email protected]>2020-05-06 10:32:28 -0700
commit1b664952ae34d28c0408c20947f8aa5420c4ab63 (patch)
treeb802421507dee5ff43acb4c3fd550a2770e74036 /module/zfs
parentddc7a2dd3b099c280b4f3ed978f16fa6bd7012c0 (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')
-rw-r--r--module/zfs/spa.c12
-rw-r--r--module/zfs/vdev_root.c3
2 files changed, 11 insertions, 4 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;
/*
diff --git a/module/zfs/vdev_root.c b/module/zfs/vdev_root.c
index 7170f7013..ce79f7c73 100644
--- a/module/zfs/vdev_root.c
+++ b/module/zfs/vdev_root.c
@@ -98,7 +98,8 @@ vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
for (int c = 0; c < vd->vdev_children; c++) {
vdev_t *cvd = vd->vdev_child[c];
- if (cvd->vdev_open_error && !cvd->vdev_islog) {
+ if (cvd->vdev_open_error && !cvd->vdev_islog &&
+ cvd->vdev_ops != &vdev_indirect_ops) {
lasterror = cvd->vdev_open_error;
numerrors++;
}