MCPcopy Create free account
hub / github.com/F-Stack/f-stack / spa_vdev_attach

Function spa_vdev_attach

freebsd/contrib/openzfs/module/zfs/spa.c:6597–6858  ·  view source on GitHub ↗

* Attach a device to a mirror. The arguments are the path to any device * in the mirror, and the nvroot for the new device. If the path specifies * a device that is not mirrored, we automatically insert the mirror vdev. * * If 'replacing' is specified, the new device is intended to replace the * existing device; in this case the two devices are made into their own * mirror using the 'repla

Source from the content-addressed store, hash-verified

6595 * an administrators perspective these are both resilver operations.
6596 */
6597int
6598spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
6599 int rebuild)
6600{
6601 uint64_t txg, dtl_max_txg;
6602 vdev_t *rvd = spa->spa_root_vdev;
6603 vdev_t *oldvd, *newvd, *newrootvd, *pvd, *tvd;
6604 vdev_ops_t *pvops;
6605 char *oldvdpath, *newvdpath;
6606 int newvd_isspare;
6607 int error;
6608
6609 ASSERT(spa_writeable(spa));
6610
6611 txg = spa_vdev_enter(spa);
6612
6613 oldvd = spa_lookup_by_guid(spa, guid, B_FALSE);
6614
6615 ASSERT(MUTEX_HELD(&spa_namespace_lock));
6616 if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
6617 error = (spa_has_checkpoint(spa)) ?
6618 ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
6619 return (spa_vdev_exit(spa, NULL, txg, error));
6620 }
6621
6622 if (rebuild) {
6623 if (!spa_feature_is_enabled(spa, SPA_FEATURE_DEVICE_REBUILD))
6624 return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
6625
6626 if (dsl_scan_resilvering(spa_get_dsl(spa)))
6627 return (spa_vdev_exit(spa, NULL, txg,
6628 ZFS_ERR_RESILVER_IN_PROGRESS));
6629 } else {
6630 if (vdev_rebuild_active(rvd))
6631 return (spa_vdev_exit(spa, NULL, txg,
6632 ZFS_ERR_REBUILD_IN_PROGRESS));
6633 }
6634
6635 if (spa->spa_vdev_removal != NULL)
6636 return (spa_vdev_exit(spa, NULL, txg, EBUSY));
6637
6638 if (oldvd == NULL)
6639 return (spa_vdev_exit(spa, NULL, txg, ENODEV));
6640
6641 if (!oldvd->vdev_ops->vdev_op_leaf)
6642 return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
6643
6644 pvd = oldvd->vdev_parent;
6645
6646 if ((error = spa_config_parse(spa, &newrootvd, nvroot, NULL, 0,
6647 VDEV_ALLOC_ATTACH)) != 0)
6648 return (spa_vdev_exit(spa, NULL, txg, EINVAL));
6649
6650 if (newrootvd->vdev_children != 1)
6651 return (spa_vdev_exit(spa, newrootvd, txg, EINVAL));
6652
6653 newvd = newrootvd->vdev_child[0];
6654

Callers 2

zfs_ioc_vdev_attachFunction · 0.85
ztest_vdev_attach_detachFunction · 0.85

Calls 15

spa_writeableFunction · 0.85
spa_vdev_enterFunction · 0.85
spa_lookup_by_guidFunction · 0.85
spa_feature_is_activeFunction · 0.85
spa_has_checkpointFunction · 0.85
spa_vdev_exitFunction · 0.85
spa_feature_is_enabledFunction · 0.85
dsl_scan_resilveringFunction · 0.85
spa_get_dslFunction · 0.85
vdev_rebuild_activeFunction · 0.85
spa_config_parseFunction · 0.85
vdev_createFunction · 0.85

Tested by 1

ztest_vdev_attach_detachFunction · 0.68