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