usr/src/uts/common/fs/zfs/zfs_ioctl.c
changeset 5450 b25030891c44
parent 5446 51fbc14b301d
child 5498 334b476844ca
equal deleted inserted replaced
5449:12ad36a911ff 5450:b25030891c44
   961 static int
   961 static int
   962 zfs_ioc_vdev_add(zfs_cmd_t *zc)
   962 zfs_ioc_vdev_add(zfs_cmd_t *zc)
   963 {
   963 {
   964 	spa_t *spa;
   964 	spa_t *spa;
   965 	int error;
   965 	int error;
   966 	nvlist_t *config;
   966 	nvlist_t *config, **l2cache;
       
   967 	uint_t nl2cache;
   967 
   968 
   968 	error = spa_open(zc->zc_name, &spa, FTAG);
   969 	error = spa_open(zc->zc_name, &spa, FTAG);
   969 	if (error != 0)
   970 	if (error != 0)
   970 		return (error);
   971 		return (error);
       
   972 
       
   973 	error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
       
   974 	    &config);
       
   975 	(void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE,
       
   976 	    &l2cache, &nl2cache);
   971 
   977 
   972 	/*
   978 	/*
   973 	 * A root pool with concatenated devices is not supported.
   979 	 * A root pool with concatenated devices is not supported.
   974 	 * Thus, can not add a device to a root pool with one device.
   980 	 * Thus, can not add a device to a root pool with one device.
       
   981 	 * Allow for l2cache devices to be added.
   975 	 */
   982 	 */
   976 	if (spa->spa_root_vdev->vdev_children == 1 && spa->spa_bootfs != 0) {
   983 	if (spa->spa_root_vdev->vdev_children == 1 && spa->spa_bootfs != 0 &&
       
   984 	    nl2cache == 0) {
   977 		spa_close(spa, FTAG);
   985 		spa_close(spa, FTAG);
   978 		return (EDOM);
   986 		return (EDOM);
   979 	}
   987 	}
   980 
   988 
   981 	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
   989 	if (error == 0) {
   982 	    &config)) == 0) {
       
   983 		error = spa_vdev_add(spa, config);
   990 		error = spa_vdev_add(spa, config);
   984 		nvlist_free(config);
   991 		nvlist_free(config);
   985 	}
   992 	}
   986 	spa_close(spa, FTAG);
   993 	spa_close(spa, FTAG);
   987 	return (error);
   994 	return (error);
  2571 	txg = spa_vdev_enter(spa);
  2578 	txg = spa_vdev_enter(spa);
  2572 
  2579 
  2573 	if (zc->zc_guid == 0) {
  2580 	if (zc->zc_guid == 0) {
  2574 		vd = NULL;
  2581 		vd = NULL;
  2575 	} else if ((vd = spa_lookup_by_guid(spa, zc->zc_guid)) == NULL) {
  2582 	} else if ((vd = spa_lookup_by_guid(spa, zc->zc_guid)) == NULL) {
  2576 		(void) spa_vdev_exit(spa, NULL, txg, ENODEV);
  2583 		spa_aux_vdev_t *sav;
  2577 		spa_close(spa, FTAG);
  2584 		int i;
  2578 		return (ENODEV);
  2585 
       
  2586 		/*
       
  2587 		 * Check if this is an l2cache device.
       
  2588 		 */
       
  2589 		ASSERT(spa != NULL);
       
  2590 		sav = &spa->spa_l2cache;
       
  2591 		for (i = 0; i < sav->sav_count; i++) {
       
  2592 			if (sav->sav_vdevs[i]->vdev_guid == zc->zc_guid) {
       
  2593 				vd = sav->sav_vdevs[i];
       
  2594 				break;
       
  2595 			}
       
  2596 		}
       
  2597 
       
  2598 		if (vd == NULL) {
       
  2599 			(void) spa_vdev_exit(spa, NULL, txg, ENODEV);
       
  2600 			spa_close(spa, FTAG);
       
  2601 			return (ENODEV);
       
  2602 		}
  2579 	}
  2603 	}
  2580 
  2604 
  2581 	vdev_clear(spa, vd, B_TRUE);
  2605 	vdev_clear(spa, vd, B_TRUE);
  2582 
  2606 
  2583 	(void) spa_vdev_exit(spa, NULL, txg, 0);
  2607 	(void) spa_vdev_exit(spa, NULL, txg, 0);