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