1*7a7741afSMartin Matuska /* 2*7a7741afSMartin Matuska * CDDL HEADER START 3*7a7741afSMartin Matuska * 4*7a7741afSMartin Matuska * The contents of this file are subject to the terms of the 5*7a7741afSMartin Matuska * Common Development and Distribution License (the "License"). 6*7a7741afSMartin Matuska * You may not use this file except in compliance with the License. 7*7a7741afSMartin Matuska * 8*7a7741afSMartin Matuska * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7a7741afSMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 10*7a7741afSMartin Matuska * See the License for the specific language governing permissions 11*7a7741afSMartin Matuska * and limitations under the License. 12*7a7741afSMartin Matuska * 13*7a7741afSMartin Matuska * When distributing Covered Code, include this CDDL HEADER in each 14*7a7741afSMartin Matuska * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7a7741afSMartin Matuska * If applicable, add the following below this CDDL HEADER, with the 16*7a7741afSMartin Matuska * fields enclosed by brackets "[]" replaced with your own identifying 17*7a7741afSMartin Matuska * information: Portions Copyright [yyyy] [name of copyright owner] 18*7a7741afSMartin Matuska * 19*7a7741afSMartin Matuska * CDDL HEADER END 20*7a7741afSMartin Matuska */ 21*7a7741afSMartin Matuska /* 22*7a7741afSMartin Matuska * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23*7a7741afSMartin Matuska * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 24*7a7741afSMartin Matuska * Copyright (c) 2014 Integros [integros.com] 25*7a7741afSMartin Matuska */ 26*7a7741afSMartin Matuska 27*7a7741afSMartin Matuska /* Portions Copyright 2007 Jeremy Teo */ 28*7a7741afSMartin Matuska /* Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org> */ 29*7a7741afSMartin Matuska 30*7a7741afSMartin Matuska #include <sys/dmu.h> 31*7a7741afSMartin Matuska #include <sys/dmu_objset.h> 32*7a7741afSMartin Matuska #include <sys/dmu_tx.h> 33*7a7741afSMartin Matuska #include <sys/zfs_refcount.h> 34*7a7741afSMartin Matuska #include <sys/stat.h> 35*7a7741afSMartin Matuska #include <sys/zap.h> 36*7a7741afSMartin Matuska #include <sys/zfs_znode.h> 37*7a7741afSMartin Matuska #include <sys/sa.h> 38*7a7741afSMartin Matuska #include <sys/zfs_sa.h> 39*7a7741afSMartin Matuska #include <sys/zfs_stat.h> 40*7a7741afSMartin Matuska 41*7a7741afSMartin Matuska #include "zfs_prop.h" 42*7a7741afSMartin Matuska #include "zfs_comutil.h" 43*7a7741afSMartin Matuska 44*7a7741afSMartin Matuska static int 45*7a7741afSMartin Matuska zfs_sa_setup(objset_t *osp, sa_attr_type_t **sa_table) 46*7a7741afSMartin Matuska { 47*7a7741afSMartin Matuska uint64_t sa_obj = 0; 48*7a7741afSMartin Matuska int error; 49*7a7741afSMartin Matuska 50*7a7741afSMartin Matuska error = zap_lookup(osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj); 51*7a7741afSMartin Matuska if (error != 0 && error != ENOENT) 52*7a7741afSMartin Matuska return (error); 53*7a7741afSMartin Matuska 54*7a7741afSMartin Matuska error = sa_setup(osp, sa_obj, zfs_attr_table, ZPL_END, sa_table); 55*7a7741afSMartin Matuska return (error); 56*7a7741afSMartin Matuska } 57*7a7741afSMartin Matuska 58*7a7741afSMartin Matuska static int 59*7a7741afSMartin Matuska zfs_grab_sa_handle(objset_t *osp, uint64_t obj, sa_handle_t **hdlp, 60*7a7741afSMartin Matuska dmu_buf_t **db, const void *tag) 61*7a7741afSMartin Matuska { 62*7a7741afSMartin Matuska dmu_object_info_t doi; 63*7a7741afSMartin Matuska int error; 64*7a7741afSMartin Matuska 65*7a7741afSMartin Matuska if ((error = sa_buf_hold(osp, obj, tag, db)) != 0) 66*7a7741afSMartin Matuska return (error); 67*7a7741afSMartin Matuska 68*7a7741afSMartin Matuska dmu_object_info_from_db(*db, &doi); 69*7a7741afSMartin Matuska if ((doi.doi_bonus_type != DMU_OT_SA && 70*7a7741afSMartin Matuska doi.doi_bonus_type != DMU_OT_ZNODE) || 71*7a7741afSMartin Matuska (doi.doi_bonus_type == DMU_OT_ZNODE && 72*7a7741afSMartin Matuska doi.doi_bonus_size < sizeof (znode_phys_t))) { 73*7a7741afSMartin Matuska sa_buf_rele(*db, tag); 74*7a7741afSMartin Matuska return (SET_ERROR(ENOTSUP)); 75*7a7741afSMartin Matuska } 76*7a7741afSMartin Matuska 77*7a7741afSMartin Matuska error = sa_handle_get(osp, obj, NULL, SA_HDL_PRIVATE, hdlp); 78*7a7741afSMartin Matuska if (error != 0) { 79*7a7741afSMartin Matuska sa_buf_rele(*db, tag); 80*7a7741afSMartin Matuska return (error); 81*7a7741afSMartin Matuska } 82*7a7741afSMartin Matuska 83*7a7741afSMartin Matuska return (0); 84*7a7741afSMartin Matuska } 85*7a7741afSMartin Matuska 86*7a7741afSMartin Matuska static void 87*7a7741afSMartin Matuska zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, const void *tag) 88*7a7741afSMartin Matuska { 89*7a7741afSMartin Matuska sa_handle_destroy(hdl); 90*7a7741afSMartin Matuska sa_buf_rele(db, tag); 91*7a7741afSMartin Matuska } 92*7a7741afSMartin Matuska 93*7a7741afSMartin Matuska /* 94*7a7741afSMartin Matuska * Given an object number, return its parent object number and whether 95*7a7741afSMartin Matuska * or not the object is an extended attribute directory. 96*7a7741afSMartin Matuska */ 97*7a7741afSMartin Matuska int 98*7a7741afSMartin Matuska zfs_obj_to_pobj(objset_t *osp, sa_handle_t *hdl, sa_attr_type_t *sa_table, 99*7a7741afSMartin Matuska uint64_t *pobjp, int *is_xattrdir) 100*7a7741afSMartin Matuska { 101*7a7741afSMartin Matuska uint64_t parent; 102*7a7741afSMartin Matuska uint64_t pflags; 103*7a7741afSMartin Matuska uint64_t mode; 104*7a7741afSMartin Matuska uint64_t parent_mode; 105*7a7741afSMartin Matuska sa_bulk_attr_t bulk[3]; 106*7a7741afSMartin Matuska sa_handle_t *sa_hdl; 107*7a7741afSMartin Matuska dmu_buf_t *sa_db; 108*7a7741afSMartin Matuska int count = 0; 109*7a7741afSMartin Matuska int error; 110*7a7741afSMartin Matuska 111*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_PARENT], NULL, 112*7a7741afSMartin Matuska &parent, sizeof (parent)); 113*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_FLAGS], NULL, 114*7a7741afSMartin Matuska &pflags, sizeof (pflags)); 115*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL, 116*7a7741afSMartin Matuska &mode, sizeof (mode)); 117*7a7741afSMartin Matuska 118*7a7741afSMartin Matuska if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0) 119*7a7741afSMartin Matuska return (error); 120*7a7741afSMartin Matuska 121*7a7741afSMartin Matuska /* 122*7a7741afSMartin Matuska * When a link is removed its parent pointer is not changed and will 123*7a7741afSMartin Matuska * be invalid. There are two cases where a link is removed but the 124*7a7741afSMartin Matuska * file stays around, when it goes to the delete queue and when there 125*7a7741afSMartin Matuska * are additional links. 126*7a7741afSMartin Matuska */ 127*7a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, parent, &sa_hdl, &sa_db, FTAG); 128*7a7741afSMartin Matuska if (error != 0) 129*7a7741afSMartin Matuska return (error); 130*7a7741afSMartin Matuska 131*7a7741afSMartin Matuska error = sa_lookup(sa_hdl, ZPL_MODE, &parent_mode, sizeof (parent_mode)); 132*7a7741afSMartin Matuska zfs_release_sa_handle(sa_hdl, sa_db, FTAG); 133*7a7741afSMartin Matuska if (error != 0) 134*7a7741afSMartin Matuska return (error); 135*7a7741afSMartin Matuska 136*7a7741afSMartin Matuska *is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode); 137*7a7741afSMartin Matuska 138*7a7741afSMartin Matuska /* 139*7a7741afSMartin Matuska * Extended attributes can be applied to files, directories, etc. 140*7a7741afSMartin Matuska * Otherwise the parent must be a directory. 141*7a7741afSMartin Matuska */ 142*7a7741afSMartin Matuska if (!*is_xattrdir && !S_ISDIR(parent_mode)) 143*7a7741afSMartin Matuska return (SET_ERROR(EINVAL)); 144*7a7741afSMartin Matuska 145*7a7741afSMartin Matuska *pobjp = parent; 146*7a7741afSMartin Matuska 147*7a7741afSMartin Matuska return (0); 148*7a7741afSMartin Matuska } 149*7a7741afSMartin Matuska 150*7a7741afSMartin Matuska /* 151*7a7741afSMartin Matuska * Given an object number, return some zpl level statistics 152*7a7741afSMartin Matuska */ 153*7a7741afSMartin Matuska static int 154*7a7741afSMartin Matuska zfs_obj_to_stats_impl(sa_handle_t *hdl, sa_attr_type_t *sa_table, 155*7a7741afSMartin Matuska zfs_stat_t *sb) 156*7a7741afSMartin Matuska { 157*7a7741afSMartin Matuska sa_bulk_attr_t bulk[4]; 158*7a7741afSMartin Matuska int count = 0; 159*7a7741afSMartin Matuska 160*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL, 161*7a7741afSMartin Matuska &sb->zs_mode, sizeof (sb->zs_mode)); 162*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_GEN], NULL, 163*7a7741afSMartin Matuska &sb->zs_gen, sizeof (sb->zs_gen)); 164*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_LINKS], NULL, 165*7a7741afSMartin Matuska &sb->zs_links, sizeof (sb->zs_links)); 166*7a7741afSMartin Matuska SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_CTIME], NULL, 167*7a7741afSMartin Matuska &sb->zs_ctime, sizeof (sb->zs_ctime)); 168*7a7741afSMartin Matuska 169*7a7741afSMartin Matuska return (sa_bulk_lookup(hdl, bulk, count)); 170*7a7741afSMartin Matuska } 171*7a7741afSMartin Matuska 172*7a7741afSMartin Matuska static int 173*7a7741afSMartin Matuska zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, 174*7a7741afSMartin Matuska sa_attr_type_t *sa_table, char *buf, int len) 175*7a7741afSMartin Matuska { 176*7a7741afSMartin Matuska sa_handle_t *sa_hdl; 177*7a7741afSMartin Matuska sa_handle_t *prevhdl = NULL; 178*7a7741afSMartin Matuska dmu_buf_t *prevdb = NULL; 179*7a7741afSMartin Matuska dmu_buf_t *sa_db = NULL; 180*7a7741afSMartin Matuska char *path = buf + len - 1; 181*7a7741afSMartin Matuska char *comp_buf; 182*7a7741afSMartin Matuska int error; 183*7a7741afSMartin Matuska 184*7a7741afSMartin Matuska *path = '\0'; 185*7a7741afSMartin Matuska sa_hdl = hdl; 186*7a7741afSMartin Matuska 187*7a7741afSMartin Matuska uint64_t deleteq_obj; 188*7a7741afSMartin Matuska VERIFY0(zap_lookup(osp, MASTER_NODE_OBJ, 189*7a7741afSMartin Matuska ZFS_UNLINKED_SET, sizeof (uint64_t), 1, &deleteq_obj)); 190*7a7741afSMartin Matuska error = zap_lookup_int(osp, deleteq_obj, obj); 191*7a7741afSMartin Matuska if (error == 0) { 192*7a7741afSMartin Matuska return (ESTALE); 193*7a7741afSMartin Matuska } else if (error != ENOENT) { 194*7a7741afSMartin Matuska return (error); 195*7a7741afSMartin Matuska } 196*7a7741afSMartin Matuska 197*7a7741afSMartin Matuska comp_buf = kmem_alloc(ZAP_MAXNAMELEN_NEW + 2, KM_SLEEP); 198*7a7741afSMartin Matuska for (;;) { 199*7a7741afSMartin Matuska uint64_t pobj = 0; 200*7a7741afSMartin Matuska char *component = comp_buf; 201*7a7741afSMartin Matuska size_t complen; 202*7a7741afSMartin Matuska int is_xattrdir = 0; 203*7a7741afSMartin Matuska 204*7a7741afSMartin Matuska if (prevdb) { 205*7a7741afSMartin Matuska ASSERT3P(prevhdl, !=, NULL); 206*7a7741afSMartin Matuska zfs_release_sa_handle(prevhdl, prevdb, FTAG); 207*7a7741afSMartin Matuska } 208*7a7741afSMartin Matuska 209*7a7741afSMartin Matuska if ((error = zfs_obj_to_pobj(osp, sa_hdl, sa_table, &pobj, 210*7a7741afSMartin Matuska &is_xattrdir)) != 0) 211*7a7741afSMartin Matuska break; 212*7a7741afSMartin Matuska 213*7a7741afSMartin Matuska if (pobj == obj) { 214*7a7741afSMartin Matuska if (path[0] != '/') 215*7a7741afSMartin Matuska *--path = '/'; 216*7a7741afSMartin Matuska break; 217*7a7741afSMartin Matuska } 218*7a7741afSMartin Matuska 219*7a7741afSMartin Matuska component[0] = '/'; 220*7a7741afSMartin Matuska if (is_xattrdir) { 221*7a7741afSMartin Matuska strcpy(component + 1, "<xattrdir>"); 222*7a7741afSMartin Matuska } else { 223*7a7741afSMartin Matuska error = zap_value_search(osp, pobj, obj, 224*7a7741afSMartin Matuska ZFS_DIRENT_OBJ(-1ULL), component + 1, 225*7a7741afSMartin Matuska ZAP_MAXNAMELEN_NEW); 226*7a7741afSMartin Matuska if (error != 0) 227*7a7741afSMartin Matuska break; 228*7a7741afSMartin Matuska } 229*7a7741afSMartin Matuska 230*7a7741afSMartin Matuska complen = strlen(component); 231*7a7741afSMartin Matuska path -= complen; 232*7a7741afSMartin Matuska ASSERT3P(path, >=, buf); 233*7a7741afSMartin Matuska memcpy(path, component, complen); 234*7a7741afSMartin Matuska obj = pobj; 235*7a7741afSMartin Matuska 236*7a7741afSMartin Matuska if (sa_hdl != hdl) { 237*7a7741afSMartin Matuska prevhdl = sa_hdl; 238*7a7741afSMartin Matuska prevdb = sa_db; 239*7a7741afSMartin Matuska } 240*7a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, obj, &sa_hdl, &sa_db, FTAG); 241*7a7741afSMartin Matuska if (error != 0) { 242*7a7741afSMartin Matuska sa_hdl = prevhdl; 243*7a7741afSMartin Matuska sa_db = prevdb; 244*7a7741afSMartin Matuska break; 245*7a7741afSMartin Matuska } 246*7a7741afSMartin Matuska } 247*7a7741afSMartin Matuska 248*7a7741afSMartin Matuska if (sa_hdl != NULL && sa_hdl != hdl) { 249*7a7741afSMartin Matuska ASSERT3P(sa_db, !=, NULL); 250*7a7741afSMartin Matuska zfs_release_sa_handle(sa_hdl, sa_db, FTAG); 251*7a7741afSMartin Matuska } 252*7a7741afSMartin Matuska 253*7a7741afSMartin Matuska if (error == 0) 254*7a7741afSMartin Matuska (void) memmove(buf, path, buf + len - path); 255*7a7741afSMartin Matuska 256*7a7741afSMartin Matuska kmem_free(comp_buf, ZAP_MAXNAMELEN_NEW +2); 257*7a7741afSMartin Matuska return (error); 258*7a7741afSMartin Matuska } 259*7a7741afSMartin Matuska 260*7a7741afSMartin Matuska int 261*7a7741afSMartin Matuska zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len) 262*7a7741afSMartin Matuska { 263*7a7741afSMartin Matuska sa_attr_type_t *sa_table; 264*7a7741afSMartin Matuska sa_handle_t *hdl; 265*7a7741afSMartin Matuska dmu_buf_t *db; 266*7a7741afSMartin Matuska int error; 267*7a7741afSMartin Matuska 268*7a7741afSMartin Matuska error = zfs_sa_setup(osp, &sa_table); 269*7a7741afSMartin Matuska if (error != 0) 270*7a7741afSMartin Matuska return (error); 271*7a7741afSMartin Matuska 272*7a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG); 273*7a7741afSMartin Matuska if (error != 0) 274*7a7741afSMartin Matuska return (error); 275*7a7741afSMartin Matuska 276*7a7741afSMartin Matuska error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len); 277*7a7741afSMartin Matuska 278*7a7741afSMartin Matuska zfs_release_sa_handle(hdl, db, FTAG); 279*7a7741afSMartin Matuska return (error); 280*7a7741afSMartin Matuska } 281*7a7741afSMartin Matuska 282*7a7741afSMartin Matuska int 283*7a7741afSMartin Matuska zfs_obj_to_stats(objset_t *osp, uint64_t obj, zfs_stat_t *sb, 284*7a7741afSMartin Matuska char *buf, int len) 285*7a7741afSMartin Matuska { 286*7a7741afSMartin Matuska char *path = buf + len - 1; 287*7a7741afSMartin Matuska sa_attr_type_t *sa_table; 288*7a7741afSMartin Matuska sa_handle_t *hdl; 289*7a7741afSMartin Matuska dmu_buf_t *db; 290*7a7741afSMartin Matuska int error; 291*7a7741afSMartin Matuska 292*7a7741afSMartin Matuska *path = '\0'; 293*7a7741afSMartin Matuska 294*7a7741afSMartin Matuska error = zfs_sa_setup(osp, &sa_table); 295*7a7741afSMartin Matuska if (error != 0) 296*7a7741afSMartin Matuska return (error); 297*7a7741afSMartin Matuska 298*7a7741afSMartin Matuska error = zfs_grab_sa_handle(osp, obj, &hdl, &db, FTAG); 299*7a7741afSMartin Matuska if (error != 0) 300*7a7741afSMartin Matuska return (error); 301*7a7741afSMartin Matuska 302*7a7741afSMartin Matuska error = zfs_obj_to_stats_impl(hdl, sa_table, sb); 303*7a7741afSMartin Matuska if (error != 0) { 304*7a7741afSMartin Matuska zfs_release_sa_handle(hdl, db, FTAG); 305*7a7741afSMartin Matuska return (error); 306*7a7741afSMartin Matuska } 307*7a7741afSMartin Matuska 308*7a7741afSMartin Matuska error = zfs_obj_to_path_impl(osp, obj, hdl, sa_table, buf, len); 309*7a7741afSMartin Matuska 310*7a7741afSMartin Matuska zfs_release_sa_handle(hdl, db, FTAG); 311*7a7741afSMartin Matuska return (error); 312*7a7741afSMartin Matuska } 313*7a7741afSMartin Matuska 314*7a7741afSMartin Matuska /* 315*7a7741afSMartin Matuska * Read a property stored within the master node. 316*7a7741afSMartin Matuska */ 317*7a7741afSMartin Matuska int 318*7a7741afSMartin Matuska zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) 319*7a7741afSMartin Matuska { 320*7a7741afSMartin Matuska uint64_t *cached_copy = NULL; 321*7a7741afSMartin Matuska 322*7a7741afSMartin Matuska /* 323*7a7741afSMartin Matuska * Figure out where in the objset_t the cached copy would live, if it 324*7a7741afSMartin Matuska * is available for the requested property. 325*7a7741afSMartin Matuska */ 326*7a7741afSMartin Matuska if (os != NULL) { 327*7a7741afSMartin Matuska switch (prop) { 328*7a7741afSMartin Matuska case ZFS_PROP_VERSION: 329*7a7741afSMartin Matuska cached_copy = &os->os_version; 330*7a7741afSMartin Matuska break; 331*7a7741afSMartin Matuska case ZFS_PROP_NORMALIZE: 332*7a7741afSMartin Matuska cached_copy = &os->os_normalization; 333*7a7741afSMartin Matuska break; 334*7a7741afSMartin Matuska case ZFS_PROP_UTF8ONLY: 335*7a7741afSMartin Matuska cached_copy = &os->os_utf8only; 336*7a7741afSMartin Matuska break; 337*7a7741afSMartin Matuska case ZFS_PROP_CASE: 338*7a7741afSMartin Matuska cached_copy = &os->os_casesensitivity; 339*7a7741afSMartin Matuska break; 340*7a7741afSMartin Matuska default: 341*7a7741afSMartin Matuska break; 342*7a7741afSMartin Matuska } 343*7a7741afSMartin Matuska } 344*7a7741afSMartin Matuska if (cached_copy != NULL && *cached_copy != OBJSET_PROP_UNINITIALIZED) { 345*7a7741afSMartin Matuska *value = *cached_copy; 346*7a7741afSMartin Matuska return (0); 347*7a7741afSMartin Matuska } 348*7a7741afSMartin Matuska 349*7a7741afSMartin Matuska /* 350*7a7741afSMartin Matuska * If the property wasn't cached, look up the file system's value for 351*7a7741afSMartin Matuska * the property. For the version property, we look up a slightly 352*7a7741afSMartin Matuska * different string. 353*7a7741afSMartin Matuska */ 354*7a7741afSMartin Matuska const char *pname; 355*7a7741afSMartin Matuska int error = ENOENT; 356*7a7741afSMartin Matuska if (prop == ZFS_PROP_VERSION) 357*7a7741afSMartin Matuska pname = ZPL_VERSION_STR; 358*7a7741afSMartin Matuska else 359*7a7741afSMartin Matuska pname = zfs_prop_to_name(prop); 360*7a7741afSMartin Matuska 361*7a7741afSMartin Matuska if (os != NULL) { 362*7a7741afSMartin Matuska ASSERT3U(os->os_phys->os_type, ==, DMU_OST_ZFS); 363*7a7741afSMartin Matuska error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value); 364*7a7741afSMartin Matuska } 365*7a7741afSMartin Matuska 366*7a7741afSMartin Matuska if (error == ENOENT) { 367*7a7741afSMartin Matuska /* No value set, use the default value */ 368*7a7741afSMartin Matuska switch (prop) { 369*7a7741afSMartin Matuska case ZFS_PROP_VERSION: 370*7a7741afSMartin Matuska *value = ZPL_VERSION; 371*7a7741afSMartin Matuska break; 372*7a7741afSMartin Matuska case ZFS_PROP_NORMALIZE: 373*7a7741afSMartin Matuska case ZFS_PROP_UTF8ONLY: 374*7a7741afSMartin Matuska *value = 0; 375*7a7741afSMartin Matuska break; 376*7a7741afSMartin Matuska case ZFS_PROP_CASE: 377*7a7741afSMartin Matuska *value = ZFS_CASE_SENSITIVE; 378*7a7741afSMartin Matuska break; 379*7a7741afSMartin Matuska case ZFS_PROP_ACLTYPE: 380*7a7741afSMartin Matuska #ifdef __FreeBSD__ 381*7a7741afSMartin Matuska *value = ZFS_ACLTYPE_NFSV4; 382*7a7741afSMartin Matuska #else 383*7a7741afSMartin Matuska *value = ZFS_ACLTYPE_OFF; 384*7a7741afSMartin Matuska #endif 385*7a7741afSMartin Matuska break; 386*7a7741afSMartin Matuska default: 387*7a7741afSMartin Matuska return (error); 388*7a7741afSMartin Matuska } 389*7a7741afSMartin Matuska error = 0; 390*7a7741afSMartin Matuska } 391*7a7741afSMartin Matuska 392*7a7741afSMartin Matuska /* 393*7a7741afSMartin Matuska * If one of the methods for getting the property value above worked, 394*7a7741afSMartin Matuska * copy it into the objset_t's cache. 395*7a7741afSMartin Matuska */ 396*7a7741afSMartin Matuska if (error == 0 && cached_copy != NULL) { 397*7a7741afSMartin Matuska *cached_copy = *value; 398*7a7741afSMartin Matuska } 399*7a7741afSMartin Matuska 400*7a7741afSMartin Matuska return (error); 401*7a7741afSMartin Matuska } 402