161145dc2SMartin Matuska // SPDX-License-Identifier: CDDL-1.0
27a7741afSMartin Matuska /*
37a7741afSMartin Matuska * CDDL HEADER START
47a7741afSMartin Matuska *
57a7741afSMartin Matuska * The contents of this file are subject to the terms of the
67a7741afSMartin Matuska * Common Development and Distribution License (the "License").
77a7741afSMartin Matuska * You may not use this file except in compliance with the License.
87a7741afSMartin Matuska *
97a7741afSMartin Matuska * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107a7741afSMartin Matuska * or https://opensource.org/licenses/CDDL-1.0.
117a7741afSMartin Matuska * See the License for the specific language governing permissions
127a7741afSMartin Matuska * and limitations under the License.
137a7741afSMartin Matuska *
147a7741afSMartin Matuska * When distributing Covered Code, include this CDDL HEADER in each
157a7741afSMartin Matuska * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167a7741afSMartin Matuska * If applicable, add the following below this CDDL HEADER, with the
177a7741afSMartin Matuska * fields enclosed by brackets "[]" replaced with your own identifying
187a7741afSMartin Matuska * information: Portions Copyright [yyyy] [name of copyright owner]
197a7741afSMartin Matuska *
207a7741afSMartin Matuska * CDDL HEADER END
217a7741afSMartin Matuska */
227a7741afSMartin Matuska /*
237a7741afSMartin Matuska * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
247a7741afSMartin Matuska * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
257a7741afSMartin Matuska * Copyright (c) 2014 Integros [integros.com]
267a7741afSMartin Matuska */
277a7741afSMartin Matuska
287a7741afSMartin Matuska /* Portions Copyright 2007 Jeremy Teo */
297a7741afSMartin Matuska /* Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org> */
307a7741afSMartin Matuska
317a7741afSMartin Matuska #include <sys/dmu.h>
327a7741afSMartin Matuska #include <sys/dmu_objset.h>
337a7741afSMartin Matuska #include <sys/dmu_tx.h>
347a7741afSMartin Matuska #include <sys/zfs_refcount.h>
357a7741afSMartin Matuska #include <sys/stat.h>
367a7741afSMartin Matuska #include <sys/zap.h>
377a7741afSMartin Matuska #include <sys/zfs_znode.h>
387a7741afSMartin Matuska #include <sys/sa.h>
397a7741afSMartin Matuska #include <sys/zfs_sa.h>
407a7741afSMartin Matuska #include <sys/zfs_stat.h>
417a7741afSMartin Matuska
427a7741afSMartin Matuska #include "zfs_prop.h"
437a7741afSMartin Matuska #include "zfs_comutil.h"
447a7741afSMartin Matuska
457a7741afSMartin Matuska static int
zfs_sa_setup(objset_t * osp,sa_attr_type_t ** sa_table)467a7741afSMartin Matuska zfs_sa_setup(objset_t *osp, sa_attr_type_t **sa_table)
477a7741afSMartin Matuska {
487a7741afSMartin Matuska uint64_t sa_obj = 0;
497a7741afSMartin Matuska int error;
507a7741afSMartin Matuska
517a7741afSMartin Matuska error = zap_lookup(osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj);
527a7741afSMartin Matuska if (error != 0 && error != ENOENT)
537a7741afSMartin Matuska return (error);
547a7741afSMartin Matuska
557a7741afSMartin Matuska error = sa_setup(osp, sa_obj, zfs_attr_table, ZPL_END, sa_table);
567a7741afSMartin Matuska return (error);
577a7741afSMartin Matuska }
587a7741afSMartin Matuska
597a7741afSMartin Matuska static int
zfs_grab_sa_handle(objset_t * osp,uint64_t obj,sa_handle_t ** hdlp,dmu_buf_t ** db,const void * tag)607a7741afSMartin Matuska zfs_grab_sa_handle(objset_t *osp, uint64_t obj, sa_handle_t **hdlp,
617a7741afSMartin Matuska dmu_buf_t **db, const void *tag)
627a7741afSMartin Matuska {
637a7741afSMartin Matuska dmu_object_info_t doi;
647a7741afSMartin Matuska int error;
657a7741afSMartin Matuska
667a7741afSMartin Matuska if ((error = sa_buf_hold(osp, obj, tag, db)) != 0)
677a7741afSMartin Matuska return (error);
687a7741afSMartin Matuska
697a7741afSMartin Matuska dmu_object_info_from_db(*db, &doi);
707a7741afSMartin Matuska if ((doi.doi_bonus_type != DMU_OT_SA &&
717a7741afSMartin Matuska doi.doi_bonus_type != DMU_OT_ZNODE) ||
727a7741afSMartin Matuska (doi.doi_bonus_type == DMU_OT_ZNODE &&
737a7741afSMartin Matuska doi.doi_bonus_size < sizeof (znode_phys_t))) {
747a7741afSMartin Matuska sa_buf_rele(*db, tag);
757a7741afSMartin Matuska return (SET_ERROR(ENOTSUP));
767a7741afSMartin Matuska }
777a7741afSMartin Matuska
787a7741afSMartin Matuska error = sa_handle_get(osp, obj, NULL, SA_HDL_PRIVATE, hdlp);
797a7741afSMartin Matuska if (error != 0) {
807a7741afSMartin Matuska sa_buf_rele(*db, tag);
817a7741afSMartin Matuska return (error);
827a7741afSMartin Matuska }
837a7741afSMartin Matuska
847a7741afSMartin Matuska return (0);
857a7741afSMartin Matuska }
867a7741afSMartin Matuska
877a7741afSMartin Matuska static void
zfs_release_sa_handle(sa_handle_t * hdl,dmu_buf_t * db,const void * tag)887a7741afSMartin Matuska zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, const void *tag)
897a7741afSMartin Matuska {
907a7741afSMartin Matuska sa_handle_destroy(hdl);
917a7741afSMartin Matuska sa_buf_rele(db, tag);
927a7741afSMartin Matuska }
937a7741afSMartin Matuska
947a7741afSMartin Matuska /*
957a7741afSMartin Matuska * Given an object number, return its parent object number and whether
967a7741afSMartin Matuska * or not the object is an extended attribute directory.
977a7741afSMartin Matuska */
987a7741afSMartin Matuska int
zfs_obj_to_pobj(objset_t * osp,sa_handle_t * hdl,sa_attr_type_t * sa_table,uint64_t * pobjp,int * is_xattrdir)997a7741afSMartin Matuska zfs_obj_to_pobj(objset_t *osp, sa_handle_t *hdl, sa_attr_type_t *sa_table,
1007a7741afSMartin Matuska uint64_t *pobjp, int *is_xattrdir)
1017a7741afSMartin Matuska {
1027a7741afSMartin Matuska uint64_t parent;
1037a7741afSMartin Matuska uint64_t pflags;
1047a7741afSMartin Matuska uint64_t mode;
1057a7741afSMartin Matuska uint64_t parent_mode;
1067a7741afSMartin Matuska sa_bulk_attr_t bulk[3];
1077a7741afSMartin Matuska sa_handle_t *sa_hdl;
1087a7741afSMartin Matuska dmu_buf_t *sa_db;
1097a7741afSMartin Matuska int count = 0;
1107a7741afSMartin Matuska int error;
1117a7741afSMartin Matuska
1127a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_PARENT], NULL,
1137a7741afSMartin Matuska &parent, sizeof (parent));
1147a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_FLAGS], NULL,
1157a7741afSMartin Matuska &pflags, sizeof (pflags));
1167a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL,
1177a7741afSMartin Matuska &mode, sizeof (mode));
1187a7741afSMartin Matuska
1197a7741afSMartin Matuska if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0)
1207a7741afSMartin Matuska return (error);
1217a7741afSMartin Matuska
1227a7741afSMartin Matuska /*
1237a7741afSMartin Matuska * When a link is removed its parent pointer is not changed and will
1247a7741afSMartin Matuska * be invalid. There are two cases where a link is removed but the
1257a7741afSMartin Matuska * file stays around, when it goes to the delete queue and when there
1267a7741afSMartin Matuska * are additional links.
1277a7741afSMartin Matuska */
1287a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, parent, &sa_hdl, &sa_db, FTAG);
1297a7741afSMartin Matuska if (error != 0)
1307a7741afSMartin Matuska return (error);
1317a7741afSMartin Matuska
1327a7741afSMartin Matuska error = sa_lookup(sa_hdl, ZPL_MODE, &parent_mode, sizeof (parent_mode));
1337a7741afSMartin Matuska zfs_release_sa_handle(sa_hdl, sa_db, FTAG);
1347a7741afSMartin Matuska if (error != 0)
1357a7741afSMartin Matuska return (error);
1367a7741afSMartin Matuska
1377a7741afSMartin Matuska *is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode);
1387a7741afSMartin Matuska
1397a7741afSMartin Matuska /*
1407a7741afSMartin Matuska * Extended attributes can be applied to files, directories, etc.
1417a7741afSMartin Matuska * Otherwise the parent must be a directory.
1427a7741afSMartin Matuska */
1437a7741afSMartin Matuska if (!*is_xattrdir && !S_ISDIR(parent_mode))
1447a7741afSMartin Matuska return (SET_ERROR(EINVAL));
1457a7741afSMartin Matuska
1467a7741afSMartin Matuska *pobjp = parent;
1477a7741afSMartin Matuska
1487a7741afSMartin Matuska return (0);
1497a7741afSMartin Matuska }
1507a7741afSMartin Matuska
1517a7741afSMartin Matuska /*
1527a7741afSMartin Matuska * Given an object number, return some zpl level statistics
1537a7741afSMartin Matuska */
1547a7741afSMartin Matuska static int
zfs_obj_to_stats_impl(sa_handle_t * hdl,sa_attr_type_t * sa_table,zfs_stat_t * sb)1557a7741afSMartin Matuska zfs_obj_to_stats_impl(sa_handle_t *hdl, sa_attr_type_t *sa_table,
1567a7741afSMartin Matuska zfs_stat_t *sb)
1577a7741afSMartin Matuska {
1587a7741afSMartin Matuska sa_bulk_attr_t bulk[4];
1597a7741afSMartin Matuska int count = 0;
1607a7741afSMartin Matuska
1617a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL,
1627a7741afSMartin Matuska &sb->zs_mode, sizeof (sb->zs_mode));
1637a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_GEN], NULL,
1647a7741afSMartin Matuska &sb->zs_gen, sizeof (sb->zs_gen));
1657a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_LINKS], NULL,
1667a7741afSMartin Matuska &sb->zs_links, sizeof (sb->zs_links));
1677a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_CTIME], NULL,
1687a7741afSMartin Matuska &sb->zs_ctime, sizeof (sb->zs_ctime));
1697a7741afSMartin Matuska
1707a7741afSMartin Matuska return (sa_bulk_lookup(hdl, bulk, count));
1717a7741afSMartin Matuska }
1727a7741afSMartin Matuska
1737a7741afSMartin Matuska static int
zfs_obj_to_path_impl(objset_t * osp,uint64_t obj,sa_handle_t * hdl,sa_attr_type_t * sa_table,char * buf,int len)1747a7741afSMartin Matuska zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
1757a7741afSMartin Matuska sa_attr_type_t *sa_table, char *buf, int len)
1767a7741afSMartin Matuska {
1777a7741afSMartin Matuska sa_handle_t *sa_hdl;
1787a7741afSMartin Matuska sa_handle_t *prevhdl = NULL;
1797a7741afSMartin Matuska dmu_buf_t *prevdb = NULL;
1807a7741afSMartin Matuska dmu_buf_t *sa_db = NULL;
1817a7741afSMartin Matuska char *path = buf + len - 1;
1827a7741afSMartin Matuska char *comp_buf;
1837a7741afSMartin Matuska int error;
1847a7741afSMartin Matuska
1857a7741afSMartin Matuska *path = '\0';
1867a7741afSMartin Matuska sa_hdl = hdl;
1877a7741afSMartin Matuska
1887a7741afSMartin Matuska uint64_t deleteq_obj;
1897a7741afSMartin Matuska VERIFY0(zap_lookup(osp, MASTER_NODE_OBJ,
1907a7741afSMartin Matuska ZFS_UNLINKED_SET, sizeof (uint64_t), 1, &deleteq_obj));
1917a7741afSMartin Matuska error = zap_lookup_int(osp, deleteq_obj, obj);
1927a7741afSMartin Matuska if (error == 0) {
1937a7741afSMartin Matuska return (ESTALE);
1947a7741afSMartin Matuska } else if (error != ENOENT) {
1957a7741afSMartin Matuska return (error);
1967a7741afSMartin Matuska }
1977a7741afSMartin Matuska
1987a7741afSMartin Matuska comp_buf = kmem_alloc(ZAP_MAXNAMELEN_NEW + 2, KM_SLEEP);
1997a7741afSMartin Matuska for (;;) {
2007a7741afSMartin Matuska uint64_t pobj = 0;
2017a7741afSMartin Matuska char *component = comp_buf;
2027a7741afSMartin Matuska size_t complen;
2037a7741afSMartin Matuska int is_xattrdir = 0;
2047a7741afSMartin Matuska
2057a7741afSMartin Matuska if (prevdb) {
2067a7741afSMartin Matuska ASSERT3P(prevhdl, !=, NULL);
2077a7741afSMartin Matuska zfs_release_sa_handle(prevhdl, prevdb, FTAG);
2087a7741afSMartin Matuska }
2097a7741afSMartin Matuska
2107a7741afSMartin Matuska if ((error = zfs_obj_to_pobj(osp, sa_hdl, sa_table, &pobj,
2117a7741afSMartin Matuska &is_xattrdir)) != 0)
2127a7741afSMartin Matuska break;
2137a7741afSMartin Matuska
2147a7741afSMartin Matuska if (pobj == obj) {
2157a7741afSMartin Matuska if (path[0] != '/')
2167a7741afSMartin Matuska *--path = '/';
2177a7741afSMartin Matuska break;
2187a7741afSMartin Matuska }
2197a7741afSMartin Matuska
2207a7741afSMartin Matuska component[0] = '/';
2217a7741afSMartin Matuska if (is_xattrdir) {
2227a7741afSMartin Matuska strcpy(component + 1, "<xattrdir>");
2237a7741afSMartin Matuska } else {
2247a7741afSMartin Matuska error = zap_value_search(osp, pobj, obj,
2257a7741afSMartin Matuska ZFS_DIRENT_OBJ(-1ULL), component + 1,
2267a7741afSMartin Matuska ZAP_MAXNAMELEN_NEW);
2277a7741afSMartin Matuska if (error != 0)
2287a7741afSMartin Matuska break;
2297a7741afSMartin Matuska }
2307a7741afSMartin Matuska
2317a7741afSMartin Matuska complen = strlen(component);
2327a7741afSMartin Matuska path -= complen;
2337a7741afSMartin Matuska ASSERT3P(path, >=, buf);
2347a7741afSMartin Matuska memcpy(path, component, complen);
2357a7741afSMartin Matuska obj = pobj;
2367a7741afSMartin Matuska
2377a7741afSMartin Matuska if (sa_hdl != hdl) {
2387a7741afSMartin Matuska prevhdl = sa_hdl;
2397a7741afSMartin Matuska prevdb = sa_db;
2407a7741afSMartin Matuska }
2417a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, obj, &sa_hdl, &sa_db, FTAG);
2427a7741afSMartin Matuska if (error != 0) {
2437a7741afSMartin Matuska sa_hdl = prevhdl;
2447a7741afSMartin Matuska sa_db = prevdb;
2457a7741afSMartin Matuska break;
2467a7741afSMartin Matuska }
2477a7741afSMartin Matuska }
2487a7741afSMartin Matuska
2497a7741afSMartin Matuska if (sa_hdl != NULL && sa_hdl != hdl) {
2507a7741afSMartin Matuska ASSERT3P(sa_db, !=, NULL);
2517a7741afSMartin Matuska zfs_release_sa_handle(sa_hdl, sa_db, FTAG);
2527a7741afSMartin Matuska }
2537a7741afSMartin Matuska
2547a7741afSMartin Matuska if (error == 0)
2557a7741afSMartin Matuska (void) memmove(buf, path, buf + len - path);
2567a7741afSMartin Matuska
2577a7741afSMartin Matuska kmem_free(comp_buf, ZAP_MAXNAMELEN_NEW +2);
2587a7741afSMartin Matuska return (error);
2597a7741afSMartin Matuska }
2607a7741afSMartin Matuska
2617a7741afSMartin Matuska int
zfs_obj_to_path(objset_t * osp,uint64_t obj,char * buf,int len)2627a7741afSMartin Matuska zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len)
2637a7741afSMartin Matuska {
2647a7741afSMartin Matuska sa_attr_type_t *sa_table;
2657a7741afSMartin Matuska sa_handle_t *hdl;
2667a7741afSMartin Matuska dmu_buf_t *db;
2677a7741afSMartin Matuska int error;
2687a7741afSMartin Matuska
2697a7741afSMartin Matuska error = zfs_sa_setup(osp, &sa_table);
2707a7741afSMartin Matuska if (error != 0)
2717a7741afSMartin Matuska return (error);
2727a7741afSMartin Matuska
2737a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG);
2747a7741afSMartin Matuska if (error != 0)
2757a7741afSMartin Matuska return (error);
2767a7741afSMartin Matuska
2777a7741afSMartin Matuska error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len);
2787a7741afSMartin Matuska
2797a7741afSMartin Matuska zfs_release_sa_handle(hdl, db, FTAG);
2807a7741afSMartin Matuska return (error);
2817a7741afSMartin Matuska }
2827a7741afSMartin Matuska
2837a7741afSMartin Matuska int
zfs_obj_to_stats(objset_t * osp,uint64_t obj,zfs_stat_t * sb,char * buf,int len)2847a7741afSMartin Matuska zfs_obj_to_stats(objset_t *osp, uint64_t obj, zfs_stat_t *sb,
2857a7741afSMartin Matuska char *buf, int len)
2867a7741afSMartin Matuska {
2877a7741afSMartin Matuska char *path = buf + len - 1;
2887a7741afSMartin Matuska sa_attr_type_t *sa_table;
2897a7741afSMartin Matuska sa_handle_t *hdl;
2907a7741afSMartin Matuska dmu_buf_t *db;
2917a7741afSMartin Matuska int error;
2927a7741afSMartin Matuska
2937a7741afSMartin Matuska *path = '\0';
2947a7741afSMartin Matuska
2957a7741afSMartin Matuska error = zfs_sa_setup(osp, &sa_table);
2967a7741afSMartin Matuska if (error != 0)
2977a7741afSMartin Matuska return (error);
2987a7741afSMartin Matuska
2997a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG);
3007a7741afSMartin Matuska if (error != 0)
3017a7741afSMartin Matuska return (error);
3027a7741afSMartin Matuska
3037a7741afSMartin Matuska error = zfs_obj_to_stats_impl(hdl, sa_table, sb);
3047a7741afSMartin Matuska if (error != 0) {
3057a7741afSMartin Matuska zfs_release_sa_handle(hdl, db, FTAG);
3067a7741afSMartin Matuska return (error);
3077a7741afSMartin Matuska }
3087a7741afSMartin Matuska
3097a7741afSMartin Matuska error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len);
3107a7741afSMartin Matuska
3117a7741afSMartin Matuska zfs_release_sa_handle(hdl, db, FTAG);
3127a7741afSMartin Matuska return (error);
3137a7741afSMartin Matuska }
3147a7741afSMartin Matuska
3157a7741afSMartin Matuska /*
3167a7741afSMartin Matuska * Read a property stored within the master node.
3177a7741afSMartin Matuska */
3187a7741afSMartin Matuska int
zfs_get_zplprop(objset_t * os,zfs_prop_t prop,uint64_t * value)3197a7741afSMartin Matuska zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
3207a7741afSMartin Matuska {
3217a7741afSMartin Matuska uint64_t *cached_copy = NULL;
3227a7741afSMartin Matuska
3237a7741afSMartin Matuska /*
3247a7741afSMartin Matuska * Figure out where in the objset_t the cached copy would live, if it
3257a7741afSMartin Matuska * is available for the requested property.
3267a7741afSMartin Matuska */
3277a7741afSMartin Matuska if (os != NULL) {
3287a7741afSMartin Matuska switch (prop) {
3297a7741afSMartin Matuska case ZFS_PROP_VERSION:
3307a7741afSMartin Matuska cached_copy = &os->os_version;
3317a7741afSMartin Matuska break;
3327a7741afSMartin Matuska case ZFS_PROP_NORMALIZE:
3337a7741afSMartin Matuska cached_copy = &os->os_normalization;
3347a7741afSMartin Matuska break;
3357a7741afSMartin Matuska case ZFS_PROP_UTF8ONLY:
3367a7741afSMartin Matuska cached_copy = &os->os_utf8only;
3377a7741afSMartin Matuska break;
3387a7741afSMartin Matuska case ZFS_PROP_CASE:
3397a7741afSMartin Matuska cached_copy = &os->os_casesensitivity;
3407a7741afSMartin Matuska break;
3417a7741afSMartin Matuska default:
3427a7741afSMartin Matuska break;
3437a7741afSMartin Matuska }
3447a7741afSMartin Matuska }
3457a7741afSMartin Matuska if (cached_copy != NULL && *cached_copy != OBJSET_PROP_UNINITIALIZED) {
3467a7741afSMartin Matuska *value = *cached_copy;
3477a7741afSMartin Matuska return (0);
3487a7741afSMartin Matuska }
3497a7741afSMartin Matuska
3507a7741afSMartin Matuska /*
3517a7741afSMartin Matuska * If the property wasn't cached, look up the file system's value for
3527a7741afSMartin Matuska * the property. For the version property, we look up a slightly
3537a7741afSMartin Matuska * different string.
3547a7741afSMartin Matuska */
3557a7741afSMartin Matuska const char *pname;
3567a7741afSMartin Matuska int error = ENOENT;
3577a7741afSMartin Matuska if (prop == ZFS_PROP_VERSION)
3587a7741afSMartin Matuska pname = ZPL_VERSION_STR;
3597a7741afSMartin Matuska else
3607a7741afSMartin Matuska pname = zfs_prop_to_name(prop);
3617a7741afSMartin Matuska
3627a7741afSMartin Matuska if (os != NULL) {
3637a7741afSMartin Matuska ASSERT3U(os->os_phys->os_type, ==, DMU_OST_ZFS);
3647a7741afSMartin Matuska error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value);
3657a7741afSMartin Matuska }
3667a7741afSMartin Matuska
3677a7741afSMartin Matuska if (error == ENOENT) {
3687a7741afSMartin Matuska /* No value set, use the default value */
3697a7741afSMartin Matuska switch (prop) {
3707a7741afSMartin Matuska case ZFS_PROP_VERSION:
3717a7741afSMartin Matuska *value = ZPL_VERSION;
3727a7741afSMartin Matuska break;
3737a7741afSMartin Matuska case ZFS_PROP_NORMALIZE:
3747a7741afSMartin Matuska case ZFS_PROP_UTF8ONLY:
3757a7741afSMartin Matuska *value = 0;
3767a7741afSMartin Matuska break;
3777a7741afSMartin Matuska case ZFS_PROP_CASE:
3787a7741afSMartin Matuska *value = ZFS_CASE_SENSITIVE;
3797a7741afSMartin Matuska break;
3807a7741afSMartin Matuska case ZFS_PROP_ACLTYPE:
3817a7741afSMartin Matuska #ifdef __FreeBSD__
3827a7741afSMartin Matuska *value = ZFS_ACLTYPE_NFSV4;
3837a7741afSMartin Matuska #else
3847a7741afSMartin Matuska *value = ZFS_ACLTYPE_OFF;
3857a7741afSMartin Matuska #endif
3867a7741afSMartin Matuska break;
387*071ab5a1SMartin Matuska case ZFS_PROP_DEFAULTUSERQUOTA:
388*071ab5a1SMartin Matuska case ZFS_PROP_DEFAULTGROUPQUOTA:
389*071ab5a1SMartin Matuska case ZFS_PROP_DEFAULTPROJECTQUOTA:
390*071ab5a1SMartin Matuska case ZFS_PROP_DEFAULTUSEROBJQUOTA:
391*071ab5a1SMartin Matuska case ZFS_PROP_DEFAULTGROUPOBJQUOTA:
392*071ab5a1SMartin Matuska case ZFS_PROP_DEFAULTPROJECTOBJQUOTA:
393*071ab5a1SMartin Matuska *value = 0;
394*071ab5a1SMartin Matuska return (0);
3957a7741afSMartin Matuska default:
3967a7741afSMartin Matuska return (error);
3977a7741afSMartin Matuska }
3987a7741afSMartin Matuska error = 0;
3997a7741afSMartin Matuska }
4007a7741afSMartin Matuska
4017a7741afSMartin Matuska /*
4027a7741afSMartin Matuska * If one of the methods for getting the property value above worked,
4037a7741afSMartin Matuska * copy it into the objset_t's cache.
4047a7741afSMartin Matuska */
4057a7741afSMartin Matuska if (error == 0 && cached_copy != NULL) {
4067a7741afSMartin Matuska *cached_copy = *value;
4077a7741afSMartin Matuska }
4087a7741afSMartin Matuska
4097a7741afSMartin Matuska return (error);
4107a7741afSMartin Matuska }
411