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; |
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 */ |