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