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