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