Deleted Added
full compact
zfs_ioctl.c (208472) zfs_ioctl.c (209962)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 5 unchanged lines hidden (view full) ---

14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/types.h>
27#include <sys/param.h>
28#include <sys/systm.h>
29#include <sys/conf.h>
30#include <sys/kernel.h>

--- 5 unchanged lines hidden (view full) ---

36#include <sys/uio.h>
37#include <sys/buf.h>
38#include <sys/file.h>
39#include <sys/kmem.h>
40#include <sys/conf.h>
41#include <sys/cmn_err.h>
42#include <sys/stat.h>
43#include <sys/zfs_ioctl.h>
23 * Use is subject to license terms.
24 */
25
26#include <sys/types.h>
27#include <sys/param.h>
28#include <sys/systm.h>
29#include <sys/conf.h>
30#include <sys/kernel.h>

--- 5 unchanged lines hidden (view full) ---

36#include <sys/uio.h>
37#include <sys/buf.h>
38#include <sys/file.h>
39#include <sys/kmem.h>
40#include <sys/conf.h>
41#include <sys/cmn_err.h>
42#include <sys/stat.h>
43#include <sys/zfs_ioctl.h>
44#include <sys/zfs_vfsops.h>
44#include <sys/zfs_znode.h>
45#include <sys/zap.h>
46#include <sys/spa.h>
47#include <sys/spa_impl.h>
48#include <sys/vdev.h>
49#include <sys/vdev_impl.h>
50#include <sys/dmu.h>
51#include <sys/dsl_dir.h>

--- 24 unchanged lines hidden (view full) ---

76static struct cdev *zfsdev;
77
78extern void zfs_init(void);
79extern void zfs_fini(void);
80
81typedef int zfs_ioc_func_t(zfs_cmd_t *);
82typedef int zfs_secpolicy_func_t(zfs_cmd_t *, cred_t *);
83
45#include <sys/zfs_znode.h>
46#include <sys/zap.h>
47#include <sys/spa.h>
48#include <sys/spa_impl.h>
49#include <sys/vdev.h>
50#include <sys/vdev_impl.h>
51#include <sys/dmu.h>
52#include <sys/dsl_dir.h>

--- 24 unchanged lines hidden (view full) ---

77static struct cdev *zfsdev;
78
79extern void zfs_init(void);
80extern void zfs_fini(void);
81
82typedef int zfs_ioc_func_t(zfs_cmd_t *);
83typedef int zfs_secpolicy_func_t(zfs_cmd_t *, cred_t *);
84
85typedef enum {
86 NO_NAME,
87 POOL_NAME,
88 DATASET_NAME
89} zfs_ioc_namecheck_t;
90
84typedef struct zfs_ioc_vec {
85 zfs_ioc_func_t *zvec_func;
86 zfs_secpolicy_func_t *zvec_secpolicy;
91typedef struct zfs_ioc_vec {
92 zfs_ioc_func_t *zvec_func;
93 zfs_secpolicy_func_t *zvec_secpolicy;
87 enum {
88 NO_NAME,
89 POOL_NAME,
90 DATASET_NAME
91 } zvec_namecheck;
94 zfs_ioc_namecheck_t zvec_namecheck;
92 boolean_t zvec_his_log;
95 boolean_t zvec_his_log;
96 boolean_t zvec_pool_check;
93} zfs_ioc_vec_t;
94
97} zfs_ioc_vec_t;
98
99/* This array is indexed by zfs_userquota_prop_t */
100static const char *userquota_perms[] = {
101 ZFS_DELEG_PERM_USERUSED,
102 ZFS_DELEG_PERM_USERQUOTA,
103 ZFS_DELEG_PERM_GROUPUSED,
104 ZFS_DELEG_PERM_GROUPQUOTA,
105};
106
107static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
95static void clear_props(char *dataset, nvlist_t *props, nvlist_t *newprops);
96static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
97 boolean_t *);
98int zfs_set_prop_nvlist(const char *, nvlist_t *);
99
100/* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
101void
102__dprintf(const char *file, const char *func, int line, const char *fmt, ...)

--- 283 unchanged lines hidden (view full) ---

386
387int
388zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr)
389{
390 return (zfs_secpolicy_write_perms(zc->zc_name,
391 ZFS_DELEG_PERM_SEND, cr));
392}
393
108static void clear_props(char *dataset, nvlist_t *props, nvlist_t *newprops);
109static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
110 boolean_t *);
111int zfs_set_prop_nvlist(const char *, nvlist_t *);
112
113/* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
114void
115__dprintf(const char *file, const char *func, int line, const char *fmt, ...)

--- 283 unchanged lines hidden (view full) ---

399
400int
401zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr)
402{
403 return (zfs_secpolicy_write_perms(zc->zc_name,
404 ZFS_DELEG_PERM_SEND, cr));
405}
406
407static int
408zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr)
409{
410 vnode_t *vp;
411 int error;
412
413 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
414 NO_FOLLOW, NULL, &vp)) != 0)
415 return (error);
416
417 /* Now make sure mntpnt and dataset are ZFS */
418
419 if (strcmp(vp->v_vfsp->mnt_stat.f_fstypename, "zfs") != 0 ||
420 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
421 zc->zc_name) != 0)) {
422 VN_RELE(vp);
423 return (EPERM);
424 }
425
426 VN_RELE(vp);
427 return (dsl_deleg_access(zc->zc_name,
428 ZFS_DELEG_PERM_SHARE, cr));
429}
430
394int
395zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr)
396{
397 if (!INGLOBALZONE(curthread))
398 return (EPERM);
399
400 if (secpolicy_nfs(cr) == 0) {
401 return (0);
402 } else {
431int
432zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr)
433{
434 if (!INGLOBALZONE(curthread))
435 return (EPERM);
436
437 if (secpolicy_nfs(cr) == 0) {
438 return (0);
439 } else {
403 vnode_t *vp;
404 int error;
440 return (zfs_secpolicy_deleg_share(zc, cr));
441 }
442}
405
443
406 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
407 NO_FOLLOW, NULL, &vp)) != 0)
408 return (error);
444int
445zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr)
446{
447 if (!INGLOBALZONE(curthread))
448 return (EPERM);
409
449
410 /* Now make sure mntpnt and dataset are ZFS */
411
412 if (strcmp(vp->v_vfsp->mnt_stat.f_fstypename, "zfs") != 0 ||
413 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
414 zc->zc_name) != 0)) {
415 VN_RELE(vp);
416 return (EPERM);
417 }
418
419 VN_RELE(vp);
420 return (dsl_deleg_access(zc->zc_name,
421 ZFS_DELEG_PERM_SHARE, cr));
450 if (secpolicy_smb(cr) == 0) {
451 return (0);
452 } else {
453 return (zfs_secpolicy_deleg_share(zc, cr));
422 }
423}
424
425static int
426zfs_get_parent(const char *datasetname, char *parent, int parentsize)
427{
428 char *cp;
429

--- 264 unchanged lines hidden (view full) ---

694
695 if (!INGLOBALZONE(curthread) && !zone_dataset_visible(dataset, &writable))
696 return (ENOENT);
697 if (secpolicy_zfs(cr) != 0 && !groupmember(GID_OPERATOR, cr))
698 return (EPERM);
699 return (0);
700}
701
454 }
455}
456
457static int
458zfs_get_parent(const char *datasetname, char *parent, int parentsize)
459{
460 char *cp;
461

--- 264 unchanged lines hidden (view full) ---

726
727 if (!INGLOBALZONE(curthread) && !zone_dataset_visible(dataset, &writable))
728 return (ENOENT);
729 if (secpolicy_zfs(cr) != 0 && !groupmember(GID_OPERATOR, cr))
730 return (EPERM);
731 return (0);
732}
733
734static int
735zfs_secpolicy_userspace_one(zfs_cmd_t *zc, cred_t *cr)
736{
737 int err = zfs_secpolicy_read(zc, cr);
738 if (err)
739 return (err);
740
741 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
742 return (EINVAL);
743
744 if (zc->zc_value[0] == 0) {
745 /*
746 * They are asking about a posix uid/gid. If it's
747 * themself, allow it.
748 */
749 if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
750 zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
751 if (zc->zc_guid == crgetuid(cr))
752 return (0);
753 } else {
754 if (groupmember(zc->zc_guid, cr))
755 return (0);
756 }
757 }
758
759 return (zfs_secpolicy_write_perms(zc->zc_name,
760 userquota_perms[zc->zc_objset_type], cr));
761}
762
763static int
764zfs_secpolicy_userspace_many(zfs_cmd_t *zc, cred_t *cr)
765{
766 int err = zfs_secpolicy_read(zc, cr);
767 if (err)
768 return (err);
769
770 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
771 return (EINVAL);
772
773 return (zfs_secpolicy_write_perms(zc->zc_name,
774 userquota_perms[zc->zc_objset_type], cr));
775}
776
777static int
778zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, cred_t *cr)
779{
780 return (zfs_secpolicy_setprop(zc->zc_name, ZFS_PROP_VERSION, cr));
781}
782
702/*
703 * Returns the nvlist as specified by the user in the zfs_cmd_t.
704 */
705static int
706get_nvlist(uint64_t nvl, uint64_t size, nvlist_t **nvp)
707{
708 char *packed;
709 int error;

--- 51 unchanged lines hidden (view full) ---

761 kmem_free(packed, size);
762 }
763
764 zc->zc_nvlist_dst_size = size;
765 return (error);
766}
767
768static int
783/*
784 * Returns the nvlist as specified by the user in the zfs_cmd_t.
785 */
786static int
787get_nvlist(uint64_t nvl, uint64_t size, nvlist_t **nvp)
788{
789 char *packed;
790 int error;

--- 51 unchanged lines hidden (view full) ---

842 kmem_free(packed, size);
843 }
844
845 zc->zc_nvlist_dst_size = size;
846 return (error);
847}
848
849static int
850getzfsvfs(const char *dsname, zfsvfs_t **zvp)
851{
852 objset_t *os;
853 int error;
854
855 error = dmu_objset_open(dsname, DMU_OST_ZFS,
856 DS_MODE_USER | DS_MODE_READONLY, &os);
857 if (error)
858 return (error);
859
860 mutex_enter(&os->os->os_user_ptr_lock);
861 *zvp = dmu_objset_get_user(os);
862 if (*zvp) {
863 VFS_HOLD((*zvp)->z_vfs);
864 } else {
865 error = ESRCH;
866 }
867 mutex_exit(&os->os->os_user_ptr_lock);
868 dmu_objset_close(os);
869 return (error);
870}
871
872/*
873 * Find a zfsvfs_t for a mounted filesystem, or create our own, in which
874 * case its z_vfs will be NULL, and it will be opened as the owner.
875 */
876static int
877zfsvfs_hold(const char *name, boolean_t readonly, void *tag, zfsvfs_t **zvp)
878{
879 int error = 0;
880 int mode = DS_MODE_OWNER | (readonly ? DS_MODE_READONLY : 0);
881
882 if (getzfsvfs(name, zvp) != 0)
883 error = zfsvfs_create(name, mode, zvp);
884 if (error == 0) {
885 rrw_enter(&(*zvp)->z_teardown_lock, RW_READER, tag);
886 if ((*zvp)->z_unmounted) {
887 /*
888 * XXX we could probably try again, since the unmounting
889 * thread should be just about to disassociate the
890 * objset from the zfsvfs.
891 */
892 rrw_exit(&(*zvp)->z_teardown_lock, tag);
893 return (EBUSY);
894 }
895 }
896 return (error);
897}
898
899static void
900zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
901{
902 rrw_exit(&zfsvfs->z_teardown_lock, tag);
903
904 if (zfsvfs->z_vfs) {
905 VFS_RELE(zfsvfs->z_vfs);
906 } else {
907 dmu_objset_close(zfsvfs->z_os);
908 zfsvfs_free(zfsvfs);
909 }
910}
911
912static int
769zfs_ioc_pool_create(zfs_cmd_t *zc)
770{
771 int error;
772 nvlist_t *config, *props = NULL;
773 nvlist_t *rootprops = NULL;
774 nvlist_t *zplprops = NULL;
775 char *buf;
776

--- 82 unchanged lines hidden (view full) ---

859 nvlist_free(config);
860 return (error);
861 }
862
863 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
864 guid != zc->zc_guid)
865 error = EINVAL;
866 else if (zc->zc_cookie)
913zfs_ioc_pool_create(zfs_cmd_t *zc)
914{
915 int error;
916 nvlist_t *config, *props = NULL;
917 nvlist_t *rootprops = NULL;
918 nvlist_t *zplprops = NULL;
919 char *buf;
920

--- 82 unchanged lines hidden (view full) ---

1003 nvlist_free(config);
1004 return (error);
1005 }
1006
1007 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
1008 guid != zc->zc_guid)
1009 error = EINVAL;
1010 else if (zc->zc_cookie)
867 error = spa_import_faulted(zc->zc_name, config,
1011 error = spa_import_verbatim(zc->zc_name, config,
868 props);
869 else
870 error = spa_import(zc->zc_name, config, props);
871
872 nvlist_free(config);
873
874 if (props)
875 nvlist_free(props);

--- 308 unchanged lines hidden (view full) ---

1184zfs_ioc_vdev_detach(zfs_cmd_t *zc)
1185{
1186 spa_t *spa;
1187 int error;
1188
1189 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1190 return (error);
1191
1012 props);
1013 else
1014 error = spa_import(zc->zc_name, config, props);
1015
1016 nvlist_free(config);
1017
1018 if (props)
1019 nvlist_free(props);

--- 308 unchanged lines hidden (view full) ---

1328zfs_ioc_vdev_detach(zfs_cmd_t *zc)
1329{
1330 spa_t *spa;
1331 int error;
1332
1333 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1334 return (error);
1335
1192 error = spa_vdev_detach(spa, zc->zc_guid, B_FALSE);
1336 error = spa_vdev_detach(spa, zc->zc_guid, 0, B_FALSE);
1193
1194 spa_close(spa, FTAG);
1195 return (error);
1196}
1197
1198static int
1199zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
1200{

--- 6 unchanged lines hidden (view full) ---

1207 if (error != 0)
1208 return (error);
1209
1210 error = spa_vdev_setpath(spa, guid, path);
1211 spa_close(spa, FTAG);
1212 return (error);
1213}
1214
1337
1338 spa_close(spa, FTAG);
1339 return (error);
1340}
1341
1342static int
1343zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
1344{

--- 6 unchanged lines hidden (view full) ---

1351 if (error != 0)
1352 return (error);
1353
1354 error = spa_vdev_setpath(spa, guid, path);
1355 spa_close(spa, FTAG);
1356 return (error);
1357}
1358
1359static int
1360zfs_ioc_vdev_setfru(zfs_cmd_t *zc)
1361{
1362 spa_t *spa;
1363 char *fru = zc->zc_value;
1364 uint64_t guid = zc->zc_guid;
1365 int error;
1366
1367 error = spa_open(zc->zc_name, &spa, FTAG);
1368 if (error != 0)
1369 return (error);
1370
1371 error = spa_vdev_setfru(spa, guid, fru);
1372 spa_close(spa, FTAG);
1373 return (error);
1374}
1375
1215/*
1216 * inputs:
1217 * zc_name name of filesystem
1218 * zc_nvlist_dst_size size of buffer for property nvlist
1219 *
1220 * outputs:
1221 * zc_objset_stats stats
1222 * zc_nvlist_dst property nvlist

--- 91 unchanged lines hidden (view full) ---

1314 nvlist_free(nv);
1315 } else {
1316 err = ENOENT;
1317 }
1318 dmu_objset_close(os);
1319 return (err);
1320}
1321
1376/*
1377 * inputs:
1378 * zc_name name of filesystem
1379 * zc_nvlist_dst_size size of buffer for property nvlist
1380 *
1381 * outputs:
1382 * zc_objset_stats stats
1383 * zc_nvlist_dst property nvlist

--- 91 unchanged lines hidden (view full) ---

1475 nvlist_free(nv);
1476 } else {
1477 err = ENOENT;
1478 }
1479 dmu_objset_close(os);
1480 return (err);
1481}
1482
1483static boolean_t
1484dataset_name_hidden(const char *name)
1485{
1486 /*
1487 * Skip over datasets that are not visible in this zone,
1488 * internal datasets (which have a $ in their name), and
1489 * temporary datasets (which have a % in their name).
1490 */
1491 if (strchr(name, '$') != NULL)
1492 return (B_TRUE);
1493 if (strchr(name, '%') != NULL)
1494 return (B_TRUE);
1495 if (!INGLOBALZONE(curthread) && !zone_dataset_visible(name, NULL))
1496 return (B_TRUE);
1497 return (B_FALSE);
1498}
1499
1322/*
1323 * inputs:
1324 * zc_name name of filesystem
1325 * zc_cookie zap cursor
1326 * zc_nvlist_dst_size size of buffer for property nvlist
1327 *
1328 * outputs:
1329 * zc_name name of next filesystem
1500/*
1501 * inputs:
1502 * zc_name name of filesystem
1503 * zc_cookie zap cursor
1504 * zc_nvlist_dst_size size of buffer for property nvlist
1505 *
1506 * outputs:
1507 * zc_name name of next filesystem
1508 * zc_cookie zap cursor
1330 * zc_objset_stats stats
1331 * zc_nvlist_dst property nvlist
1332 * zc_nvlist_dst_size size of property nvlist
1333 */
1334static int
1335zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
1336{
1337 objset_t *os;

--- 7 unchanged lines hidden (view full) ---

1345 return (error);
1346 }
1347
1348 p = strrchr(zc->zc_name, '/');
1349 if (p == NULL || p[1] != '\0')
1350 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
1351 p = zc->zc_name + strlen(zc->zc_name);
1352
1509 * zc_objset_stats stats
1510 * zc_nvlist_dst property nvlist
1511 * zc_nvlist_dst_size size of property nvlist
1512 */
1513static int
1514zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
1515{
1516 objset_t *os;

--- 7 unchanged lines hidden (view full) ---

1524 return (error);
1525 }
1526
1527 p = strrchr(zc->zc_name, '/');
1528 if (p == NULL || p[1] != '\0')
1529 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
1530 p = zc->zc_name + strlen(zc->zc_name);
1531
1532 /*
1533 * Pre-fetch the datasets. dmu_objset_prefetch() always returns 0
1534 * but is not declared void because its called by dmu_objset_find().
1535 */
1353 if (zc->zc_cookie == 0) {
1354 uint64_t cookie = 0;
1355 int len = sizeof (zc->zc_name) - (p - zc->zc_name);
1356
1357 while (dmu_dir_list_next(os, len, p, NULL, &cookie) == 0)
1536 if (zc->zc_cookie == 0) {
1537 uint64_t cookie = 0;
1538 int len = sizeof (zc->zc_name) - (p - zc->zc_name);
1539
1540 while (dmu_dir_list_next(os, len, p, NULL, &cookie) == 0)
1358 dmu_objset_prefetch(p, NULL);
1541 (void) dmu_objset_prefetch(p, NULL);
1359 }
1360
1361 do {
1362 error = dmu_dir_list_next(os,
1363 sizeof (zc->zc_name) - (p - zc->zc_name), p,
1364 NULL, &zc->zc_cookie);
1365 if (error == ENOENT)
1366 error = ESRCH;
1542 }
1543
1544 do {
1545 error = dmu_dir_list_next(os,
1546 sizeof (zc->zc_name) - (p - zc->zc_name), p,
1547 NULL, &zc->zc_cookie);
1548 if (error == ENOENT)
1549 error = ESRCH;
1367 } while (error == 0 && !INGLOBALZONE(curthread) &&
1368 !zone_dataset_visible(zc->zc_name, NULL));
1550 } while (error == 0 && dataset_name_hidden(zc->zc_name));
1369 dmu_objset_close(os);
1370
1551 dmu_objset_close(os);
1552
1371 /*
1372 * If it's a hidden dataset (ie. with a '$' in its name), don't
1373 * try to get stats for it. Userland will skip over it.
1374 */
1375 if (error == 0 && strchr(zc->zc_name, '$') == NULL)
1553 if (error == 0)
1376 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
1377
1378 return (error);
1379}
1380
1381/*
1382 * inputs:
1383 * zc_name name of filesystem

--- 7 unchanged lines hidden (view full) ---

1391 * zc_nvlist_dst_size size of property nvlist
1392 */
1393static int
1394zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
1395{
1396 objset_t *os;
1397 int error;
1398
1554 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
1555
1556 return (error);
1557}
1558
1559/*
1560 * inputs:
1561 * zc_name name of filesystem

--- 7 unchanged lines hidden (view full) ---

1569 * zc_nvlist_dst_size size of property nvlist
1570 */
1571static int
1572zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
1573{
1574 objset_t *os;
1575 int error;
1576
1399 if (zc->zc_cookie == 0)
1400 dmu_objset_find(zc->zc_name, dmu_objset_prefetch,
1401 NULL, DS_FIND_SNAPSHOTS);
1402 error = dmu_objset_open(zc->zc_name,
1403 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os);
1404 if (error)
1405 return (error == ENOENT ? ESRCH : error);
1406
1577 error = dmu_objset_open(zc->zc_name,
1578 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os);
1579 if (error)
1580 return (error == ENOENT ? ESRCH : error);
1581
1582 if (zc->zc_cookie == 0) {
1583 (void) dmu_objset_find(zc->zc_name, dmu_objset_prefetch,
1584 NULL, DS_FIND_SNAPSHOTS);
1585 }
1407 /*
1408 * A dataset name of maximum length cannot have any snapshots,
1409 * so exit immediately.
1410 */
1411 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
1412 dmu_objset_close(os);
1413 return (ESRCH);
1414 }

--- 12 unchanged lines hidden (view full) ---

1427 *strchr(zc->zc_name, '@') = '\0';
1428 return (error);
1429}
1430
1431int
1432zfs_set_prop_nvlist(const char *name, nvlist_t *nvl)
1433{
1434 nvpair_t *elem;
1586 /*
1587 * A dataset name of maximum length cannot have any snapshots,
1588 * so exit immediately.
1589 */
1590 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
1591 dmu_objset_close(os);
1592 return (ESRCH);
1593 }

--- 12 unchanged lines hidden (view full) ---

1606 *strchr(zc->zc_name, '@') = '\0';
1607 return (error);
1608}
1609
1610int
1611zfs_set_prop_nvlist(const char *name, nvlist_t *nvl)
1612{
1613 nvpair_t *elem;
1435 int error;
1614 int error = 0;
1436 uint64_t intval;
1437 char *strval;
1615 uint64_t intval;
1616 char *strval;
1617 nvlist_t *genericnvl;
1618 boolean_t issnap = (strchr(name, '@') != NULL);
1438
1439 /*
1440 * First validate permission to set all of the properties
1441 */
1619
1620 /*
1621 * First validate permission to set all of the properties
1622 */
1623 VERIFY(nvlist_alloc(&genericnvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1442 elem = NULL;
1443 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1444 const char *propname = nvpair_name(elem);
1445 zfs_prop_t prop = zfs_name_to_prop(propname);
1446
1447 if (prop == ZPROP_INVAL) {
1448 /*
1449 * If this is a user-defined property, it must be a
1450 * string, and there is no further validation to do.
1451 */
1624 elem = NULL;
1625 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1626 const char *propname = nvpair_name(elem);
1627 zfs_prop_t prop = zfs_name_to_prop(propname);
1628
1629 if (prop == ZPROP_INVAL) {
1630 /*
1631 * If this is a user-defined property, it must be a
1632 * string, and there is no further validation to do.
1633 */
1452 if (!zfs_prop_user(propname) ||
1453 nvpair_type(elem) != DATA_TYPE_STRING)
1454 return (EINVAL);
1634 if (zfs_prop_user(propname) &&
1635 nvpair_type(elem) == DATA_TYPE_STRING) {
1636 if (error = zfs_secpolicy_write_perms(name,
1637 ZFS_DELEG_PERM_USERPROP, CRED()))
1638 return (error);
1639 continue;
1640 }
1455
1641
1456 if (error = zfs_secpolicy_write_perms(name,
1457 ZFS_DELEG_PERM_USERPROP, CRED()))
1458 return (error);
1459 continue;
1642 if (!issnap && zfs_prop_userquota(propname) &&
1643 nvpair_type(elem) == DATA_TYPE_UINT64_ARRAY) {
1644 const char *perm;
1645 const char *up = zfs_userquota_prop_prefixes
1646 [ZFS_PROP_USERQUOTA];
1647 if (strncmp(propname, up, strlen(up)) == 0)
1648 perm = ZFS_DELEG_PERM_USERQUOTA;
1649 else
1650 perm = ZFS_DELEG_PERM_GROUPQUOTA;
1651 if (error = zfs_secpolicy_write_perms(name,
1652 perm, CRED()))
1653 return (error);
1654 continue;
1655 }
1656
1657 return (EINVAL);
1460 }
1461
1658 }
1659
1660 if (issnap)
1661 return (EINVAL);
1662
1462 if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0)
1463 return (error);
1464
1465 /*
1466 * Check that this value is valid for this pool version
1467 */
1468 switch (prop) {
1469 case ZFS_PROP_COMPRESSION:

--- 19 unchanged lines hidden (view full) ---

1489 */
1490 if (zfs_is_bootfs(name) &&
1491 !BOOTFS_COMPRESS_VALID(intval))
1492 return (ERANGE);
1493 }
1494 break;
1495
1496 case ZFS_PROP_COPIES:
1663 if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0)
1664 return (error);
1665
1666 /*
1667 * Check that this value is valid for this pool version
1668 */
1669 switch (prop) {
1670 case ZFS_PROP_COMPRESSION:

--- 19 unchanged lines hidden (view full) ---

1690 */
1691 if (zfs_is_bootfs(name) &&
1692 !BOOTFS_COMPRESS_VALID(intval))
1693 return (ERANGE);
1694 }
1695 break;
1696
1697 case ZFS_PROP_COPIES:
1497 if (zfs_earlier_version(name,
1498 SPA_VERSION_DITTO_BLOCKS))
1698 if (zfs_earlier_version(name, SPA_VERSION_DITTO_BLOCKS))
1499 return (ENOTSUP);
1500 break;
1501
1502 case ZFS_PROP_SHARESMB:
1503 if (zpl_earlier_version(name, ZPL_VERSION_FUID))
1504 return (ENOTSUP);
1505 break;
1506

--- 8 unchanged lines hidden (view full) ---

1515 }
1516
1517 elem = NULL;
1518 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1519 const char *propname = nvpair_name(elem);
1520 zfs_prop_t prop = zfs_name_to_prop(propname);
1521
1522 if (prop == ZPROP_INVAL) {
1699 return (ENOTSUP);
1700 break;
1701
1702 case ZFS_PROP_SHARESMB:
1703 if (zpl_earlier_version(name, ZPL_VERSION_FUID))
1704 return (ENOTSUP);
1705 break;
1706

--- 8 unchanged lines hidden (view full) ---

1715 }
1716
1717 elem = NULL;
1718 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1719 const char *propname = nvpair_name(elem);
1720 zfs_prop_t prop = zfs_name_to_prop(propname);
1721
1722 if (prop == ZPROP_INVAL) {
1523 VERIFY(nvpair_value_string(elem, &strval) == 0);
1524 error = dsl_prop_set(name, propname, 1,
1525 strlen(strval) + 1, strval);
1526 if (error == 0)
1527 continue;
1528 else
1529 return (error);
1723 if (zfs_prop_userquota(propname)) {
1724 uint64_t *valary;
1725 unsigned int vallen;
1726 const char *domain;
1727 zfs_userquota_prop_t type;
1728 uint64_t rid;
1729 uint64_t quota;
1730 zfsvfs_t *zfsvfs;
1731
1732 VERIFY(nvpair_value_uint64_array(elem,
1733 &valary, &vallen) == 0);
1734 VERIFY(vallen == 3);
1735 type = valary[0];
1736 rid = valary[1];
1737 quota = valary[2];
1738 domain = propname +
1739 strlen(zfs_userquota_prop_prefixes[type]);
1740
1741 error = zfsvfs_hold(name, B_FALSE, FTAG,
1742 &zfsvfs);
1743 if (error == 0) {
1744 error = zfs_set_userquota(zfsvfs,
1745 type, domain, rid, quota);
1746 zfsvfs_rele(zfsvfs, FTAG);
1747 }
1748 if (error == 0)
1749 continue;
1750 else
1751 goto out;
1752 } else if (zfs_prop_user(propname)) {
1753 VERIFY(nvpair_value_string(elem, &strval) == 0);
1754 error = dsl_prop_set(name, propname, 1,
1755 strlen(strval) + 1, strval);
1756 if (error == 0)
1757 continue;
1758 else
1759 goto out;
1760 }
1530 }
1531
1532 switch (prop) {
1533 case ZFS_PROP_QUOTA:
1534 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1535 (error = dsl_dir_set_quota(name, intval)) != 0)
1761 }
1762
1763 switch (prop) {
1764 case ZFS_PROP_QUOTA:
1765 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1766 (error = dsl_dir_set_quota(name, intval)) != 0)
1536 return (error);
1767 goto out;
1537 break;
1538
1539 case ZFS_PROP_REFQUOTA:
1540 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1541 (error = dsl_dataset_set_quota(name, intval)) != 0)
1768 break;
1769
1770 case ZFS_PROP_REFQUOTA:
1771 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1772 (error = dsl_dataset_set_quota(name, intval)) != 0)
1542 return (error);
1773 goto out;
1543 break;
1544
1545 case ZFS_PROP_RESERVATION:
1546 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1547 (error = dsl_dir_set_reservation(name,
1548 intval)) != 0)
1774 break;
1775
1776 case ZFS_PROP_RESERVATION:
1777 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1778 (error = dsl_dir_set_reservation(name,
1779 intval)) != 0)
1549 return (error);
1780 goto out;
1550 break;
1551
1552 case ZFS_PROP_REFRESERVATION:
1553 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1554 (error = dsl_dataset_set_reservation(name,
1555 intval)) != 0)
1781 break;
1782
1783 case ZFS_PROP_REFRESERVATION:
1784 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1785 (error = dsl_dataset_set_reservation(name,
1786 intval)) != 0)
1556 return (error);
1787 goto out;
1557 break;
1558
1559 case ZFS_PROP_VOLSIZE:
1560 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1561 (error = zvol_set_volsize(name,
1562 ddi_driver_major(zfs_dip), intval)) != 0)
1788 break;
1789
1790 case ZFS_PROP_VOLSIZE:
1791 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1792 (error = zvol_set_volsize(name,
1793 ddi_driver_major(zfs_dip), intval)) != 0)
1563 return (error);
1794 goto out;
1564 break;
1565
1566 case ZFS_PROP_VOLBLOCKSIZE:
1567 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1568 (error = zvol_set_volblocksize(name, intval)) != 0)
1795 break;
1796
1797 case ZFS_PROP_VOLBLOCKSIZE:
1798 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1799 (error = zvol_set_volblocksize(name, intval)) != 0)
1569 return (error);
1800 goto out;
1570 break;
1571
1572 case ZFS_PROP_VERSION:
1801 break;
1802
1803 case ZFS_PROP_VERSION:
1573 if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
1574 (error = zfs_set_version(name, intval)) != 0)
1575 return (error);
1804 {
1805 zfsvfs_t *zfsvfs;
1806
1807 if ((error = nvpair_value_uint64(elem, &intval)) != 0)
1808 goto out;
1809 if ((error = zfsvfs_hold(name, B_FALSE, FTAG,
1810 &zfsvfs)) != 0)
1811 goto out;
1812 error = zfs_set_version(zfsvfs, intval);
1813 zfsvfs_rele(zfsvfs, FTAG);
1814
1815 if (error == 0 && intval >= ZPL_VERSION_USERSPACE) {
1816 zfs_cmd_t zc = { 0 };
1817 (void) strcpy(zc.zc_name, name);
1818 (void) zfs_ioc_userspace_upgrade(&zc);
1819 }
1820 if (error)
1821 goto out;
1576 break;
1822 break;
1823 }
1577
1578 default:
1579 if (nvpair_type(elem) == DATA_TYPE_STRING) {
1580 if (zfs_prop_get_type(prop) !=
1824
1825 default:
1826 if (nvpair_type(elem) == DATA_TYPE_STRING) {
1827 if (zfs_prop_get_type(prop) !=
1581 PROP_TYPE_STRING)
1582 return (EINVAL);
1583 VERIFY(nvpair_value_string(elem, &strval) == 0);
1584 if ((error = dsl_prop_set(name,
1585 nvpair_name(elem), 1, strlen(strval) + 1,
1586 strval)) != 0)
1587 return (error);
1828 PROP_TYPE_STRING) {
1829 error = EINVAL;
1830 goto out;
1831 }
1588 } else if (nvpair_type(elem) == DATA_TYPE_UINT64) {
1589 const char *unused;
1590
1591 VERIFY(nvpair_value_uint64(elem, &intval) == 0);
1592
1593 switch (zfs_prop_get_type(prop)) {
1594 case PROP_TYPE_NUMBER:
1595 break;
1596 case PROP_TYPE_STRING:
1832 } else if (nvpair_type(elem) == DATA_TYPE_UINT64) {
1833 const char *unused;
1834
1835 VERIFY(nvpair_value_uint64(elem, &intval) == 0);
1836
1837 switch (zfs_prop_get_type(prop)) {
1838 case PROP_TYPE_NUMBER:
1839 break;
1840 case PROP_TYPE_STRING:
1597 return (EINVAL);
1841 error = EINVAL;
1842 goto out;
1598 case PROP_TYPE_INDEX:
1599 if (zfs_prop_index_to_string(prop,
1843 case PROP_TYPE_INDEX:
1844 if (zfs_prop_index_to_string(prop,
1600 intval, &unused) != 0)
1601 return (EINVAL);
1845 intval, &unused) != 0) {
1846 error = EINVAL;
1847 goto out;
1848 }
1602 break;
1603 default:
1604 cmn_err(CE_PANIC,
1605 "unknown property type");
1606 break;
1607 }
1849 break;
1850 default:
1851 cmn_err(CE_PANIC,
1852 "unknown property type");
1853 break;
1854 }
1608
1609 if ((error = dsl_prop_set(name, propname,
1610 8, 1, &intval)) != 0)
1611 return (error);
1612 } else {
1855 } else {
1613 return (EINVAL);
1856 error = EINVAL;
1857 goto out;
1614 }
1858 }
1615 break;
1859 if ((error = nvlist_add_nvpair(genericnvl, elem)) != 0)
1860 goto out;
1616 }
1617 }
1618
1861 }
1862 }
1863
1864 if (nvlist_next_nvpair(genericnvl, NULL) != NULL) {
1865 error = dsl_props_set(name, genericnvl);
1866 }
1867out:
1868 nvlist_free(genericnvl);
1869 return (error);
1870}
1871
1872/*
1873 * Check that all the properties are valid user properties.
1874 */
1875static int
1876zfs_check_userprops(char *fsname, nvlist_t *nvl)
1877{
1878 nvpair_t *elem = NULL;
1879 int error = 0;
1880
1881 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1882 const char *propname = nvpair_name(elem);
1883 char *valstr;
1884
1885 if (!zfs_prop_user(propname) ||
1886 nvpair_type(elem) != DATA_TYPE_STRING)
1887 return (EINVAL);
1888
1889 if (error = zfs_secpolicy_write_perms(fsname,
1890 ZFS_DELEG_PERM_USERPROP, CRED()))
1891 return (error);
1892
1893 if (strlen(propname) >= ZAP_MAXNAMELEN)
1894 return (ENAMETOOLONG);
1895
1896 VERIFY(nvpair_value_string(elem, &valstr) == 0);
1897 if (strlen(valstr) >= ZAP_MAXVALUELEN)
1898 return (E2BIG);
1899 }
1619 return (0);
1620}
1621
1622/*
1623 * inputs:
1624 * zc_name name of filesystem
1900 return (0);
1901}
1902
1903/*
1904 * inputs:
1905 * zc_name name of filesystem
1625 * zc_value name of property to inherit
1906 * zc_value name of property to set
1626 * zc_nvlist_src{_size} nvlist of properties to apply
1627 * zc_cookie clear existing local props?
1628 *
1629 * outputs: none
1630 */
1631static int
1632zfs_ioc_set_prop(zfs_cmd_t *zc)
1633{

--- 40 unchanged lines hidden (view full) ---

1674}
1675
1676static int
1677zfs_ioc_pool_set_props(zfs_cmd_t *zc)
1678{
1679 nvlist_t *props;
1680 spa_t *spa;
1681 int error;
1907 * zc_nvlist_src{_size} nvlist of properties to apply
1908 * zc_cookie clear existing local props?
1909 *
1910 * outputs: none
1911 */
1912static int
1913zfs_ioc_set_prop(zfs_cmd_t *zc)
1914{

--- 40 unchanged lines hidden (view full) ---

1955}
1956
1957static int
1958zfs_ioc_pool_set_props(zfs_cmd_t *zc)
1959{
1960 nvlist_t *props;
1961 spa_t *spa;
1962 int error;
1963 nvpair_t *elem;
1682
1683 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1684 &props)))
1685 return (error);
1686
1964
1965 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1966 &props)))
1967 return (error);
1968
1969 /*
1970 * If the only property is the configfile, then just do a spa_lookup()
1971 * to handle the faulted case.
1972 */
1973 elem = nvlist_next_nvpair(props, NULL);
1974 if (elem != NULL && strcmp(nvpair_name(elem),
1975 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
1976 nvlist_next_nvpair(props, elem) == NULL) {
1977 mutex_enter(&spa_namespace_lock);
1978 if ((spa = spa_lookup(zc->zc_name)) != NULL) {
1979 spa_configfile_set(spa, props, B_FALSE);
1980 spa_config_sync(spa, B_FALSE, B_TRUE);
1981 }
1982 mutex_exit(&spa_namespace_lock);
1983 if (spa != NULL)
1984 return (0);
1985 }
1986
1687 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
1688 nvlist_free(props);
1689 return (error);
1690 }
1691
1692 error = spa_prop_set(spa, props);
1693
1694 nvlist_free(props);

--- 4 unchanged lines hidden (view full) ---

1699
1700static int
1701zfs_ioc_pool_get_props(zfs_cmd_t *zc)
1702{
1703 spa_t *spa;
1704 int error;
1705 nvlist_t *nvp = NULL;
1706
1987 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
1988 nvlist_free(props);
1989 return (error);
1990 }
1991
1992 error = spa_prop_set(spa, props);
1993
1994 nvlist_free(props);

--- 4 unchanged lines hidden (view full) ---

1999
2000static int
2001zfs_ioc_pool_get_props(zfs_cmd_t *zc)
2002{
2003 spa_t *spa;
2004 int error;
2005 nvlist_t *nvp = NULL;
2006
1707 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1708 return (error);
2007 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
2008 /*
2009 * If the pool is faulted, there may be properties we can still
2010 * get (such as altroot and cachefile), so attempt to get them
2011 * anyway.
2012 */
2013 mutex_enter(&spa_namespace_lock);
2014 if ((spa = spa_lookup(zc->zc_name)) != NULL)
2015 error = spa_prop_get(spa, &nvp);
2016 mutex_exit(&spa_namespace_lock);
2017 } else {
2018 error = spa_prop_get(spa, &nvp);
2019 spa_close(spa, FTAG);
2020 }
1709
2021
1710 error = spa_prop_get(spa, &nvp);
1711
1712 if (error == 0 && zc->zc_nvlist_dst != 0)
1713 error = put_nvlist(zc, nvp);
1714 else
1715 error = EFAULT;
1716
2022 if (error == 0 && zc->zc_nvlist_dst != 0)
2023 error = put_nvlist(zc, nvp);
2024 else
2025 error = EFAULT;
2026
1717 spa_close(spa, FTAG);
1718
1719 if (nvp)
1720 nvlist_free(nvp);
2027 nvlist_free(nvp);
1721 return (error);
1722}
1723
1724static int
1725zfs_ioc_iscsi_perm_check(zfs_cmd_t *zc)
1726{
2028 return (error);
2029}
2030
2031static int
2032zfs_ioc_iscsi_perm_check(zfs_cmd_t *zc)
2033{
1727#ifdef TODO
2034#ifdef sun
1728 nvlist_t *nvp;
1729 int error;
1730 uint32_t uid;
1731 uint32_t gid;
1732 uint32_t *groups;
1733 uint_t group_cnt;
1734 cred_t *usercred;
1735

--- 26 unchanged lines hidden (view full) ---

1762 crfree(usercred);
1763 return (EPERM);
1764 }
1765 nvlist_free(nvp);
1766 error = dsl_deleg_access(zc->zc_name,
1767 zfs_prop_to_name(ZFS_PROP_SHAREISCSI), usercred);
1768 crfree(usercred);
1769 return (error);
2035 nvlist_t *nvp;
2036 int error;
2037 uint32_t uid;
2038 uint32_t gid;
2039 uint32_t *groups;
2040 uint_t group_cnt;
2041 cred_t *usercred;
2042

--- 26 unchanged lines hidden (view full) ---

2069 crfree(usercred);
2070 return (EPERM);
2071 }
2072 nvlist_free(nvp);
2073 error = dsl_deleg_access(zc->zc_name,
2074 zfs_prop_to_name(ZFS_PROP_SHAREISCSI), usercred);
2075 crfree(usercred);
2076 return (error);
1770#else
2077#else /* sun */
1771 return (EPERM);
2078 return (EPERM);
1772#endif
2079#endif /* sun */
1773}
1774
1775/*
1776 * inputs:
1777 * zc_name name of filesystem
1778 * zc_nvlist_src{_size} nvlist of delegated permissions
1779 * zc_perm_action allow/unallow flag
1780 *

--- 134 unchanged lines hidden (view full) ---

1915 * creator and/or we can inherit values from the parent dataset. If
1916 * the file system is of too early a vintage, a creator can not
1917 * request settings for these properties, even if the requested
1918 * setting is the default value. We don't actually want to create dsl
1919 * properties for these, so remove them from the source nvlist after
1920 * processing.
1921 */
1922static int
2080}
2081
2082/*
2083 * inputs:
2084 * zc_name name of filesystem
2085 * zc_nvlist_src{_size} nvlist of delegated permissions
2086 * zc_perm_action allow/unallow flag
2087 *

--- 134 unchanged lines hidden (view full) ---

2222 * creator and/or we can inherit values from the parent dataset. If
2223 * the file system is of too early a vintage, a creator can not
2224 * request settings for these properties, even if the requested
2225 * setting is the default value. We don't actually want to create dsl
2226 * properties for these, so remove them from the source nvlist after
2227 * processing.
2228 */
2229static int
1923zfs_fill_zplprops_impl(objset_t *os, uint64_t default_zplver,
2230zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
1924 boolean_t fuids_ok, nvlist_t *createprops, nvlist_t *zplprops,
1925 boolean_t *is_ci)
1926{
2231 boolean_t fuids_ok, nvlist_t *createprops, nvlist_t *zplprops,
2232 boolean_t *is_ci)
2233{
1927 uint64_t zplver = default_zplver;
1928 uint64_t sense = ZFS_PROP_UNDEFINED;
1929 uint64_t norm = ZFS_PROP_UNDEFINED;
1930 uint64_t u8 = ZFS_PROP_UNDEFINED;
1931
1932 ASSERT(zplprops != NULL);
1933
1934 /*
1935 * Pull out creator prop choices, if any.

--- 71 unchanged lines hidden (view full) ---

2007 char *cp;
2008 int error;
2009
2010 (void) strlcpy(parentname, dataset, sizeof (parentname));
2011 cp = strrchr(parentname, '/');
2012 ASSERT(cp != NULL);
2013 cp[0] = '\0';
2014
2234 uint64_t sense = ZFS_PROP_UNDEFINED;
2235 uint64_t norm = ZFS_PROP_UNDEFINED;
2236 uint64_t u8 = ZFS_PROP_UNDEFINED;
2237
2238 ASSERT(zplprops != NULL);
2239
2240 /*
2241 * Pull out creator prop choices, if any.

--- 71 unchanged lines hidden (view full) ---

2313 char *cp;
2314 int error;
2315
2316 (void) strlcpy(parentname, dataset, sizeof (parentname));
2317 cp = strrchr(parentname, '/');
2318 ASSERT(cp != NULL);
2319 cp[0] = '\0';
2320
2321 if (zfs_earlier_version(dataset, SPA_VERSION_USERSPACE))
2322 zplver = ZPL_VERSION_USERSPACE - 1;
2015 if (zfs_earlier_version(dataset, SPA_VERSION_FUID)) {
2016 zplver = ZPL_VERSION_FUID - 1;
2017 fuids_ok = B_FALSE;
2018 }
2019
2020 /*
2021 * Open parent object set so we can inherit zplprop values.
2022 */

--- 162 unchanged lines hidden (view full) ---

2185 if (error == 0) {
2186 if ((error = zfs_set_prop_nvlist(zc->zc_name, nvprops)) != 0)
2187 (void) dmu_objset_destroy(zc->zc_name);
2188 }
2189 nvlist_free(nvprops);
2190 return (error);
2191}
2192
2323 if (zfs_earlier_version(dataset, SPA_VERSION_FUID)) {
2324 zplver = ZPL_VERSION_FUID - 1;
2325 fuids_ok = B_FALSE;
2326 }
2327
2328 /*
2329 * Open parent object set so we can inherit zplprop values.
2330 */

--- 162 unchanged lines hidden (view full) ---

2493 if (error == 0) {
2494 if ((error = zfs_set_prop_nvlist(zc->zc_name, nvprops)) != 0)
2495 (void) dmu_objset_destroy(zc->zc_name);
2496 }
2497 nvlist_free(nvprops);
2498 return (error);
2499}
2500
2193struct snap_prop_arg {
2194 nvlist_t *nvprops;
2195 const char *snapname;
2196};
2197
2198static int
2199set_snap_props(char *name, void *arg)
2200{
2201 struct snap_prop_arg *snpa = arg;
2202 int len = strlen(name) + strlen(snpa->snapname) + 2;
2203 char *buf = kmem_alloc(len, KM_SLEEP);
2204 int err;
2205
2206 (void) snprintf(buf, len, "%s@%s", name, snpa->snapname);
2207 err = zfs_set_prop_nvlist(buf, snpa->nvprops);
2208 if (err)
2209 (void) dmu_objset_destroy(buf);
2210 kmem_free(buf, len);
2211 return (err);
2212}
2213
2214/*
2215 * inputs:
2216 * zc_name name of filesystem
2217 * zc_value short name of snapshot
2218 * zc_cookie recursive flag
2501/*
2502 * inputs:
2503 * zc_name name of filesystem
2504 * zc_value short name of snapshot
2505 * zc_cookie recursive flag
2506 * zc_nvlist_src[_size] property list
2219 *
2220 * outputs: none
2221 */
2222static int
2223zfs_ioc_snapshot(zfs_cmd_t *zc)
2224{
2225 nvlist_t *nvprops = NULL;
2226 int error;
2227 boolean_t recursive = zc->zc_cookie;
2228
2229 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
2230 return (EINVAL);
2231
2232 if (zc->zc_nvlist_src != 0 &&
2233 (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2234 &nvprops)) != 0)
2235 return (error);
2236
2507 *
2508 * outputs: none
2509 */
2510static int
2511zfs_ioc_snapshot(zfs_cmd_t *zc)
2512{
2513 nvlist_t *nvprops = NULL;
2514 int error;
2515 boolean_t recursive = zc->zc_cookie;
2516
2517 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
2518 return (EINVAL);
2519
2520 if (zc->zc_nvlist_src != 0 &&
2521 (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2522 &nvprops)) != 0)
2523 return (error);
2524
2237 error = dmu_objset_snapshot(zc->zc_name, zc->zc_value, recursive);
2525 error = zfs_check_userprops(zc->zc_name, nvprops);
2526 if (error)
2527 goto out;
2238
2528
2239 /*
2240 * It would be nice to do this atomically.
2241 */
2242 if (error == 0) {
2243 struct snap_prop_arg snpa;
2244 snpa.nvprops = nvprops;
2245 snpa.snapname = zc->zc_value;
2246 if (recursive) {
2247 error = dmu_objset_find(zc->zc_name,
2248 set_snap_props, &snpa, DS_FIND_CHILDREN);
2249 if (error) {
2250 (void) dmu_snapshots_destroy(zc->zc_name,
2251 zc->zc_value);
2252 }
2253 } else {
2254 error = set_snap_props(zc->zc_name, &snpa);
2255 }
2529 if (nvprops != NULL && nvlist_next_nvpair(nvprops, NULL) != NULL &&
2530 zfs_earlier_version(zc->zc_name, SPA_VERSION_SNAP_PROPS)) {
2531 error = ENOTSUP;
2532 goto out;
2256 }
2533 }
2534
2535 error = dmu_objset_snapshot(zc->zc_name, zc->zc_value,
2536 nvprops, recursive);
2537
2538out:
2257 nvlist_free(nvprops);
2258 return (error);
2259}
2260
2261int
2262zfs_unmount_snap(char *name, void *arg)
2263{
2264 vfs_t *vfsp = NULL;

--- 88 unchanged lines hidden (view full) ---

2353 * Get the zfsvfs for the receiving objset. There
2354 * won't be one if we're operating on a zvol, if the
2355 * objset doesn't exist yet, or is not mounted.
2356 */
2357 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, DS_MODE_USER, &os);
2358 if (error)
2359 return (error);
2360
2539 nvlist_free(nvprops);
2540 return (error);
2541}
2542
2543int
2544zfs_unmount_snap(char *name, void *arg)
2545{
2546 vfs_t *vfsp = NULL;

--- 88 unchanged lines hidden (view full) ---

2635 * Get the zfsvfs for the receiving objset. There
2636 * won't be one if we're operating on a zvol, if the
2637 * objset doesn't exist yet, or is not mounted.
2638 */
2639 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, DS_MODE_USER, &os);
2640 if (error)
2641 return (error);
2642
2361 if (dmu_objset_type(os) == DMU_OST_ZFS) {
2362 mutex_enter(&os->os->os_user_ptr_lock);
2363 zfsvfs = dmu_objset_get_user(os);
2364 if (zfsvfs != NULL)
2365 VFS_HOLD(zfsvfs->z_vfs);
2366 mutex_exit(&os->os->os_user_ptr_lock);
2367 }
2368
2369 if (zfsvfs != NULL) {
2370 char *osname;
2643 if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
2371 int mode;
2372
2644 int mode;
2645
2373 osname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
2374 error = zfs_suspend_fs(zfsvfs, osname, &mode);
2646 error = zfs_suspend_fs(zfsvfs, NULL, &mode);
2375 if (error == 0) {
2376 int resume_err;
2377
2647 if (error == 0) {
2648 int resume_err;
2649
2378 ASSERT(strcmp(osname, zc->zc_name) == 0);
2379 error = dmu_objset_rollback(os);
2650 error = dmu_objset_rollback(os);
2380 resume_err = zfs_resume_fs(zfsvfs, osname, mode);
2651 resume_err = zfs_resume_fs(zfsvfs, zc->zc_name, mode);
2381 error = error ? error : resume_err;
2382 } else {
2383 dmu_objset_close(os);
2384 }
2652 error = error ? error : resume_err;
2653 } else {
2654 dmu_objset_close(os);
2655 }
2385 kmem_free(osname, MAXNAMELEN);
2386 VFS_RELE(zfsvfs->z_vfs);
2387 } else {
2388 error = dmu_objset_rollback(os);
2389 }
2390 /* Note, the dmu_objset_rollback() releases the objset for us. */
2391
2392 return (error);
2393}

--- 98 unchanged lines hidden (view full) ---

2492
2493 fd = zc->zc_cookie;
2494 fp = getf(fd, 0);
2495 if (fp == NULL) {
2496 nvlist_free(props);
2497 return (EBADF);
2498 }
2499
2656 VFS_RELE(zfsvfs->z_vfs);
2657 } else {
2658 error = dmu_objset_rollback(os);
2659 }
2660 /* Note, the dmu_objset_rollback() releases the objset for us. */
2661
2662 return (error);
2663}

--- 98 unchanged lines hidden (view full) ---

2762
2763 fd = zc->zc_cookie;
2764 fp = getf(fd, 0);
2765 if (fp == NULL) {
2766 nvlist_free(props);
2767 return (EBADF);
2768 }
2769
2500 if (dmu_objset_open(tofs, DMU_OST_ANY,
2501 DS_MODE_USER | DS_MODE_READONLY, &os) == 0) {
2502 /*
2503 * Try to get the zfsvfs for the receiving objset.
2504 * There won't be one if we're operating on a zvol,
2505 * if the objset doesn't exist yet, or is not mounted.
2506 */
2507 mutex_enter(&os->os->os_user_ptr_lock);
2508 if (zfsvfs = dmu_objset_get_user(os)) {
2509 if (!mutex_tryenter(&zfsvfs->z_online_recv_lock)) {
2510 mutex_exit(&os->os->os_user_ptr_lock);
2511 dmu_objset_close(os);
2512 zfsvfs = NULL;
2513 error = EBUSY;
2514 goto out;
2515 }
2516 VFS_HOLD(zfsvfs->z_vfs);
2770 if (getzfsvfs(tofs, &zfsvfs) == 0) {
2771 if (!mutex_tryenter(&zfsvfs->z_online_recv_lock)) {
2772 VFS_RELE(zfsvfs->z_vfs);
2773 zfsvfs = NULL;
2774 error = EBUSY;
2775 goto out;
2517 }
2776 }
2518 mutex_exit(&os->os->os_user_ptr_lock);
2519
2520 /*
2521 * If new properties are supplied, they are to completely
2522 * replace the existing ones, so stash away the existing ones.
2523 */
2524 if (props)
2777 /*
2778 * If new properties are supplied, they are to completely
2779 * replace the existing ones, so stash away the existing ones.
2780 */
2781 if (props)
2525 (void) dsl_prop_get_all(os, &origprops, TRUE);
2782 (void) dsl_prop_get_all(zfsvfs->z_os, &origprops, TRUE);
2783 } else if (props && dmu_objset_open(tofs, DMU_OST_ANY,
2784 DS_MODE_USER | DS_MODE_READONLY, &os) == 0) {
2785 /*
2786 * Get the props even if there was no zfsvfs (zvol or
2787 * unmounted zpl).
2788 */
2789 (void) dsl_prop_get_all(os, &origprops, TRUE);
2526
2527 dmu_objset_close(os);
2528 }
2529
2530 if (zc->zc_string[0]) {
2531 error = dmu_objset_open(zc->zc_string, DMU_OST_ANY,
2532 DS_MODE_USER | DS_MODE_READONLY, &origin);
2533 if (error)

--- 223 unchanged lines hidden (view full) ---

2757
2758 vdev_clear(spa, vd);
2759
2760 (void) spa_vdev_state_exit(spa, NULL, 0);
2761
2762 /*
2763 * Resume any suspended I/Os.
2764 */
2790
2791 dmu_objset_close(os);
2792 }
2793
2794 if (zc->zc_string[0]) {
2795 error = dmu_objset_open(zc->zc_string, DMU_OST_ANY,
2796 DS_MODE_USER | DS_MODE_READONLY, &origin);
2797 if (error)

--- 223 unchanged lines hidden (view full) ---

3021
3022 vdev_clear(spa, vd);
3023
3024 (void) spa_vdev_state_exit(spa, NULL, 0);
3025
3026 /*
3027 * Resume any suspended I/Os.
3028 */
2765 zio_resume(spa);
3029 if (zio_resume(spa) != 0)
3030 error = EIO;
2766
2767 spa_close(spa, FTAG);
2768
3031
3032 spa_close(spa, FTAG);
3033
2769 return (0);
3034 return (error);
2770}
2771
2772/*
2773 * inputs:
2774 * zc_name name of filesystem
2775 * zc_value name of origin snapshot
2776 *
2777 * outputs: none

--- 10 unchanged lines hidden (view full) ---

2788 cp = strchr(zc->zc_value, '@');
2789 if (cp)
2790 *cp = '\0';
2791 (void) dmu_objset_find(zc->zc_value,
2792 zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS);
2793 return (dsl_dataset_promote(zc->zc_name));
2794}
2795
3035}
3036
3037/*
3038 * inputs:
3039 * zc_name name of filesystem
3040 * zc_value name of origin snapshot
3041 *
3042 * outputs: none

--- 10 unchanged lines hidden (view full) ---

3053 cp = strchr(zc->zc_value, '@');
3054 if (cp)
3055 *cp = '\0';
3056 (void) dmu_objset_find(zc->zc_value,
3057 zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS);
3058 return (dsl_dataset_promote(zc->zc_name));
3059}
3060
2796#ifdef TODO
2797/*
3061/*
3062 * Retrieve a single {user|group}{used|quota}@... property.
3063 *
3064 * inputs:
3065 * zc_name name of filesystem
3066 * zc_objset_type zfs_userquota_prop_t
3067 * zc_value domain name (eg. "S-1-234-567-89")
3068 * zc_guid RID/UID/GID
3069 *
3070 * outputs:
3071 * zc_cookie property value
3072 */
3073static int
3074zfs_ioc_userspace_one(zfs_cmd_t *zc)
3075{
3076 zfsvfs_t *zfsvfs;
3077 int error;
3078
3079 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
3080 return (EINVAL);
3081
3082 error = zfsvfs_hold(zc->zc_name, B_TRUE, FTAG, &zfsvfs);
3083 if (error)
3084 return (error);
3085
3086 error = zfs_userspace_one(zfsvfs,
3087 zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
3088 zfsvfs_rele(zfsvfs, FTAG);
3089
3090 return (error);
3091}
3092
3093/*
3094 * inputs:
3095 * zc_name name of filesystem
3096 * zc_cookie zap cursor
3097 * zc_objset_type zfs_userquota_prop_t
3098 * zc_nvlist_dst[_size] buffer to fill (not really an nvlist)
3099 *
3100 * outputs:
3101 * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t)
3102 * zc_cookie zap cursor
3103 */
3104static int
3105zfs_ioc_userspace_many(zfs_cmd_t *zc)
3106{
3107 zfsvfs_t *zfsvfs;
3108 int error;
3109
3110 error = zfsvfs_hold(zc->zc_name, B_TRUE, FTAG, &zfsvfs);
3111 if (error)
3112 return (error);
3113
3114 int bufsize = zc->zc_nvlist_dst_size;
3115 void *buf = kmem_alloc(bufsize, KM_SLEEP);
3116
3117 error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie,
3118 buf, &zc->zc_nvlist_dst_size);
3119
3120 if (error == 0) {
3121 error = xcopyout(buf,
3122 (void *)(uintptr_t)zc->zc_nvlist_dst,
3123 zc->zc_nvlist_dst_size);
3124 }
3125 kmem_free(buf, bufsize);
3126 zfsvfs_rele(zfsvfs, FTAG);
3127
3128 return (error);
3129}
3130
3131/*
3132 * inputs:
3133 * zc_name name of filesystem
3134 *
3135 * outputs:
3136 * none
3137 */
3138static int
3139zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
3140{
3141 objset_t *os;
3142 int error;
3143 zfsvfs_t *zfsvfs;
3144
3145 if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
3146 if (!dmu_objset_userused_enabled(zfsvfs->z_os->os)) {
3147 /*
3148 * If userused is not enabled, it may be because the
3149 * objset needs to be closed & reopened (to grow the
3150 * objset_phys_t). Suspend/resume the fs will do that.
3151 */
3152 int mode;
3153 error = zfs_suspend_fs(zfsvfs, NULL, &mode);
3154 if (error == 0) {
3155 error = zfs_resume_fs(zfsvfs,
3156 zc->zc_name, mode);
3157 }
3158 }
3159 if (error == 0)
3160 error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
3161 VFS_RELE(zfsvfs->z_vfs);
3162 } else {
3163 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY,
3164 DS_MODE_USER, &os);
3165 if (error)
3166 return (error);
3167
3168 error = dmu_objset_userspace_upgrade(os);
3169 dmu_objset_close(os);
3170 }
3171
3172 return (error);
3173}
3174
3175#ifdef sun
3176/*
2798 * We don't want to have a hard dependency
2799 * against some special symbols in sharefs
2800 * nfs, and smbsrv. Determine them if needed when
2801 * the first file system is shared.
2802 * Neither sharefs, nfs or smbsrv are unloadable modules.
2803 */
2804int (*znfsexport_fs)(void *arg);
2805int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
2806int (*zsmbexport_fs)(void *arg, boolean_t add_share);
2807
2808int zfs_nfsshare_inited;
2809int zfs_smbshare_inited;
2810
2811ddi_modhandle_t nfs_mod;
2812ddi_modhandle_t sharefs_mod;
2813ddi_modhandle_t smbsrv_mod;
3177 * We don't want to have a hard dependency
3178 * against some special symbols in sharefs
3179 * nfs, and smbsrv. Determine them if needed when
3180 * the first file system is shared.
3181 * Neither sharefs, nfs or smbsrv are unloadable modules.
3182 */
3183int (*znfsexport_fs)(void *arg);
3184int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
3185int (*zsmbexport_fs)(void *arg, boolean_t add_share);
3186
3187int zfs_nfsshare_inited;
3188int zfs_smbshare_inited;
3189
3190ddi_modhandle_t nfs_mod;
3191ddi_modhandle_t sharefs_mod;
3192ddi_modhandle_t smbsrv_mod;
2814#endif
3193#endif /* sun */
2815kmutex_t zfs_share_lock;
2816
3194kmutex_t zfs_share_lock;
3195
2817#ifdef TODO
3196#ifdef sun
2818static int
2819zfs_init_sharefs()
2820{
2821 int error;
2822
2823 ASSERT(MUTEX_HELD(&zfs_share_lock));
2824 /* Both NFS and SMB shares also require sharetab support. */
2825 if (sharefs_mod == NULL && ((sharefs_mod =
2826 ddi_modopen("fs/sharefs",
2827 KRTLD_MODE_FIRST, &error)) == NULL)) {
2828 return (ENOSYS);
2829 }
2830 if (zshare_fs == NULL && ((zshare_fs =
2831 (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
2832 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
2833 return (ENOSYS);
2834 }
2835 return (0);
2836}
3197static int
3198zfs_init_sharefs()
3199{
3200 int error;
3201
3202 ASSERT(MUTEX_HELD(&zfs_share_lock));
3203 /* Both NFS and SMB shares also require sharetab support. */
3204 if (sharefs_mod == NULL && ((sharefs_mod =
3205 ddi_modopen("fs/sharefs",
3206 KRTLD_MODE_FIRST, &error)) == NULL)) {
3207 return (ENOSYS);
3208 }
3209 if (zshare_fs == NULL && ((zshare_fs =
3210 (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
3211 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
3212 return (ENOSYS);
3213 }
3214 return (0);
3215}
2837#endif
3216#endif /* sun */
2838
2839static int
2840zfs_ioc_share(zfs_cmd_t *zc)
2841{
3217
3218static int
3219zfs_ioc_share(zfs_cmd_t *zc)
3220{
2842#ifdef TODO
3221#ifdef sun
2843 int error;
2844 int opcode;
2845
2846 switch (zc->zc_share.z_sharetype) {
2847 case ZFS_SHARE_NFS:
2848 case ZFS_UNSHARE_NFS:
2849 if (zfs_nfsshare_inited == 0) {
2850 mutex_enter(&zfs_share_lock);

--- 55 unchanged lines hidden (view full) ---

2906 (uintptr_t)zc->zc_share.z_exportdata))
2907 return (error);
2908 break;
2909 case ZFS_SHARE_SMB:
2910 case ZFS_UNSHARE_SMB:
2911 if (error = zsmbexport_fs((void *)
2912 (uintptr_t)zc->zc_share.z_exportdata,
2913 zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
3222 int error;
3223 int opcode;
3224
3225 switch (zc->zc_share.z_sharetype) {
3226 case ZFS_SHARE_NFS:
3227 case ZFS_UNSHARE_NFS:
3228 if (zfs_nfsshare_inited == 0) {
3229 mutex_enter(&zfs_share_lock);

--- 55 unchanged lines hidden (view full) ---

3285 (uintptr_t)zc->zc_share.z_exportdata))
3286 return (error);
3287 break;
3288 case ZFS_SHARE_SMB:
3289 case ZFS_UNSHARE_SMB:
3290 if (error = zsmbexport_fs((void *)
3291 (uintptr_t)zc->zc_share.z_exportdata,
3292 zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
2914 B_TRUE : B_FALSE)) {
3293 B_TRUE: B_FALSE)) {
2915 return (error);
2916 }
2917 break;
2918 }
2919
2920 opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
2921 zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
2922 SHAREFS_ADD : SHAREFS_REMOVE;
2923
2924 /*
2925 * Add or remove share from sharetab
2926 */
2927 error = zshare_fs(opcode,
2928 (void *)(uintptr_t)zc->zc_share.z_sharedata,
2929 zc->zc_share.z_sharemax);
2930
2931 return (error);
3294 return (error);
3295 }
3296 break;
3297 }
3298
3299 opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
3300 zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
3301 SHAREFS_ADD : SHAREFS_REMOVE;
3302
3303 /*
3304 * Add or remove share from sharetab
3305 */
3306 error = zshare_fs(opcode,
3307 (void *)(uintptr_t)zc->zc_share.z_sharedata,
3308 zc->zc_share.z_sharemax);
3309
3310 return (error);
2932#else
3311#else /* sun */
2933 return (ENOSYS);
3312 return (ENOSYS);
2934#endif
3313#endif /* sun */
2935}
2936
3314}
3315
3316ace_t full_access[] = {
3317 {(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
3318};
3319
3320#ifdef sun
2937/*
3321/*
3322 * Remove all ACL files in shares dir
3323 */
3324static int
3325zfs_smb_acl_purge(znode_t *dzp)
3326{
3327 zap_cursor_t zc;
3328 zap_attribute_t zap;
3329 zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
3330 int error;
3331
3332 for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
3333 (error = zap_cursor_retrieve(&zc, &zap)) == 0;
3334 zap_cursor_advance(&zc)) {
3335 if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
3336 NULL, 0)) != 0)
3337 break;
3338 }
3339 zap_cursor_fini(&zc);
3340 return (error);
3341}
3342#endif /* sun */
3343
3344static int
3345zfs_ioc_smb_acl(zfs_cmd_t *zc)
3346{
3347#ifdef sun
3348 vnode_t *vp;
3349 znode_t *dzp;
3350 vnode_t *resourcevp = NULL;
3351 znode_t *sharedir;
3352 zfsvfs_t *zfsvfs;
3353 nvlist_t *nvlist;
3354 char *src, *target;
3355 vattr_t vattr;
3356 vsecattr_t vsec;
3357 int error = 0;
3358
3359 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
3360 NO_FOLLOW, NULL, &vp)) != 0)
3361 return (error);
3362
3363 /* Now make sure mntpnt and dataset are ZFS */
3364
3365 if (vp->v_vfsp->vfs_fstype != zfsfstype ||
3366 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
3367 zc->zc_name) != 0)) {
3368 VN_RELE(vp);
3369 return (EINVAL);
3370 }
3371
3372 dzp = VTOZ(vp);
3373 zfsvfs = dzp->z_zfsvfs;
3374
3375 ZFS_ENTER(zfsvfs);
3376
3377 /*
3378 * Create share dir if its missing.
3379 */
3380 mutex_enter(&zfsvfs->z_lock);
3381 if (zfsvfs->z_shares_dir == 0) {
3382 dmu_tx_t *tx;
3383
3384 tx = dmu_tx_create(zfsvfs->z_os);
3385 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
3386 ZFS_SHARES_DIR);
3387 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
3388 error = dmu_tx_assign(tx, TXG_WAIT);
3389 if (error) {
3390 dmu_tx_abort(tx);
3391 } else {
3392 error = zfs_create_share_dir(zfsvfs, tx);
3393 dmu_tx_commit(tx);
3394 }
3395 if (error) {
3396 mutex_exit(&zfsvfs->z_lock);
3397 VN_RELE(vp);
3398 ZFS_EXIT(zfsvfs);
3399 return (error);
3400 }
3401 }
3402 mutex_exit(&zfsvfs->z_lock);
3403
3404 ASSERT(zfsvfs->z_shares_dir);
3405 if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
3406 VN_RELE(vp);
3407 ZFS_EXIT(zfsvfs);
3408 return (error);
3409 }
3410
3411 switch (zc->zc_cookie) {
3412 case ZFS_SMB_ACL_ADD:
3413 vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
3414 vattr.va_type = VREG;
3415 vattr.va_mode = S_IFREG|0777;
3416 vattr.va_uid = 0;
3417 vattr.va_gid = 0;
3418
3419 vsec.vsa_mask = VSA_ACE;
3420 vsec.vsa_aclentp = &full_access;
3421 vsec.vsa_aclentsz = sizeof (full_access);
3422 vsec.vsa_aclcnt = 1;
3423
3424 error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
3425 &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
3426 if (resourcevp)
3427 VN_RELE(resourcevp);
3428 break;
3429
3430 case ZFS_SMB_ACL_REMOVE:
3431 error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
3432 NULL, 0);
3433 break;
3434
3435 case ZFS_SMB_ACL_RENAME:
3436 if ((error = get_nvlist(zc->zc_nvlist_src,
3437 zc->zc_nvlist_src_size, &nvlist)) != 0) {
3438 VN_RELE(vp);
3439 ZFS_EXIT(zfsvfs);
3440 return (error);
3441 }
3442 if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
3443 nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
3444 &target)) {
3445 VN_RELE(vp);
3446 VN_RELE(ZTOV(sharedir));
3447 ZFS_EXIT(zfsvfs);
3448 return (error);
3449 }
3450 error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
3451 kcred, NULL, 0);
3452 nvlist_free(nvlist);
3453 break;
3454
3455 case ZFS_SMB_ACL_PURGE:
3456 error = zfs_smb_acl_purge(sharedir);
3457 break;
3458
3459 default:
3460 error = EINVAL;
3461 break;
3462 }
3463
3464 VN_RELE(vp);
3465 VN_RELE(ZTOV(sharedir));
3466
3467 ZFS_EXIT(zfsvfs);
3468
3469 return (error);
3470#else /* !sun */
3471 return (EOPNOTSUPP);
3472#endif /* !sun */
3473}
3474
3475/*
2938 * pool create, destroy, and export don't log the history as part of
2939 * zfsdev_ioctl, but rather zfs_ioc_pool_create, and zfs_ioc_pool_export
2940 * do the logging of those commands.
2941 */
2942static int
2943zfs_ioc_jail(zfs_cmd_t *zc)
2944{
2945

--- 5 unchanged lines hidden (view full) ---

2951zfs_ioc_unjail(zfs_cmd_t *zc)
2952{
2953
2954 return (zone_dataset_detach(curthread->td_ucred, zc->zc_name,
2955 (int)zc->zc_jailid));
2956}
2957
2958static zfs_ioc_vec_t zfs_ioc_vec[] = {
3476 * pool create, destroy, and export don't log the history as part of
3477 * zfsdev_ioctl, but rather zfs_ioc_pool_create, and zfs_ioc_pool_export
3478 * do the logging of those commands.
3479 */
3480static int
3481zfs_ioc_jail(zfs_cmd_t *zc)
3482{
3483

--- 5 unchanged lines hidden (view full) ---

3489zfs_ioc_unjail(zfs_cmd_t *zc)
3490{
3491
3492 return (zone_dataset_detach(curthread->td_ucred, zc->zc_name,
3493 (int)zc->zc_jailid));
3494}
3495
3496static zfs_ioc_vec_t zfs_ioc_vec[] = {
2959 { zfs_ioc_pool_create, zfs_secpolicy_config, POOL_NAME, B_FALSE },
2960 { zfs_ioc_pool_destroy, zfs_secpolicy_config, POOL_NAME, B_FALSE },
2961 { zfs_ioc_pool_import, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2962 { zfs_ioc_pool_export, zfs_secpolicy_config, POOL_NAME, B_FALSE },
2963 { zfs_ioc_pool_configs, zfs_secpolicy_none, NO_NAME, B_FALSE },
2964 { zfs_ioc_pool_stats, zfs_secpolicy_read, POOL_NAME, B_FALSE },
2965 { zfs_ioc_pool_tryimport, zfs_secpolicy_config, NO_NAME, B_FALSE },
2966 { zfs_ioc_pool_scrub, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2967 { zfs_ioc_pool_freeze, zfs_secpolicy_config, NO_NAME, B_FALSE },
2968 { zfs_ioc_pool_upgrade, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2969 { zfs_ioc_pool_get_history, zfs_secpolicy_config, POOL_NAME, B_FALSE },
2970 { zfs_ioc_vdev_add, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2971 { zfs_ioc_vdev_remove, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2972 { zfs_ioc_vdev_set_state, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2973 { zfs_ioc_vdev_attach, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2974 { zfs_ioc_vdev_detach, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2975 { zfs_ioc_vdev_setpath, zfs_secpolicy_config, POOL_NAME, B_FALSE },
2976 { zfs_ioc_objset_stats, zfs_secpolicy_read, DATASET_NAME, B_FALSE },
2977 { zfs_ioc_objset_zplprops, zfs_secpolicy_read, DATASET_NAME, B_FALSE },
2978 { zfs_ioc_dataset_list_next, zfs_secpolicy_read,
2979 DATASET_NAME, B_FALSE },
2980 { zfs_ioc_snapshot_list_next, zfs_secpolicy_read,
2981 DATASET_NAME, B_FALSE },
2982 { zfs_ioc_set_prop, zfs_secpolicy_none, DATASET_NAME, B_TRUE },
2983 { zfs_ioc_create_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE },
2984 { zfs_ioc_remove_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE },
2985 { zfs_ioc_create, zfs_secpolicy_create, DATASET_NAME, B_TRUE },
2986 { zfs_ioc_destroy, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE },
2987 { zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, B_TRUE },
2988 { zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE },
2989 { zfs_ioc_recv, zfs_secpolicy_receive, DATASET_NAME, B_TRUE },
2990 { zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_TRUE },
2991 { zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE },
2992 { zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE },
2993 { zfs_ioc_inject_list_next, zfs_secpolicy_inject, NO_NAME, B_FALSE },
2994 { zfs_ioc_error_log, zfs_secpolicy_inject, POOL_NAME, B_FALSE },
2995 { zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE },
2996 { zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE },
2997 { zfs_ioc_destroy_snaps, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE },
2998 { zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE },
2999 { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_config, POOL_NAME, B_FALSE },
3000 { zfs_ioc_obj_to_path, zfs_secpolicy_config, NO_NAME, B_FALSE },
3001 { zfs_ioc_pool_set_props, zfs_secpolicy_config, POOL_NAME, B_TRUE },
3002 { zfs_ioc_pool_get_props, zfs_secpolicy_read, POOL_NAME, B_FALSE },
3003 { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, DATASET_NAME, B_TRUE },
3004 { zfs_ioc_get_fsacl, zfs_secpolicy_read, DATASET_NAME, B_FALSE },
3005 { zfs_ioc_iscsi_perm_check, zfs_secpolicy_iscsi,
3006 DATASET_NAME, B_FALSE },
3007 { zfs_ioc_share, zfs_secpolicy_share, DATASET_NAME, B_FALSE },
3008 { zfs_ioc_inherit_prop, zfs_secpolicy_inherit, DATASET_NAME, B_TRUE },
3009 { zfs_ioc_jail, zfs_secpolicy_config, DATASET_NAME, B_TRUE },
3010 { zfs_ioc_unjail, zfs_secpolicy_config, DATASET_NAME, B_TRUE }
3497 { zfs_ioc_pool_create, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3498 B_FALSE },
3499 { zfs_ioc_pool_destroy, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3500 B_FALSE },
3501 { zfs_ioc_pool_import, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3502 B_FALSE },
3503 { zfs_ioc_pool_export, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3504 B_FALSE },
3505 { zfs_ioc_pool_configs, zfs_secpolicy_none, NO_NAME, B_FALSE,
3506 B_FALSE },
3507 { zfs_ioc_pool_stats, zfs_secpolicy_read, POOL_NAME, B_FALSE,
3508 B_FALSE },
3509 { zfs_ioc_pool_tryimport, zfs_secpolicy_config, NO_NAME, B_FALSE,
3510 B_FALSE },
3511 { zfs_ioc_pool_scrub, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3512 B_TRUE },
3513 { zfs_ioc_pool_freeze, zfs_secpolicy_config, NO_NAME, B_FALSE,
3514 B_FALSE },
3515 { zfs_ioc_pool_upgrade, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3516 B_TRUE },
3517 { zfs_ioc_pool_get_history, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3518 B_FALSE },
3519 { zfs_ioc_vdev_add, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3520 B_TRUE },
3521 { zfs_ioc_vdev_remove, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3522 B_TRUE },
3523 { zfs_ioc_vdev_set_state, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3524 B_FALSE },
3525 { zfs_ioc_vdev_attach, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3526 B_TRUE },
3527 { zfs_ioc_vdev_detach, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3528 B_TRUE },
3529 { zfs_ioc_vdev_setpath, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3530 B_TRUE },
3531 { zfs_ioc_objset_stats, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
3532 B_TRUE },
3533 { zfs_ioc_objset_zplprops, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
3534 B_FALSE },
3535 { zfs_ioc_dataset_list_next, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
3536 B_TRUE },
3537 { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
3538 B_TRUE },
3539 { zfs_ioc_set_prop, zfs_secpolicy_none, DATASET_NAME, B_TRUE, B_TRUE },
3540 { zfs_ioc_create_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE,
3541 B_FALSE },
3542 { zfs_ioc_remove_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE,
3543 B_FALSE },
3544 { zfs_ioc_create, zfs_secpolicy_create, DATASET_NAME, B_TRUE, B_TRUE },
3545 { zfs_ioc_destroy, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE,
3546 B_TRUE},
3547 { zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, B_TRUE,
3548 B_TRUE },
3549 { zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE, B_TRUE },
3550 { zfs_ioc_recv, zfs_secpolicy_receive, DATASET_NAME, B_TRUE, B_TRUE },
3551 { zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_TRUE, B_FALSE },
3552 { zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
3553 B_FALSE },
3554 { zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
3555 B_FALSE },
3556 { zfs_ioc_inject_list_next, zfs_secpolicy_inject, NO_NAME, B_FALSE,
3557 B_FALSE },
3558 { zfs_ioc_error_log, zfs_secpolicy_inject, POOL_NAME, B_FALSE,
3559 B_FALSE },
3560 { zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE, B_FALSE },
3561 { zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE,
3562 B_TRUE },
3563 { zfs_ioc_destroy_snaps, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE,
3564 B_TRUE },
3565 { zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE,
3566 B_TRUE },
3567 { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3568 B_FALSE },
3569 { zfs_ioc_obj_to_path, zfs_secpolicy_config, NO_NAME, B_FALSE,
3570 B_FALSE },
3571 { zfs_ioc_pool_set_props, zfs_secpolicy_config, POOL_NAME, B_TRUE,
3572 B_TRUE },
3573 { zfs_ioc_pool_get_props, zfs_secpolicy_read, POOL_NAME, B_FALSE,
3574 B_FALSE },
3575 { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, DATASET_NAME, B_TRUE,
3576 B_TRUE },
3577 { zfs_ioc_get_fsacl, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
3578 B_FALSE },
3579 { zfs_ioc_iscsi_perm_check, zfs_secpolicy_iscsi, DATASET_NAME, B_FALSE,
3580 B_FALSE },
3581 { zfs_ioc_share, zfs_secpolicy_share, DATASET_NAME, B_FALSE, B_FALSE },
3582 { zfs_ioc_inherit_prop, zfs_secpolicy_inherit, DATASET_NAME, B_TRUE,
3583 B_TRUE },
3584 { zfs_ioc_jail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE },
3585 { zfs_ioc_unjail, zfs_secpolicy_config, DATASET_NAME, B_TRUE, B_FALSE },
3586 { zfs_ioc_smb_acl, zfs_secpolicy_smb_acl, DATASET_NAME, B_FALSE,
3587 B_FALSE },
3588 { zfs_ioc_userspace_one, zfs_secpolicy_userspace_one,
3589 DATASET_NAME, B_FALSE, B_FALSE },
3590 { zfs_ioc_userspace_many, zfs_secpolicy_userspace_many,
3591 DATASET_NAME, B_FALSE, B_FALSE },
3592 { zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
3593 DATASET_NAME, B_FALSE, B_TRUE },
3594 { zfs_ioc_vdev_setfru, zfs_secpolicy_config, POOL_NAME, B_FALSE,
3595 B_TRUE }
3011};
3012
3596};
3597
3598int
3599pool_status_check(const char *name, zfs_ioc_namecheck_t type)
3600{
3601 spa_t *spa;
3602 char pool[ZFS_MAXNAMELEN];
3603 int error;
3604
3605 ASSERT(type == POOL_NAME || type == DATASET_NAME);
3606
3607 error = spa_open(name, &spa, FTAG);
3608 if (error == 0) {
3609 if (spa_suspended(spa))
3610 error = EAGAIN;
3611 spa_close(spa, FTAG);
3612 }
3613 return (error);
3614}
3615
3013static int
3014zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
3015 struct thread *td)
3016{
3017 zfs_cmd_t *zc = (void *)addr;
3018 uint_t vec;
3019 int error;
3020

--- 9 unchanged lines hidden (view full) ---

3030 * the lower layers.
3031 */
3032 if (error == 0) {
3033 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
3034 switch (zfs_ioc_vec[vec].zvec_namecheck) {
3035 case POOL_NAME:
3036 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
3037 error = EINVAL;
3616static int
3617zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
3618 struct thread *td)
3619{
3620 zfs_cmd_t *zc = (void *)addr;
3621 uint_t vec;
3622 int error;
3623

--- 9 unchanged lines hidden (view full) ---

3633 * the lower layers.
3634 */
3635 if (error == 0) {
3636 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
3637 switch (zfs_ioc_vec[vec].zvec_namecheck) {
3638 case POOL_NAME:
3639 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
3640 error = EINVAL;
3641 if (zfs_ioc_vec[vec].zvec_pool_check)
3642 error = pool_status_check(zc->zc_name,
3643 zfs_ioc_vec[vec].zvec_namecheck);
3038 break;
3039
3040 case DATASET_NAME:
3041 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
3042 error = EINVAL;
3644 break;
3645
3646 case DATASET_NAME:
3647 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
3648 error = EINVAL;
3649 if (zfs_ioc_vec[vec].zvec_pool_check)
3650 error = pool_status_check(zc->zc_name,
3651 zfs_ioc_vec[vec].zvec_namecheck);
3043 break;
3044
3045 case NO_NAME:
3046 break;
3047 }
3048 }
3049
3050 if (error == 0)
3051 error = zfs_ioc_vec[vec].zvec_func(zc);
3052
3053 if (error == 0) {
3652 break;
3653
3654 case NO_NAME:
3655 break;
3656 }
3657 }
3658
3659 if (error == 0)
3660 error = zfs_ioc_vec[vec].zvec_func(zc);
3661
3662 if (error == 0) {
3054 if (zfs_ioc_vec[vec].zvec_his_log == B_TRUE)
3663 if (zfs_ioc_vec[vec].zvec_his_log)
3055 zfs_log_history(zc);
3056 }
3057
3058 return (error);
3059}
3060
3061/*
3062 * OK, so this is a little weird.

--- 88 unchanged lines hidden ---
3664 zfs_log_history(zc);
3665 }
3666
3667 return (error);
3668}
3669
3670/*
3671 * OK, so this is a little weird.

--- 88 unchanged lines hidden ---