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