xref: /freebsd/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c (revision 7a7741af18d6c8a804cc643cb7ecda9d730c6aa6)
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
9  * or https://opensource.org/licenses/CDDL-1.0.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
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 (C) 2011 Lawrence Livermore National Security, LLC.
23  * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
24  * LLNL-CODE-403049.
25  * Rewritten for Linux by:
26  *   Rohan Puri <rohan.puri15@gmail.com>
27  *   Brian Behlendorf <behlendorf1@llnl.gov>
28  */
29 
30 #include <sys/zfs_znode.h>
31 #include <sys/zfs_vfsops.h>
32 #include <sys/zfs_vnops.h>
33 #include <sys/zfs_ctldir.h>
34 #include <sys/zpl.h>
35 #include <sys/dmu.h>
36 #include <sys/dsl_dataset.h>
37 #include <sys/zap.h>
38 
39 /*
40  * Common open routine.  Disallow any write access.
41  */
42 static int
zpl_common_open(struct inode * ip,struct file * filp)43 zpl_common_open(struct inode *ip, struct file *filp)
44 {
45 	if (blk_mode_is_open_write(filp->f_mode))
46 		return (-EACCES);
47 
48 	return (generic_file_open(ip, filp));
49 }
50 
51 /*
52  * Get root directory contents.
53  */
54 static int
zpl_root_iterate(struct file * filp,struct dir_context * ctx)55 zpl_root_iterate(struct file *filp, struct dir_context *ctx)
56 {
57 	zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
58 	int error = 0;
59 
60 	if (zfsvfs->z_show_ctldir == ZFS_SNAPDIR_DISABLED) {
61 		return (SET_ERROR(ENOENT));
62 	}
63 
64 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
65 		return (error);
66 
67 	if (!dir_emit_dots(filp, ctx))
68 		goto out;
69 
70 	if (ctx->pos == 2) {
71 		if (!dir_emit(ctx, ZFS_SNAPDIR_NAME,
72 		    strlen(ZFS_SNAPDIR_NAME), ZFSCTL_INO_SNAPDIR, DT_DIR))
73 			goto out;
74 
75 		ctx->pos++;
76 	}
77 
78 	if (ctx->pos == 3) {
79 		if (!dir_emit(ctx, ZFS_SHAREDIR_NAME,
80 		    strlen(ZFS_SHAREDIR_NAME), ZFSCTL_INO_SHARES, DT_DIR))
81 			goto out;
82 
83 		ctx->pos++;
84 	}
85 out:
86 	zpl_exit(zfsvfs, FTAG);
87 
88 	return (error);
89 }
90 
91 /*
92  * Get root directory attributes.
93  */
94 static int
95 #ifdef HAVE_IDMAP_IOPS_GETATTR
zpl_root_getattr_impl(struct mnt_idmap * user_ns,const struct path * path,struct kstat * stat,u32 request_mask,unsigned int query_flags)96 zpl_root_getattr_impl(struct mnt_idmap *user_ns,
97     const struct path *path, struct kstat *stat, u32 request_mask,
98     unsigned int query_flags)
99 #elif defined(HAVE_USERNS_IOPS_GETATTR)
100 zpl_root_getattr_impl(struct user_namespace *user_ns,
101     const struct path *path, struct kstat *stat, u32 request_mask,
102     unsigned int query_flags)
103 #else
104 zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
105     u32 request_mask, unsigned int query_flags)
106 #endif
107 {
108 	(void) request_mask, (void) query_flags;
109 	struct inode *ip = path->dentry->d_inode;
110 
111 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
112 #ifdef HAVE_GENERIC_FILLATTR_USERNS
113 	generic_fillattr(user_ns, ip, stat);
114 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
115 	generic_fillattr(user_ns, ip, stat);
116 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
117 	generic_fillattr(user_ns, request_mask, ip, stat);
118 #else
119 	(void) user_ns;
120 #endif
121 #else
122 	generic_fillattr(ip, stat);
123 #endif
124 	stat->atime = current_time(ip);
125 
126 	return (0);
127 }
128 ZPL_GETATTR_WRAPPER(zpl_root_getattr);
129 
130 static struct dentry *
zpl_root_lookup(struct inode * dip,struct dentry * dentry,unsigned int flags)131 zpl_root_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
132 {
133 	cred_t *cr = CRED();
134 	struct inode *ip;
135 	int error;
136 
137 	crhold(cr);
138 	error = -zfsctl_root_lookup(dip, dname(dentry), &ip, 0, cr, NULL, NULL);
139 	ASSERT3S(error, <=, 0);
140 	crfree(cr);
141 
142 	if (error) {
143 		if (error == -ENOENT)
144 			return (d_splice_alias(NULL, dentry));
145 		else
146 			return (ERR_PTR(error));
147 	}
148 
149 	return (d_splice_alias(ip, dentry));
150 }
151 
152 /*
153  * The '.zfs' control directory file and inode operations.
154  */
155 const struct file_operations zpl_fops_root = {
156 	.open		= zpl_common_open,
157 	.llseek		= generic_file_llseek,
158 	.read		= generic_read_dir,
159 	.iterate_shared	= zpl_root_iterate,
160 };
161 
162 const struct inode_operations zpl_ops_root = {
163 	.lookup		= zpl_root_lookup,
164 	.getattr	= zpl_root_getattr,
165 };
166 
167 static struct vfsmount *
zpl_snapdir_automount(struct path * path)168 zpl_snapdir_automount(struct path *path)
169 {
170 	int error;
171 
172 	error = -zfsctl_snapshot_mount(path, 0);
173 	if (error)
174 		return (ERR_PTR(error));
175 
176 	/*
177 	 * Rather than returning the new vfsmount for the snapshot we must
178 	 * return NULL to indicate a mount collision.  This is done because
179 	 * the user space mount calls do_add_mount() which adds the vfsmount
180 	 * to the name space.  If we returned the new mount here it would be
181 	 * added again to the vfsmount list resulting in list corruption.
182 	 */
183 	return (NULL);
184 }
185 
186 /*
187  * Negative dentries must always be revalidated so newly created snapshots
188  * can be detected and automounted.  Normal dentries should be kept because
189  * as of the 3.18 kernel revaliding the mountpoint dentry will result in
190  * the snapshot being immediately unmounted.
191  */
192 static int
zpl_snapdir_revalidate(struct dentry * dentry,unsigned int flags)193 zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
194 {
195 	return (!!dentry->d_inode);
196 }
197 
198 static dentry_operations_t zpl_dops_snapdirs = {
199 /*
200  * Auto mounting of snapshots is only supported for 2.6.37 and
201  * newer kernels.  Prior to this kernel the ops->follow_link()
202  * callback was used as a hack to trigger the mount.  The
203  * resulting vfsmount was then explicitly grafted in to the
204  * name space.  While it might be possible to add compatibility
205  * code to accomplish this it would require considerable care.
206  */
207 	.d_automount	= zpl_snapdir_automount,
208 	.d_revalidate	= zpl_snapdir_revalidate,
209 };
210 
211 static struct dentry *
zpl_snapdir_lookup(struct inode * dip,struct dentry * dentry,unsigned int flags)212 zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
213     unsigned int flags)
214 {
215 	fstrans_cookie_t cookie;
216 	cred_t *cr = CRED();
217 	struct inode *ip = NULL;
218 	int error;
219 
220 	crhold(cr);
221 	cookie = spl_fstrans_mark();
222 	error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
223 	    0, cr, NULL, NULL);
224 	ASSERT3S(error, <=, 0);
225 	spl_fstrans_unmark(cookie);
226 	crfree(cr);
227 
228 	if (error && error != -ENOENT)
229 		return (ERR_PTR(error));
230 
231 	ASSERT(error == 0 || ip == NULL);
232 	d_clear_d_op(dentry);
233 	d_set_d_op(dentry, &zpl_dops_snapdirs);
234 	dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
235 
236 	return (d_splice_alias(ip, dentry));
237 }
238 
239 static int
zpl_snapdir_iterate(struct file * filp,struct dir_context * ctx)240 zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
241 {
242 	zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
243 	fstrans_cookie_t cookie;
244 	char snapname[MAXNAMELEN];
245 	boolean_t case_conflict;
246 	uint64_t id, pos;
247 	int error = 0;
248 
249 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
250 		return (error);
251 	cookie = spl_fstrans_mark();
252 
253 	if (!dir_emit_dots(filp, ctx))
254 		goto out;
255 
256 	/* Start the position at 0 if it already emitted . and .. */
257 	pos = (ctx->pos == 2 ? 0 : ctx->pos);
258 	while (error == 0) {
259 		dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
260 		error = -dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN,
261 		    snapname, &id, &pos, &case_conflict);
262 		dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
263 		if (error)
264 			goto out;
265 
266 		if (!dir_emit(ctx, snapname, strlen(snapname),
267 		    ZFSCTL_INO_SHARES - id, DT_DIR))
268 			goto out;
269 
270 		ctx->pos = pos;
271 	}
272 out:
273 	spl_fstrans_unmark(cookie);
274 	zpl_exit(zfsvfs, FTAG);
275 
276 	if (error == -ENOENT)
277 		return (0);
278 
279 	return (error);
280 }
281 
282 static int
283 #ifdef HAVE_IOPS_RENAME_USERNS
zpl_snapdir_rename2(struct user_namespace * user_ns,struct inode * sdip,struct dentry * sdentry,struct inode * tdip,struct dentry * tdentry,unsigned int flags)284 zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip,
285     struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
286     unsigned int flags)
287 #elif defined(HAVE_IOPS_RENAME_IDMAP)
288 zpl_snapdir_rename2(struct mnt_idmap *user_ns, struct inode *sdip,
289     struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
290     unsigned int flags)
291 #else
292 zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
293     struct inode *tdip, struct dentry *tdentry, unsigned int flags)
294 #endif
295 {
296 	cred_t *cr = CRED();
297 	int error;
298 
299 	/* We probably don't want to support renameat2(2) in ctldir */
300 	if (flags)
301 		return (-EINVAL);
302 
303 	crhold(cr);
304 	error = -zfsctl_snapdir_rename(sdip, dname(sdentry),
305 	    tdip, dname(tdentry), cr, 0);
306 	ASSERT3S(error, <=, 0);
307 	crfree(cr);
308 
309 	return (error);
310 }
311 
312 #if (!defined(HAVE_RENAME_WANTS_FLAGS) && \
313 	!defined(HAVE_IOPS_RENAME_USERNS) && \
314 	!defined(HAVE_IOPS_RENAME_IDMAP))
315 static int
zpl_snapdir_rename(struct inode * sdip,struct dentry * sdentry,struct inode * tdip,struct dentry * tdentry)316 zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
317     struct inode *tdip, struct dentry *tdentry)
318 {
319 	return (zpl_snapdir_rename2(sdip, sdentry, tdip, tdentry, 0));
320 }
321 #endif
322 
323 static int
zpl_snapdir_rmdir(struct inode * dip,struct dentry * dentry)324 zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
325 {
326 	cred_t *cr = CRED();
327 	int error;
328 
329 	crhold(cr);
330 	error = -zfsctl_snapdir_remove(dip, dname(dentry), cr, 0);
331 	ASSERT3S(error, <=, 0);
332 	crfree(cr);
333 
334 	return (error);
335 }
336 
337 static int
338 #ifdef HAVE_IOPS_MKDIR_USERNS
zpl_snapdir_mkdir(struct user_namespace * user_ns,struct inode * dip,struct dentry * dentry,umode_t mode)339 zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
340     struct dentry *dentry, umode_t mode)
341 #elif defined(HAVE_IOPS_MKDIR_IDMAP)
342 zpl_snapdir_mkdir(struct mnt_idmap *user_ns, struct inode *dip,
343     struct dentry *dentry, umode_t mode)
344 #else
345 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
346 #endif
347 {
348 	cred_t *cr = CRED();
349 	vattr_t *vap;
350 	struct inode *ip;
351 	int error;
352 
353 	crhold(cr);
354 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
355 #if (defined(HAVE_IOPS_MKDIR_USERNS) || defined(HAVE_IOPS_MKDIR_IDMAP))
356 	zpl_vap_init(vap, dip, mode | S_IFDIR, cr, user_ns);
357 #else
358 	zpl_vap_init(vap, dip, mode | S_IFDIR, cr, zfs_init_idmap);
359 #endif
360 
361 	error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
362 	if (error == 0) {
363 		d_clear_d_op(dentry);
364 		d_set_d_op(dentry, &zpl_dops_snapdirs);
365 		d_instantiate(dentry, ip);
366 	}
367 
368 	kmem_free(vap, sizeof (vattr_t));
369 	ASSERT3S(error, <=, 0);
370 	crfree(cr);
371 
372 	return (error);
373 }
374 
375 /*
376  * Get snapshot directory attributes.
377  */
378 static int
379 #ifdef HAVE_IDMAP_IOPS_GETATTR
zpl_snapdir_getattr_impl(struct mnt_idmap * user_ns,const struct path * path,struct kstat * stat,u32 request_mask,unsigned int query_flags)380 zpl_snapdir_getattr_impl(struct mnt_idmap *user_ns,
381     const struct path *path, struct kstat *stat, u32 request_mask,
382     unsigned int query_flags)
383 #elif defined(HAVE_USERNS_IOPS_GETATTR)
384 zpl_snapdir_getattr_impl(struct user_namespace *user_ns,
385     const struct path *path, struct kstat *stat, u32 request_mask,
386     unsigned int query_flags)
387 #else
388 zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
389     u32 request_mask, unsigned int query_flags)
390 #endif
391 {
392 	(void) request_mask, (void) query_flags;
393 	struct inode *ip = path->dentry->d_inode;
394 	zfsvfs_t *zfsvfs = ITOZSB(ip);
395 	int error;
396 
397 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
398 		return (error);
399 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
400 #ifdef HAVE_GENERIC_FILLATTR_USERNS
401 	generic_fillattr(user_ns, ip, stat);
402 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
403 	generic_fillattr(user_ns, ip, stat);
404 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
405 	generic_fillattr(user_ns, request_mask, ip, stat);
406 #else
407 	(void) user_ns;
408 #endif
409 #else
410 	generic_fillattr(ip, stat);
411 #endif
412 
413 	stat->nlink = stat->size = 2;
414 
415 	dsl_dataset_t *ds = dmu_objset_ds(zfsvfs->z_os);
416 	if (dsl_dataset_phys(ds)->ds_snapnames_zapobj != 0) {
417 		uint64_t snap_count;
418 		int err = zap_count(
419 		    dmu_objset_pool(ds->ds_objset)->dp_meta_objset,
420 		    dsl_dataset_phys(ds)->ds_snapnames_zapobj, &snap_count);
421 		if (err != 0) {
422 			zpl_exit(zfsvfs, FTAG);
423 			return (-err);
424 		}
425 		stat->nlink += snap_count;
426 	}
427 
428 	stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
429 	stat->atime = current_time(ip);
430 	zpl_exit(zfsvfs, FTAG);
431 
432 	return (0);
433 }
434 ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr);
435 
436 /*
437  * The '.zfs/snapshot' directory file operations.  These mainly control
438  * generating the list of available snapshots when doing an 'ls' in the
439  * directory.  See zpl_snapdir_readdir().
440  */
441 const struct file_operations zpl_fops_snapdir = {
442 	.open		= zpl_common_open,
443 	.llseek		= generic_file_llseek,
444 	.read		= generic_read_dir,
445 	.iterate_shared	= zpl_snapdir_iterate,
446 
447 };
448 
449 /*
450  * The '.zfs/snapshot' directory inode operations.  These mainly control
451  * creating an inode for a snapshot directory and initializing the needed
452  * infrastructure to automount the snapshot.  See zpl_snapdir_lookup().
453  */
454 const struct inode_operations zpl_ops_snapdir = {
455 	.lookup		= zpl_snapdir_lookup,
456 	.getattr	= zpl_snapdir_getattr,
457 #if (defined(HAVE_RENAME_WANTS_FLAGS) || \
458 	defined(HAVE_IOPS_RENAME_USERNS) || \
459 	defined(HAVE_IOPS_RENAME_IDMAP))
460 	.rename		= zpl_snapdir_rename2,
461 #else
462 	.rename		= zpl_snapdir_rename,
463 #endif
464 	.rmdir		= zpl_snapdir_rmdir,
465 	.mkdir		= zpl_snapdir_mkdir,
466 };
467 
468 static struct dentry *
zpl_shares_lookup(struct inode * dip,struct dentry * dentry,unsigned int flags)469 zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
470     unsigned int flags)
471 {
472 	fstrans_cookie_t cookie;
473 	cred_t *cr = CRED();
474 	struct inode *ip = NULL;
475 	int error;
476 
477 	crhold(cr);
478 	cookie = spl_fstrans_mark();
479 	error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
480 	    0, cr, NULL, NULL);
481 	ASSERT3S(error, <=, 0);
482 	spl_fstrans_unmark(cookie);
483 	crfree(cr);
484 
485 	if (error) {
486 		if (error == -ENOENT)
487 			return (d_splice_alias(NULL, dentry));
488 		else
489 			return (ERR_PTR(error));
490 	}
491 
492 	return (d_splice_alias(ip, dentry));
493 }
494 
495 static int
zpl_shares_iterate(struct file * filp,struct dir_context * ctx)496 zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
497 {
498 	fstrans_cookie_t cookie;
499 	cred_t *cr = CRED();
500 	zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
501 	znode_t *dzp;
502 	int error = 0;
503 
504 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
505 		return (error);
506 	cookie = spl_fstrans_mark();
507 
508 	if (zfsvfs->z_shares_dir == 0) {
509 		dir_emit_dots(filp, ctx);
510 		goto out;
511 	}
512 
513 	error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
514 	if (error)
515 		goto out;
516 
517 	crhold(cr);
518 	error = -zfs_readdir(ZTOI(dzp), ctx, cr);
519 	crfree(cr);
520 
521 	iput(ZTOI(dzp));
522 out:
523 	spl_fstrans_unmark(cookie);
524 	zpl_exit(zfsvfs, FTAG);
525 	ASSERT3S(error, <=, 0);
526 
527 	return (error);
528 }
529 
530 static int
531 #ifdef HAVE_USERNS_IOPS_GETATTR
zpl_shares_getattr_impl(struct user_namespace * user_ns,const struct path * path,struct kstat * stat,u32 request_mask,unsigned int query_flags)532 zpl_shares_getattr_impl(struct user_namespace *user_ns,
533     const struct path *path, struct kstat *stat, u32 request_mask,
534     unsigned int query_flags)
535 #elif defined(HAVE_IDMAP_IOPS_GETATTR)
536 zpl_shares_getattr_impl(struct mnt_idmap *user_ns,
537     const struct path *path, struct kstat *stat, u32 request_mask,
538     unsigned int query_flags)
539 #else
540 zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
541     u32 request_mask, unsigned int query_flags)
542 #endif
543 {
544 	(void) request_mask, (void) query_flags;
545 	struct inode *ip = path->dentry->d_inode;
546 	zfsvfs_t *zfsvfs = ITOZSB(ip);
547 	znode_t *dzp;
548 	int error;
549 
550 	if ((error = zpl_enter(zfsvfs, FTAG)) != 0)
551 		return (error);
552 
553 	if (zfsvfs->z_shares_dir == 0) {
554 #if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
555 #ifdef HAVE_GENERIC_FILLATTR_USERNS
556 		generic_fillattr(user_ns, path->dentry->d_inode, stat);
557 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
558 		generic_fillattr(user_ns, path->dentry->d_inode, stat);
559 #elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK)
560 	generic_fillattr(user_ns, request_mask, ip, stat);
561 #else
562 		(void) user_ns;
563 #endif
564 #else
565 		generic_fillattr(path->dentry->d_inode, stat);
566 #endif
567 		stat->nlink = stat->size = 2;
568 		stat->atime = current_time(ip);
569 		zpl_exit(zfsvfs, FTAG);
570 		return (0);
571 	}
572 
573 	error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
574 	if (error == 0) {
575 #ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK
576 		error = -zfs_getattr_fast(user_ns, request_mask, ZTOI(dzp),
577 		    stat);
578 #elif (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
579 		error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat);
580 #else
581 		error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
582 #endif
583 		iput(ZTOI(dzp));
584 	}
585 
586 	zpl_exit(zfsvfs, FTAG);
587 	ASSERT3S(error, <=, 0);
588 
589 	return (error);
590 }
591 ZPL_GETATTR_WRAPPER(zpl_shares_getattr);
592 
593 /*
594  * The '.zfs/shares' directory file operations.
595  */
596 const struct file_operations zpl_fops_shares = {
597 	.open		= zpl_common_open,
598 	.llseek		= generic_file_llseek,
599 	.read		= generic_read_dir,
600 	.iterate_shared	= zpl_shares_iterate,
601 };
602 
603 /*
604  * The '.zfs/shares' directory inode operations.
605  */
606 const struct inode_operations zpl_ops_shares = {
607 	.lookup		= zpl_shares_lookup,
608 	.getattr	= zpl_shares_getattr,
609 };
610