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