]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - zfs/module/zfs/zpl_ctldir.c
UBUNTU: SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7
[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{
df9d7621
CIK
106 struct inode *ip = path->dentry->d_inode;
107
108 generic_fillattr(ip, stat);
109 stat->atime = current_time(ip);
87d546d8 110
3e990ae0 111 return (0);
87d546d8 112}
3e990ae0 113ZPL_GETATTR_WRAPPER(zpl_root_getattr);
87d546d8
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
3e990ae0
CIK
379zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
380 u32 request_mask, unsigned int query_flags)
87d546d8 381{
df9d7621
CIK
382 struct inode *ip = path->dentry->d_inode;
383 zfs_sb_t *zsb = ITOZSB(ip);
87d546d8
TG
384
385 ZFS_ENTER(zsb);
df9d7621 386 generic_fillattr(ip, stat);
3e990ae0 387
87d546d8
TG
388 stat->nlink = stat->size = 2;
389 stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zsb->z_os);
df9d7621 390 stat->atime = current_time(ip);
87d546d8
TG
391 ZFS_EXIT(zsb);
392
3e990ae0 393 return (0);
87d546d8 394}
3e990ae0 395ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr);
87d546d8
TG
396
397/*
398 * The '.zfs/snapshot' directory file operations. These mainly control
399 * generating the list of available snapshots when doing an 'ls' in the
400 * directory. See zpl_snapdir_readdir().
401 */
402const struct file_operations zpl_fops_snapdir = {
403 .open = zpl_common_open,
404 .llseek = generic_file_llseek,
405 .read = generic_read_dir,
406#ifdef HAVE_VFS_ITERATE_SHARED
407 .iterate_shared = zpl_snapdir_iterate,
408#elif defined(HAVE_VFS_ITERATE)
409 .iterate = zpl_snapdir_iterate,
410#else
411 .readdir = zpl_snapdir_readdir,
412#endif
413
414};
415
416/*
417 * The '.zfs/snapshot' directory inode operations. These mainly control
418 * creating an inode for a snapshot directory and initializing the needed
419 * infrastructure to automount the snapshot. See zpl_snapdir_lookup().
420 */
421const struct inode_operations zpl_ops_snapdir = {
422 .lookup = zpl_snapdir_lookup,
423 .getattr = zpl_snapdir_getattr,
424#ifdef HAVE_RENAME_WANTS_FLAGS
425 .rename = zpl_snapdir_rename2,
426#else
427 .rename = zpl_snapdir_rename,
428#endif
429 .rmdir = zpl_snapdir_rmdir,
430 .mkdir = zpl_snapdir_mkdir,
431};
432
433static struct dentry *
434#ifdef HAVE_LOOKUP_NAMEIDATA
435zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
436 struct nameidata *nd)
437#else
438zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
439 unsigned int flags)
440#endif
441{
442 fstrans_cookie_t cookie;
443 cred_t *cr = CRED();
444 struct inode *ip = NULL;
445 int error;
446
447 crhold(cr);
448 cookie = spl_fstrans_mark();
449 error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
450 0, cr, NULL, NULL);
451 ASSERT3S(error, <=, 0);
452 spl_fstrans_unmark(cookie);
453 crfree(cr);
454
455 if (error) {
456 if (error == -ENOENT)
457 return (d_splice_alias(NULL, dentry));
458 else
459 return (ERR_PTR(error));
460 }
461
462 return (d_splice_alias(ip, dentry));
463}
464
465static int
466zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
467{
468 fstrans_cookie_t cookie;
469 cred_t *cr = CRED();
470 zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
471 znode_t *dzp;
472 int error = 0;
473
474 ZFS_ENTER(zsb);
475 cookie = spl_fstrans_mark();
476
477 if (zsb->z_shares_dir == 0) {
478 dir_emit_dots(filp, ctx);
479 goto out;
480 }
481
482 error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
483 if (error)
484 goto out;
485
486 crhold(cr);
487 error = -zfs_readdir(ZTOI(dzp), ctx, cr);
488 crfree(cr);
489
490 iput(ZTOI(dzp));
491out:
492 spl_fstrans_unmark(cookie);
493 ZFS_EXIT(zsb);
494 ASSERT3S(error, <=, 0);
495
496 return (error);
497}
498
499#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
500static int
501zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
502{
503 struct dir_context ctx = DIR_CONTEXT_INIT(dirent, filldir, filp->f_pos);
504 int error;
505
506 error = zpl_shares_iterate(filp, &ctx);
507 filp->f_pos = ctx.pos;
508
509 return (error);
510}
511#endif /* HAVE_VFS_ITERATE */
512
513/* ARGSUSED */
514static int
3e990ae0
CIK
515zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
516 u32 request_mask, unsigned int query_flags)
87d546d8 517{
3e990ae0 518 struct inode *ip = path->dentry->d_inode;
87d546d8
TG
519 zfs_sb_t *zsb = ITOZSB(ip);
520 znode_t *dzp;
521 int error;
522
523 ZFS_ENTER(zsb);
524
525 if (zsb->z_shares_dir == 0) {
3e990ae0 526 generic_fillattr(path->dentry->d_inode, stat);
87d546d8 527 stat->nlink = stat->size = 2;
df9d7621 528 stat->atime = current_time(ip);
87d546d8 529 ZFS_EXIT(zsb);
3e990ae0 530 return (0);
87d546d8
TG
531 }
532
533 error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
534 if (error == 0) {
535 error = -zfs_getattr_fast(ZTOI(dzp), stat);
536 iput(ZTOI(dzp));
537 }
538
539 ZFS_EXIT(zsb);
540 ASSERT3S(error, <=, 0);
541
542 return (error);
543}
3e990ae0 544ZPL_GETATTR_WRAPPER(zpl_shares_getattr);
87d546d8
TG
545
546/*
547 * The '.zfs/shares' directory file operations.
548 */
549const struct file_operations zpl_fops_shares = {
550 .open = zpl_common_open,
551 .llseek = generic_file_llseek,
552 .read = generic_read_dir,
553#ifdef HAVE_VFS_ITERATE_SHARED
554 .iterate_shared = zpl_shares_iterate,
555#elif defined(HAVE_VFS_ITERATE)
556 .iterate = zpl_shares_iterate,
557#else
558 .readdir = zpl_shares_readdir,
559#endif
560
561};
562
563/*
564 * The '.zfs/shares' directory inode operations.
565 */
566const struct inode_operations zpl_ops_shares = {
567 .lookup = zpl_shares_lookup,
568 .getattr = zpl_shares_getattr,
569};