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