37 #include <errno.h>
38 #include <libintl.h>
39 #include <math.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <strings.h>
43 #include <unistd.h>
44 #include <stddef.h>
45 #include <zone.h>
46 #include <fcntl.h>
47 #include <sys/mntent.h>
48 #include <sys/mount.h>
49 #include <priv.h>
50 #include <pwd.h>
51 #include <grp.h>
52 #include <stddef.h>
53 #include <ucred.h>
54 #include <idmap.h>
55 #include <aclutils.h>
56 #include <directory.h>
57
58 #include <sys/dnode.h>
59 #include <sys/spa.h>
60 #include <sys/zap.h>
61 #include <libzfs.h>
62
63 #include "zfs_namecheck.h"
64 #include "zfs_prop.h"
65 #include "libzfs_impl.h"
66 #include "zfs_deleg.h"
67
68 static int userquota_propname_decode(const char *propname, boolean_t zoned,
69 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
70
71 /*
72 * Given a single type (not a mask of types), return the type in a human
73 * readable form.
74 */
75 const char *
76 zfs_type_to_name(zfs_type_t type)
768 avl_node_t mtn_node;
769 } mnttab_node_t;
770
771 static int
772 libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
773 {
774 const mnttab_node_t *mtn1 = arg1;
775 const mnttab_node_t *mtn2 = arg2;
776 int rv;
777
778 rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
779
780 if (rv == 0)
781 return (0);
782 return (rv > 0 ? 1 : -1);
783 }
784
785 void
786 libzfs_mnttab_init(libzfs_handle_t *hdl)
787 {
788 assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
789 avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
790 sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
791 }
792
793 void
794 libzfs_mnttab_update(libzfs_handle_t *hdl)
795 {
796 struct mnttab entry;
797
798 rewind(hdl->libzfs_mnttab);
799 while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
800 mnttab_node_t *mtn;
801
802 if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
803 continue;
804 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
805 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
806 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
807 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
808 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
809 avl_add(&hdl->libzfs_mnttab_cache, mtn);
810 }
811 }
812
813 void
814 libzfs_mnttab_fini(libzfs_handle_t *hdl)
815 {
816 void *cookie = NULL;
817 mnttab_node_t *mtn;
818
819 while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))
820 != NULL) {
821 free(mtn->mtn_mt.mnt_special);
822 free(mtn->mtn_mt.mnt_mountp);
823 free(mtn->mtn_mt.mnt_fstype);
824 free(mtn->mtn_mt.mnt_mntopts);
825 free(mtn);
826 }
827 avl_destroy(&hdl->libzfs_mnttab_cache);
828 }
829
830 void
831 libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
832 {
833 hdl->libzfs_mnttab_enable = enable;
834 }
835
836 int
837 libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
838 struct mnttab *entry)
839 {
840 mnttab_node_t find;
841 mnttab_node_t *mtn;
842
843 if (!hdl->libzfs_mnttab_enable) {
844 struct mnttab srch = { 0 };
845
846 if (avl_numnodes(&hdl->libzfs_mnttab_cache))
847 libzfs_mnttab_fini(hdl);
848 rewind(hdl->libzfs_mnttab);
849 srch.mnt_special = (char *)fsname;
850 srch.mnt_fstype = MNTTYPE_ZFS;
851 if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0)
852 return (0);
853 else
854 return (ENOENT);
855 }
856
857 if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
858 libzfs_mnttab_update(hdl);
859
860 find.mtn_mt.mnt_special = (char *)fsname;
861 mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
862 if (mtn) {
863 *entry = mtn->mtn_mt;
864 return (0);
865 }
866 return (ENOENT);
867 }
868
869 void
870 libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
871 const char *mountp, const char *mntopts)
872 {
873 mnttab_node_t *mtn;
874
875 if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
876 return;
877 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
878 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
879 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
880 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
881 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
882 avl_add(&hdl->libzfs_mnttab_cache, mtn);
883 }
884
885 void
886 libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
887 {
888 mnttab_node_t find;
889 mnttab_node_t *ret;
890
891 find.mtn_mt.mnt_special = (char *)fsname;
892 if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))
893 != NULL) {
894 avl_remove(&hdl->libzfs_mnttab_cache, ret);
895 free(ret->mtn_mt.mnt_special);
896 free(ret->mtn_mt.mnt_mountp);
897 free(ret->mtn_mt.mnt_fstype);
898 free(ret->mtn_mt.mnt_mntopts);
899 free(ret);
900 }
901 }
902
903 int
904 zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
905 {
906 zpool_handle_t *zpool_handle = zhp->zpool_hdl;
907
908 if (zpool_handle == NULL)
909 return (-1);
910
911 *spa_version = zpool_get_prop_int(zpool_handle,
912 ZPOOL_PROP_VERSION, NULL);
913 return (0);
914 }
915
916 /*
917 * The choice of reservation property depends on the SPA version.
918 */
919 static int
920 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
|
37 #include <errno.h>
38 #include <libintl.h>
39 #include <math.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <strings.h>
43 #include <unistd.h>
44 #include <stddef.h>
45 #include <zone.h>
46 #include <fcntl.h>
47 #include <sys/mntent.h>
48 #include <sys/mount.h>
49 #include <priv.h>
50 #include <pwd.h>
51 #include <grp.h>
52 #include <stddef.h>
53 #include <ucred.h>
54 #include <idmap.h>
55 #include <aclutils.h>
56 #include <directory.h>
57 #include <time.h>
58
59 #include <sys/dnode.h>
60 #include <sys/spa.h>
61 #include <sys/zap.h>
62 #include <libzfs.h>
63
64 #include "zfs_namecheck.h"
65 #include "zfs_prop.h"
66 #include "libzfs_impl.h"
67 #include "zfs_deleg.h"
68
69 static int userquota_propname_decode(const char *propname, boolean_t zoned,
70 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
71
72 /*
73 * Given a single type (not a mask of types), return the type in a human
74 * readable form.
75 */
76 const char *
77 zfs_type_to_name(zfs_type_t type)
769 avl_node_t mtn_node;
770 } mnttab_node_t;
771
772 static int
773 libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
774 {
775 const mnttab_node_t *mtn1 = arg1;
776 const mnttab_node_t *mtn2 = arg2;
777 int rv;
778
779 rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
780
781 if (rv == 0)
782 return (0);
783 return (rv > 0 ? 1 : -1);
784 }
785
786 void
787 libzfs_mnttab_init(libzfs_handle_t *hdl)
788 {
789 (void) mutex_init(&hdl->libzfs_mnttab_cache_lock, USYNC_THREAD, NULL);
790 assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
791 avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
792 sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
793 }
794
795 void
796 libzfs_mnttab_update(libzfs_handle_t *hdl)
797 {
798 struct mnttab entry;
799
800 rewind(hdl->libzfs_mnttab);
801 while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
802 mnttab_node_t *mtn;
803
804 if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
805 continue;
806 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
807 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
808 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
809 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
810 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
811 avl_add(&hdl->libzfs_mnttab_cache, mtn);
812 }
813 }
814
815 void
816 libzfs_mnttab_fini(libzfs_handle_t *hdl)
817 {
818 void *cookie = NULL;
819 mnttab_node_t *mtn;
820
821 while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))
822 != NULL) {
823 free(mtn->mtn_mt.mnt_special);
824 free(mtn->mtn_mt.mnt_mountp);
825 free(mtn->mtn_mt.mnt_fstype);
826 free(mtn->mtn_mt.mnt_mntopts);
827 free(mtn);
828 }
829 avl_destroy(&hdl->libzfs_mnttab_cache);
830 (void) mutex_destroy(&hdl->libzfs_mnttab_cache_lock);
831 }
832
833 void
834 libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
835 {
836 hdl->libzfs_mnttab_enable = enable;
837 }
838
839 int
840 libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
841 struct mnttab *entry)
842 {
843 mnttab_node_t find;
844 mnttab_node_t *mtn;
845 int ret = ENOENT;
846
847 if (!hdl->libzfs_mnttab_enable) {
848 struct mnttab srch = { 0 };
849
850 if (avl_numnodes(&hdl->libzfs_mnttab_cache))
851 libzfs_mnttab_fini(hdl);
852 rewind(hdl->libzfs_mnttab);
853 srch.mnt_special = (char *)fsname;
854 srch.mnt_fstype = MNTTYPE_ZFS;
855 if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0)
856 ret = 0;
857 return (ret);
858 }
859
860 (void) mutex_lock(&hdl->libzfs_mnttab_cache_lock);
861 if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
862 libzfs_mnttab_update(hdl);
863
864 find.mtn_mt.mnt_special = (char *)fsname;
865 mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
866 if (mtn) {
867 *entry = mtn->mtn_mt;
868 ret = 0;
869 }
870 (void) mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
871 return (ret);
872 }
873
874 void
875 libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
876 const char *mountp, const char *mntopts)
877 {
878 mnttab_node_t *mtn;
879
880 (void) mutex_lock(&hdl->libzfs_mnttab_cache_lock);
881 if (avl_numnodes(&hdl->libzfs_mnttab_cache) != 0) {
882 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
883 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
884 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
885 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
886 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
887 avl_add(&hdl->libzfs_mnttab_cache, mtn);
888 }
889 (void) mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
890 }
891
892 void
893 libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
894 {
895 mnttab_node_t find;
896 mnttab_node_t *ret;
897
898 (void) mutex_lock(&hdl->libzfs_mnttab_cache_lock);
899 find.mtn_mt.mnt_special = (char *)fsname;
900 if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))
901 != NULL) {
902 avl_remove(&hdl->libzfs_mnttab_cache, ret);
903 free(ret->mtn_mt.mnt_special);
904 free(ret->mtn_mt.mnt_mountp);
905 free(ret->mtn_mt.mnt_fstype);
906 free(ret->mtn_mt.mnt_mntopts);
907 free(ret);
908 }
909 (void) mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
910 }
911
912 int
913 zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
914 {
915 zpool_handle_t *zpool_handle = zhp->zpool_hdl;
916
917 if (zpool_handle == NULL)
918 return (-1);
919
920 *spa_version = zpool_get_prop_int(zpool_handle,
921 ZPOOL_PROP_VERSION, NULL);
922 return (0);
923 }
924
925 /*
926 * The choice of reservation property depends on the SPA version.
927 */
928 static int
929 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
|