]> git.proxmox.com Git - mirror_zfs.git/blob - module/os/linux/zfs/zpl_ctldir.c
module/*.ko: prune .data, global .rodata
[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 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
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
36 /*
37 * Common open routine. Disallow any write access.
38 */
39 /* ARGSUSED */
40 static int
41 zpl_common_open(struct inode *ip, struct file *filp)
42 {
43 if (filp->f_mode & FMODE_WRITE)
44 return (-EACCES);
45
46 return (generic_file_open(ip, filp));
47 }
48
49 /*
50 * Get root directory contents.
51 */
52 static int
53 zpl_root_iterate(struct file *filp, zpl_dir_context_t *ctx)
54 {
55 zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
56 int error = 0;
57
58 ZPL_ENTER(zfsvfs);
59
60 if (!zpl_dir_emit_dots(filp, ctx))
61 goto out;
62
63 if (ctx->pos == 2) {
64 if (!zpl_dir_emit(ctx, ZFS_SNAPDIR_NAME,
65 strlen(ZFS_SNAPDIR_NAME), ZFSCTL_INO_SNAPDIR, DT_DIR))
66 goto out;
67
68 ctx->pos++;
69 }
70
71 if (ctx->pos == 3) {
72 if (!zpl_dir_emit(ctx, ZFS_SHAREDIR_NAME,
73 strlen(ZFS_SHAREDIR_NAME), ZFSCTL_INO_SHARES, DT_DIR))
74 goto out;
75
76 ctx->pos++;
77 }
78 out:
79 ZPL_EXIT(zfsvfs);
80
81 return (error);
82 }
83
84 #if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
85 static int
86 zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
87 {
88 zpl_dir_context_t ctx =
89 ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
90 int error;
91
92 error = zpl_root_iterate(filp, &ctx);
93 filp->f_pos = ctx.pos;
94
95 return (error);
96 }
97 #endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
98
99 /*
100 * Get root directory attributes.
101 */
102 /* ARGSUSED */
103 static int
104 #ifdef HAVE_USERNS_IOPS_GETATTR
105 zpl_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
109 zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
110 u32 request_mask, unsigned int query_flags)
111 #endif
112 {
113 struct inode *ip = path->dentry->d_inode;
114
115 #if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
116 generic_fillattr(user_ns, ip, stat);
117 #else
118 generic_fillattr(ip, stat);
119 #endif
120 stat->atime = current_time(ip);
121
122 return (0);
123 }
124 ZPL_GETATTR_WRAPPER(zpl_root_getattr);
125
126 static struct dentry *
127 zpl_root_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
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)
140 return (d_splice_alias(NULL, dentry));
141 else
142 return (ERR_PTR(error));
143 }
144
145 return (d_splice_alias(ip, dentry));
146 }
147
148 /*
149 * The '.zfs' control directory file and inode operations.
150 */
151 const struct file_operations zpl_fops_root = {
152 .open = zpl_common_open,
153 .llseek = generic_file_llseek,
154 .read = generic_read_dir,
155 #ifdef HAVE_VFS_ITERATE_SHARED
156 .iterate_shared = zpl_root_iterate,
157 #elif defined(HAVE_VFS_ITERATE)
158 .iterate = zpl_root_iterate,
159 #else
160 .readdir = zpl_root_readdir,
161 #endif
162 };
163
164 const struct inode_operations zpl_ops_root = {
165 .lookup = zpl_root_lookup,
166 .getattr = zpl_root_getattr,
167 };
168
169 static struct vfsmount *
170 zpl_snapdir_automount(struct path *path)
171 {
172 int error;
173
174 error = -zfsctl_snapshot_mount(path, 0);
175 if (error)
176 return (ERR_PTR(error));
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 }
187
188 /*
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.
193 */
194 static int
195 #ifdef HAVE_D_REVALIDATE_NAMEIDATA
196 zpl_snapdir_revalidate(struct dentry *dentry, struct nameidata *i)
197 #else
198 zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
199 #endif
200 {
201 return (!!dentry->d_inode);
202 }
203
204 static const dentry_operations_t zpl_dops_snapdirs = {
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 */
213 .d_automount = zpl_snapdir_automount,
214 .d_revalidate = zpl_snapdir_revalidate,
215 };
216
217 static struct dentry *
218 zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
219 unsigned int flags)
220 {
221 fstrans_cookie_t cookie;
222 cred_t *cr = CRED();
223 struct inode *ip = NULL;
224 int error;
225
226 crhold(cr);
227 cookie = spl_fstrans_mark();
228 error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
229 0, cr, NULL, NULL);
230 ASSERT3S(error, <=, 0);
231 spl_fstrans_unmark(cookie);
232 crfree(cr);
233
234 if (error && error != -ENOENT)
235 return (ERR_PTR(error));
236
237 ASSERT(error == 0 || ip == NULL);
238 d_clear_d_op(dentry);
239 d_set_d_op(dentry, &zpl_dops_snapdirs);
240 dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
241
242 return (d_splice_alias(ip, dentry));
243 }
244
245 static int
246 zpl_snapdir_iterate(struct file *filp, zpl_dir_context_t *ctx)
247 {
248 zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
249 fstrans_cookie_t cookie;
250 char snapname[MAXNAMELEN];
251 boolean_t case_conflict;
252 uint64_t id, pos;
253 int error = 0;
254
255 ZPL_ENTER(zfsvfs);
256 cookie = spl_fstrans_mark();
257
258 if (!zpl_dir_emit_dots(filp, ctx))
259 goto out;
260
261 /* Start the position at 0 if it already emitted . and .. */
262 pos = (ctx->pos == 2 ? 0 : ctx->pos);
263 while (error == 0) {
264 dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
265 error = -dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN,
266 snapname, &id, &pos, &case_conflict);
267 dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
268 if (error)
269 goto out;
270
271 if (!zpl_dir_emit(ctx, snapname, strlen(snapname),
272 ZFSCTL_INO_SHARES - id, DT_DIR))
273 goto out;
274
275 ctx->pos = pos;
276 }
277 out:
278 spl_fstrans_unmark(cookie);
279 ZPL_EXIT(zfsvfs);
280
281 if (error == -ENOENT)
282 return (0);
283
284 return (error);
285 }
286
287 #if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
288 static int
289 zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
290 {
291 zpl_dir_context_t ctx =
292 ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
293 int error;
294
295 error = zpl_snapdir_iterate(filp, &ctx);
296 filp->f_pos = ctx.pos;
297
298 return (error);
299 }
300 #endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
301
302 static int
303 #ifdef HAVE_IOPS_RENAME_USERNS
304 zpl_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
308 zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
309 struct inode *tdip, struct dentry *tdentry, unsigned int flags)
310 #endif
311 {
312 cred_t *cr = CRED();
313 int error;
314
315 /* We probably don't want to support renameat2(2) in ctldir */
316 if (flags)
317 return (-EINVAL);
318
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
328 #if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
329 static int
330 zpl_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
337 static int
338 zpl_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
351 static int
352 #ifdef HAVE_IOPS_MKDIR_USERNS
353 zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
354 struct dentry *dentry, umode_t mode)
355 #else
356 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
357 #endif
358 {
359 cred_t *cr = CRED();
360 vattr_t *vap;
361 struct inode *ip;
362 int error;
363
364 crhold(cr);
365 vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
366 zpl_vap_init(vap, dip, mode | S_IFDIR, cr);
367
368 error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
369 if (error == 0) {
370 d_clear_d_op(dentry);
371 d_set_d_op(dentry, &zpl_dops_snapdirs);
372 d_instantiate(dentry, ip);
373 }
374
375 kmem_free(vap, sizeof (vattr_t));
376 ASSERT3S(error, <=, 0);
377 crfree(cr);
378
379 return (error);
380 }
381
382 /*
383 * Get snapshot directory attributes.
384 */
385 /* ARGSUSED */
386 static int
387 #ifdef HAVE_USERNS_IOPS_GETATTR
388 zpl_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
392 zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
393 u32 request_mask, unsigned int query_flags)
394 #endif
395 {
396 struct inode *ip = path->dentry->d_inode;
397 zfsvfs_t *zfsvfs = ITOZSB(ip);
398
399 ZPL_ENTER(zfsvfs);
400 #if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
401 generic_fillattr(user_ns, ip, stat);
402 #else
403 generic_fillattr(ip, stat);
404 #endif
405
406 stat->nlink = stat->size = 2;
407 stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
408 stat->atime = current_time(ip);
409 ZPL_EXIT(zfsvfs);
410
411 return (0);
412 }
413 ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr);
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 */
420 const struct file_operations zpl_fops_snapdir = {
421 .open = zpl_common_open,
422 .llseek = generic_file_llseek,
423 .read = generic_read_dir,
424 #ifdef HAVE_VFS_ITERATE_SHARED
425 .iterate_shared = zpl_snapdir_iterate,
426 #elif defined(HAVE_VFS_ITERATE)
427 .iterate = zpl_snapdir_iterate,
428 #else
429 .readdir = zpl_snapdir_readdir,
430 #endif
431
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 */
439 const struct inode_operations zpl_ops_snapdir = {
440 .lookup = zpl_snapdir_lookup,
441 .getattr = zpl_snapdir_getattr,
442 #if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
443 .rename = zpl_snapdir_rename2,
444 #else
445 .rename = zpl_snapdir_rename,
446 #endif
447 .rmdir = zpl_snapdir_rmdir,
448 .mkdir = zpl_snapdir_mkdir,
449 };
450
451 static struct dentry *
452 zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
453 unsigned int flags)
454 {
455 fstrans_cookie_t cookie;
456 cred_t *cr = CRED();
457 struct inode *ip = NULL;
458 int error;
459
460 crhold(cr);
461 cookie = spl_fstrans_mark();
462 error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
463 0, cr, NULL, NULL);
464 ASSERT3S(error, <=, 0);
465 spl_fstrans_unmark(cookie);
466 crfree(cr);
467
468 if (error) {
469 if (error == -ENOENT)
470 return (d_splice_alias(NULL, dentry));
471 else
472 return (ERR_PTR(error));
473 }
474
475 return (d_splice_alias(ip, dentry));
476 }
477
478 static int
479 zpl_shares_iterate(struct file *filp, zpl_dir_context_t *ctx)
480 {
481 fstrans_cookie_t cookie;
482 cred_t *cr = CRED();
483 zfsvfs_t *zfsvfs = ITOZSB(file_inode(filp));
484 znode_t *dzp;
485 int error = 0;
486
487 ZPL_ENTER(zfsvfs);
488 cookie = spl_fstrans_mark();
489
490 if (zfsvfs->z_shares_dir == 0) {
491 zpl_dir_emit_dots(filp, ctx);
492 goto out;
493 }
494
495 error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
496 if (error)
497 goto out;
498
499 crhold(cr);
500 error = -zfs_readdir(ZTOI(dzp), ctx, cr);
501 crfree(cr);
502
503 iput(ZTOI(dzp));
504 out:
505 spl_fstrans_unmark(cookie);
506 ZPL_EXIT(zfsvfs);
507 ASSERT3S(error, <=, 0);
508
509 return (error);
510 }
511
512 #if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
513 static int
514 zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
515 {
516 zpl_dir_context_t ctx =
517 ZPL_DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
518 int error;
519
520 error = zpl_shares_iterate(filp, &ctx);
521 filp->f_pos = ctx.pos;
522
523 return (error);
524 }
525 #endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
526
527 /* ARGSUSED */
528 static int
529 #ifdef HAVE_USERNS_IOPS_GETATTR
530 zpl_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
534 zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
535 u32 request_mask, unsigned int query_flags)
536 #endif
537 {
538 struct inode *ip = path->dentry->d_inode;
539 zfsvfs_t *zfsvfs = ITOZSB(ip);
540 znode_t *dzp;
541 int error;
542
543 ZPL_ENTER(zfsvfs);
544
545 if (zfsvfs->z_shares_dir == 0) {
546 #if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
547 generic_fillattr(user_ns, path->dentry->d_inode, stat);
548 #else
549 generic_fillattr(path->dentry->d_inode, stat);
550 #endif
551 stat->nlink = stat->size = 2;
552 stat->atime = current_time(ip);
553 ZPL_EXIT(zfsvfs);
554 return (0);
555 }
556
557 error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
558 if (error == 0) {
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
564 iput(ZTOI(dzp));
565 }
566
567 ZPL_EXIT(zfsvfs);
568 ASSERT3S(error, <=, 0);
569
570 return (error);
571 }
572 ZPL_GETATTR_WRAPPER(zpl_shares_getattr);
573
574 /*
575 * The '.zfs/shares' directory file operations.
576 */
577 const struct file_operations zpl_fops_shares = {
578 .open = zpl_common_open,
579 .llseek = generic_file_llseek,
580 .read = generic_read_dir,
581 #ifdef HAVE_VFS_ITERATE_SHARED
582 .iterate_shared = zpl_shares_iterate,
583 #elif defined(HAVE_VFS_ITERATE)
584 .iterate = zpl_shares_iterate,
585 #else
586 .readdir = zpl_shares_readdir,
587 #endif
588
589 };
590
591 /*
592 * The '.zfs/shares' directory inode operations.
593 */
594 const struct inode_operations zpl_ops_shares = {
595 .lookup = zpl_shares_lookup,
596 .getattr = zpl_shares_getattr,
597 };