usr/src/uts/common/fs/zfs/zfs_ioctl.c
changeset 12527 693dd2cad55f
parent 12296 7cf402a7f374
child 12620 12fcd99a642d
equal deleted inserted replaced
12526:6f48102ad665 12527:693dd2cad55f
    58 #include <sys/mount.h>
    58 #include <sys/mount.h>
    59 #include <sys/sdt.h>
    59 #include <sys/sdt.h>
    60 #include <sys/fs/zfs.h>
    60 #include <sys/fs/zfs.h>
    61 #include <sys/zfs_ctldir.h>
    61 #include <sys/zfs_ctldir.h>
    62 #include <sys/zfs_dir.h>
    62 #include <sys/zfs_dir.h>
       
    63 #include <sys/zfs_onexit.h>
    63 #include <sys/zvol.h>
    64 #include <sys/zvol.h>
    64 #include <sys/dsl_scan.h>
    65 #include <sys/dsl_scan.h>
    65 #include <sharefs/share.h>
    66 #include <sharefs/share.h>
    66 #include <sys/dmu_objset.h>
    67 #include <sys/dmu_objset.h>
    67 
    68 
  3340  * zc_value		name of snapshot to create
  3341  * zc_value		name of snapshot to create
  3341  * zc_string		name of clone origin (if DRR_FLAG_CLONE)
  3342  * zc_string		name of clone origin (if DRR_FLAG_CLONE)
  3342  * zc_cookie		file descriptor to recv from
  3343  * zc_cookie		file descriptor to recv from
  3343  * zc_begin_record	the BEGIN record of the stream (not byteswapped)
  3344  * zc_begin_record	the BEGIN record of the stream (not byteswapped)
  3344  * zc_guid		force flag
  3345  * zc_guid		force flag
       
  3346  * zc_cleanup_fd	cleanup-on-exit file descriptor
       
  3347  * zc_action_handle	handle for this guid/ds mapping (or zero on first call)
  3345  *
  3348  *
  3346  * outputs:
  3349  * outputs:
  3347  * zc_cookie		number of bytes read
  3350  * zc_cookie		number of bytes read
  3348  * zc_nvlist_dst{_size} error for each unapplied received property
  3351  * zc_nvlist_dst{_size} error for each unapplied received property
  3349  * zc_obj		zprop_errflags_t
  3352  * zc_obj		zprop_errflags_t
       
  3353  * zc_action_handle	handle for this guid/ds mapping
  3350  */
  3354  */
  3351 static int
  3355 static int
  3352 zfs_ioc_recv(zfs_cmd_t *zc)
  3356 zfs_ioc_recv(zfs_cmd_t *zc)
  3353 {
  3357 {
  3354 	file_t *fp;
  3358 	file_t *fp;
  3473 		 */
  3477 		 */
  3474 		props_error = EINVAL;
  3478 		props_error = EINVAL;
  3475 	}
  3479 	}
  3476 
  3480 
  3477 	off = fp->f_offset;
  3481 	off = fp->f_offset;
  3478 	error = dmu_recv_stream(&drc, fp->f_vnode, &off);
  3482 	error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
       
  3483 	    &zc->zc_action_handle);
  3479 
  3484 
  3480 	if (error == 0) {
  3485 	if (error == 0) {
  3481 		zfsvfs_t *zfsvfs = NULL;
  3486 		zfsvfs_t *zfsvfs = NULL;
  3482 
  3487 
  3483 		if (getzfsvfs(tofs, &zfsvfs) == 0) {
  3488 		if (getzfsvfs(tofs, &zfsvfs) == 0) {
  4180 	return (error);
  4185 	return (error);
  4181 }
  4186 }
  4182 
  4187 
  4183 /*
  4188 /*
  4184  * inputs:
  4189  * inputs:
  4185  * zc_name	name of filesystem
  4190  * zc_name		name of filesystem
  4186  * zc_value	short name of snap
  4191  * zc_value		short name of snap
  4187  * zc_string	user-supplied tag for this reference
  4192  * zc_string		user-supplied tag for this hold
  4188  * zc_cookie	recursive flag
  4193  * zc_cookie		recursive flag
  4189  * zc_temphold	set if hold is temporary
  4194  * zc_temphold		set if hold is temporary
       
  4195  * zc_cleanup_fd	cleanup-on-exit file descriptor for calling process
  4190  *
  4196  *
  4191  * outputs:		none
  4197  * outputs:		none
  4192  */
  4198  */
  4193 static int
  4199 static int
  4194 zfs_ioc_hold(zfs_cmd_t *zc)
  4200 zfs_ioc_hold(zfs_cmd_t *zc)
  4197 
  4203 
  4198 	if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
  4204 	if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
  4199 		return (EINVAL);
  4205 		return (EINVAL);
  4200 
  4206 
  4201 	return (dsl_dataset_user_hold(zc->zc_name, zc->zc_value,
  4207 	return (dsl_dataset_user_hold(zc->zc_name, zc->zc_value,
  4202 	    zc->zc_string, recursive, zc->zc_temphold));
  4208 	    zc->zc_string, recursive, zc->zc_temphold, zc->zc_cleanup_fd));
  4203 }
  4209 }
  4204 
  4210 
  4205 /*
  4211 /*
  4206  * inputs:
  4212  * inputs:
  4207  * zc_name	name of dataset from which we're releasing a user reference
  4213  * zc_name	name of dataset from which we're releasing a user hold
  4208  * zc_value	short name of snap
  4214  * zc_value	short name of snap
  4209  * zc_string	user-supplied tag for this reference
  4215  * zc_string	user-supplied tag for this hold
  4210  * zc_cookie	recursive flag
  4216  * zc_cookie	recursive flag
  4211  *
  4217  *
  4212  * outputs:		none
  4218  * outputs:	none
  4213  */
  4219  */
  4214 static int
  4220 static int
  4215 zfs_ioc_release(zfs_cmd_t *zc)
  4221 zfs_ioc_release(zfs_cmd_t *zc)
  4216 {
  4222 {
  4217 	boolean_t recursive = zc->zc_cookie;
  4223 	boolean_t recursive = zc->zc_cookie;
  4367 		spa_close(spa, FTAG);
  4373 		spa_close(spa, FTAG);
  4368 	}
  4374 	}
  4369 	return (error);
  4375 	return (error);
  4370 }
  4376 }
  4371 
  4377 
       
  4378 /*
       
  4379  * Find a free minor number.
       
  4380  */
       
  4381 minor_t
       
  4382 zfsdev_minor_alloc(void)
       
  4383 {
       
  4384 	static minor_t last_minor;
       
  4385 	minor_t m;
       
  4386 
       
  4387 	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
       
  4388 
       
  4389 	for (m = last_minor + 1; m != last_minor; m++) {
       
  4390 		if (m > ZFSDEV_MAX_MINOR)
       
  4391 			m = 1;
       
  4392 		if (ddi_get_soft_state(zfsdev_state, m) == NULL) {
       
  4393 			last_minor = m;
       
  4394 			return (m);
       
  4395 		}
       
  4396 	}
       
  4397 
       
  4398 	return (0);
       
  4399 }
       
  4400 
       
  4401 static int
       
  4402 zfs_ctldev_init(dev_t *devp)
       
  4403 {
       
  4404 	minor_t minor;
       
  4405 	zfs_soft_state_t *zs;
       
  4406 
       
  4407 	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
       
  4408 	ASSERT(getminor(*devp) == 0);
       
  4409 
       
  4410 	minor = zfsdev_minor_alloc();
       
  4411 	if (minor == 0)
       
  4412 		return (ENXIO);
       
  4413 
       
  4414 	if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS)
       
  4415 		return (EAGAIN);
       
  4416 
       
  4417 	*devp = makedevice(getemajor(*devp), minor);
       
  4418 
       
  4419 	zs = ddi_get_soft_state(zfsdev_state, minor);
       
  4420 	zs->zss_type = ZSST_CTLDEV;
       
  4421 	zfs_onexit_init((zfs_onexit_t **)&zs->zss_data);
       
  4422 
       
  4423 	return (0);
       
  4424 }
       
  4425 
       
  4426 static void
       
  4427 zfs_ctldev_destroy(zfs_onexit_t *zo, minor_t minor)
       
  4428 {
       
  4429 	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
       
  4430 
       
  4431 	zfs_onexit_destroy(zo);
       
  4432 	ddi_soft_state_free(zfsdev_state, minor);
       
  4433 }
       
  4434 
       
  4435 void *
       
  4436 zfsdev_get_soft_state(minor_t minor, enum zfs_soft_state_type which)
       
  4437 {
       
  4438 	zfs_soft_state_t *zp;
       
  4439 
       
  4440 	zp = ddi_get_soft_state(zfsdev_state, minor);
       
  4441 	if (zp == NULL || zp->zss_type != which)
       
  4442 		return (NULL);
       
  4443 
       
  4444 	return (zp->zss_data);
       
  4445 }
       
  4446 
       
  4447 static int
       
  4448 zfsdev_open(dev_t *devp, int flag, int otyp, cred_t *cr)
       
  4449 {
       
  4450 	int error = 0;
       
  4451 
       
  4452 	if (getminor(*devp) != 0)
       
  4453 		return (zvol_open(devp, flag, otyp, cr));
       
  4454 
       
  4455 	/* This is the control device. Allocate a new minor if requested. */
       
  4456 	if (flag & FEXCL) {
       
  4457 		mutex_enter(&zfsdev_state_lock);
       
  4458 		error = zfs_ctldev_init(devp);
       
  4459 		mutex_exit(&zfsdev_state_lock);
       
  4460 	}
       
  4461 
       
  4462 	return (error);
       
  4463 }
       
  4464 
       
  4465 static int
       
  4466 zfsdev_close(dev_t dev, int flag, int otyp, cred_t *cr)
       
  4467 {
       
  4468 	zfs_onexit_t *zo;
       
  4469 	minor_t minor = getminor(dev);
       
  4470 
       
  4471 	if (minor == 0)
       
  4472 		return (0);
       
  4473 
       
  4474 	mutex_enter(&zfsdev_state_lock);
       
  4475 	zo = zfsdev_get_soft_state(minor, ZSST_CTLDEV);
       
  4476 	if (zo == NULL) {
       
  4477 		mutex_exit(&zfsdev_state_lock);
       
  4478 		return (zvol_close(dev, flag, otyp, cr));
       
  4479 	}
       
  4480 	zfs_ctldev_destroy(zo, minor);
       
  4481 	mutex_exit(&zfsdev_state_lock);
       
  4482 
       
  4483 	return (0);
       
  4484 }
       
  4485 
  4372 static int
  4486 static int
  4373 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
  4487 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
  4374 {
  4488 {
  4375 	zfs_cmd_t *zc;
  4489 	zfs_cmd_t *zc;
  4376 	uint_t vec;
  4490 	uint_t vec;
  4377 	int error, rc;
  4491 	int error, rc;
  4378 
  4492 	minor_t minor = getminor(dev);
  4379 	if (getminor(dev) != 0)
  4493 
       
  4494 	if (minor != 0 &&
       
  4495 	    zfsdev_get_soft_state(minor, ZSST_CTLDEV) == NULL)
  4380 		return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp));
  4496 		return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp));
  4381 
  4497 
  4382 	vec = cmd - ZFS_IOC;
  4498 	vec = cmd - ZFS_IOC;
  4383 	ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip));
  4499 	ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip));
  4384 
  4500 
  4497  *
  4613  *
  4498  * /dev/zfs has basically nothing to do except serve up ioctls,
  4614  * /dev/zfs has basically nothing to do except serve up ioctls,
  4499  * so most of the standard driver entry points are in zvol.c.
  4615  * so most of the standard driver entry points are in zvol.c.
  4500  */
  4616  */
  4501 static struct cb_ops zfs_cb_ops = {
  4617 static struct cb_ops zfs_cb_ops = {
  4502 	zvol_open,	/* open */
  4618 	zfsdev_open,	/* open */
  4503 	zvol_close,	/* close */
  4619 	zfsdev_close,	/* close */
  4504 	zvol_strategy,	/* strategy */
  4620 	zvol_strategy,	/* strategy */
  4505 	nodev,		/* print */
  4621 	nodev,		/* print */
  4506 	zvol_dump,	/* dump */
  4622 	zvol_dump,	/* dump */
  4507 	zvol_read,	/* read */
  4623 	zvol_read,	/* read */
  4508 	zvol_write,	/* write */
  4624 	zvol_write,	/* write */