6c742c9e8c6a636270ab6391b16e89cd79f30dd6
[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 static int
50 zpl_common_readdir(struct file *filp, void *dirent, filldir_t filldir)
51 {
52         struct dentry *dentry = filp->f_path.dentry;
53         struct inode *ip = dentry->d_inode;
54         int error = 0;
55
56         switch (filp->f_pos) {
57         case 0:
58                 error = filldir(dirent, ".", 1, 0, ip->i_ino, DT_DIR);
59                 if (error)
60                         break;
61
62                 filp->f_pos++;
63                 /* fall-thru */
64         case 1:
65                 error = filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR);
66                 if (error)
67                         break;
68
69                 filp->f_pos++;
70                 /* fall-thru */
71         default:
72                 break;
73         }
74
75         return (error);
76 }
77
78 /*
79  * Get root directory contents.
80  */
81 static int
82 zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
83 {
84         struct dentry *dentry = filp->f_path.dentry;
85         struct inode *ip = dentry->d_inode;
86         zfs_sb_t *zsb = ITOZSB(ip);
87         int error = 0;
88
89         ZFS_ENTER(zsb);
90
91         switch (filp->f_pos) {
92         case 0:
93                 error = filldir(dirent, ".", 1, 0, ip->i_ino, DT_DIR);
94                 if (error)
95                         goto out;
96
97                 filp->f_pos++;
98                 /* fall-thru */
99         case 1:
100                 error = filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR);
101                 if (error)
102                         goto out;
103
104                 filp->f_pos++;
105                 /* fall-thru */
106         case 2:
107                 error = filldir(dirent, ZFS_SNAPDIR_NAME,
108                     strlen(ZFS_SNAPDIR_NAME), 2, ZFSCTL_INO_SNAPDIR, DT_DIR);
109                 if (error)
110                         goto out;
111
112                 filp->f_pos++;
113                 /* fall-thru */
114         case 3:
115                 error = filldir(dirent, ZFS_SHAREDIR_NAME,
116                     strlen(ZFS_SHAREDIR_NAME), 3, ZFSCTL_INO_SHARES, DT_DIR);
117                 if (error)
118                         goto out;
119
120                 filp->f_pos++;
121                 /* fall-thru */
122         }
123 out:
124         ZFS_EXIT(zsb);
125
126         return (error);
127 }
128
129 /*
130  * Get root directory attributes.
131  */
132 /* ARGSUSED */
133 static int
134 zpl_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
135     struct kstat *stat)
136 {
137         int error;
138
139         error = simple_getattr(mnt, dentry, stat);
140         stat->atime = CURRENT_TIME;
141
142         return (error);
143 }
144
145 static struct dentry *
146 zpl_root_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd)
147 {
148         cred_t *cr = CRED();
149         struct inode *ip;
150         int error;
151
152         crhold(cr);
153         error = -zfsctl_root_lookup(dip, dname(dentry), &ip, 0, cr, NULL, NULL);
154         ASSERT3S(error, <=, 0);
155         crfree(cr);
156
157         if (error) {
158                 if (error == -ENOENT)
159                         return d_splice_alias(NULL, dentry);
160                 else
161                         return ERR_PTR(error);
162         }
163
164         return d_splice_alias(ip, dentry);
165 }
166
167 /*
168  * The '.zfs' control directory file and inode operations.
169  */
170 const struct file_operations zpl_fops_root = {
171         .open           = zpl_common_open,
172         .llseek         = generic_file_llseek,
173         .read           = generic_read_dir,
174         .readdir        = zpl_root_readdir,
175 };
176
177 const struct inode_operations zpl_ops_root = {
178         .lookup         = zpl_root_lookup,
179         .getattr        = zpl_root_getattr,
180 };
181
182 static struct dentry *
183 zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
184     struct nameidata *nd)
185 {
186         cred_t *cr = CRED();
187         struct inode *ip;
188         int error;
189
190         crhold(cr);
191         error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
192             0, cr, NULL, NULL);
193         ASSERT3S(error, <=, 0);
194         crfree(cr);
195
196         if (error) {
197                 if (error == -ENOENT)
198                         return d_splice_alias(NULL, dentry);
199                 else
200                         return ERR_PTR(error);
201         }
202
203         /*
204          * Auto mounting of snapshots is only supported for 2.6.37 and
205          * newer kernels.  Prior to this kernel the ops->follow_link()
206          * callback was used as a hack to trigger the mount.  The
207          * resulting vfsmount was then explicitly grafted in to the
208          * name space.  While it might be possible to add compatibility
209          * code to accomplish this it would require considerable care.
210          */
211 #ifdef HAVE_AUTOMOUNT
212         dentry->d_op = &zpl_dops_snapdirs;
213 #endif /* HAVE_AUTOMOUNT */
214
215         return d_splice_alias(ip, dentry);
216 }
217
218 /* ARGSUSED */
219 static int
220 zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
221 {
222         struct dentry *dentry = filp->f_path.dentry;
223         struct inode *dip = dentry->d_inode;
224         zfs_sb_t *zsb = ITOZSB(dip);
225         char snapname[MAXNAMELEN];
226         uint64_t id, cookie;
227         boolean_t case_conflict;
228         int error = 0;
229
230         ZFS_ENTER(zsb);
231
232         cookie = filp->f_pos;
233         switch (filp->f_pos) {
234         case 0:
235                 error = filldir(dirent, ".", 1, 0, dip->i_ino, DT_DIR);
236                 if (error)
237                         goto out;
238
239                 filp->f_pos++;
240                 /* fall-thru */
241         case 1:
242                 error = filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR);
243                 if (error)
244                         goto out;
245
246                 filp->f_pos++;
247                 /* fall-thru */
248         default:
249                 while (error == 0) {
250                         error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
251                             snapname, &id, &cookie, &case_conflict);
252                         if (error)
253                                 goto out;
254
255                         error = filldir(dirent, snapname, strlen(snapname),
256                             filp->f_pos, ZFSCTL_INO_SHARES - id, DT_DIR);
257                         if (error)
258                                 goto out;
259
260                         filp->f_pos = cookie;
261                 }
262         }
263 out:
264         ZFS_EXIT(zsb);
265
266         if (error == -ENOENT)
267                 return (0);
268
269         return (error);
270 }
271
272 int
273 zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
274     struct inode *tdip, struct dentry *tdentry)
275 {
276         cred_t *cr = CRED();
277         int error;
278
279         crhold(cr);
280         error = -zfsctl_snapdir_rename(sdip, dname(sdentry),
281             tdip, dname(tdentry), cr, 0);
282         ASSERT3S(error, <=, 0);
283         crfree(cr);
284
285         return (error);
286 }
287
288 static int
289 zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
290 {
291         cred_t *cr = CRED();
292         int error;
293
294         crhold(cr);
295         error = -zfsctl_snapdir_remove(dip, dname(dentry), cr, 0);
296         ASSERT3S(error, <=, 0);
297         crfree(cr);
298
299         return (error);
300 }
301
302 static int
303 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, int mode)
304 {
305         cred_t *cr = CRED();
306         vattr_t *vap;
307         struct inode *ip;
308         int error;
309
310         crhold(cr);
311         vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
312         zpl_vap_init(vap, dip, dentry, mode | S_IFDIR, cr);
313
314         error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
315         if (error == 0) {
316 #ifdef HAVE_AUTOMOUNT
317                 dentry->d_op = &zpl_dops_snapdirs;
318 #endif /* HAVE_AUTOMOUNT */
319                 d_instantiate(dentry, ip);
320         }
321
322         kmem_free(vap, sizeof(vattr_t));
323         ASSERT3S(error, <=, 0);
324         crfree(cr);
325
326         return (error);
327 }
328
329 #ifdef HAVE_AUTOMOUNT
330 static struct vfsmount *
331 zpl_snapdir_automount(struct path *path)
332 {
333         struct dentry *dentry = path->dentry;
334         int error;
335
336         /*
337          * We must briefly disable automounts for this dentry because the
338          * user space mount utility will trigger another lookup on this
339          * directory.  That will result in zpl_snapdir_automount() being
340          * called repeatedly.  The DCACHE_NEED_AUTOMOUNT flag can be
341          * safely reset once the mount completes.
342          */
343         dentry->d_flags &= ~DCACHE_NEED_AUTOMOUNT;
344         error = -zfsctl_mount_snapshot(path, 0);
345         dentry->d_flags |= DCACHE_NEED_AUTOMOUNT;
346         if (error)
347                 return ERR_PTR(error);
348
349         /*
350          * Rather than returning the new vfsmount for the snapshot we must
351          * return NULL to indicate a mount collision.  This is done because
352          * the user space mount calls do_add_mount() which adds the vfsmount
353          * to the name space.  If we returned the new mount here it would be
354          * added again to the vfsmount list resulting in list corruption.
355          */
356         return (NULL);
357 }
358 #endif /* HAVE_AUTOMOUNT */
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 = avl_numnodes(&zsb->z_ctldir_snaps) + 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         .readdir        = zpl_snapdir_readdir,
391 };
392
393 /*
394  * The '.zfs/snapshot' directory inode operations.  These mainly control
395  * creating an inode for a snapshot directory and initializing the needed
396  * infrastructure to automount the snapshot.  See zpl_snapdir_lookup().
397  */
398 const struct inode_operations zpl_ops_snapdir = {
399         .lookup         = zpl_snapdir_lookup,
400         .getattr        = zpl_snapdir_getattr,
401         .rename         = zpl_snapdir_rename,
402         .rmdir          = zpl_snapdir_rmdir,
403         .mkdir          = zpl_snapdir_mkdir,
404 };
405
406 #ifdef HAVE_AUTOMOUNT
407 const struct dentry_operations zpl_dops_snapdirs = {
408         .d_automount    = zpl_snapdir_automount,
409 };
410 #endif /* HAVE_AUTOMOUNT */
411
412 static struct dentry *
413 zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
414     struct nameidata *nd)
415 {
416         cred_t *cr = CRED();
417         struct inode *ip = NULL;
418         int error;
419
420         crhold(cr);
421         error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
422             0, cr, NULL, NULL);
423         ASSERT3S(error, <=, 0);
424         crfree(cr);
425
426         if (error) {
427                 if (error == -ENOENT)
428                         return d_splice_alias(NULL, dentry);
429                 else
430                         return ERR_PTR(error);
431         }
432
433         return d_splice_alias(ip, dentry);
434 }
435
436 /* ARGSUSED */
437 static int
438 zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
439 {
440         cred_t *cr = CRED();
441         struct dentry *dentry = filp->f_path.dentry;
442         struct inode *ip = dentry->d_inode;
443         zfs_sb_t *zsb = ITOZSB(ip);
444         znode_t *dzp;
445         int error;
446
447         ZFS_ENTER(zsb);
448
449         if (zsb->z_shares_dir == 0) {
450                 error = zpl_common_readdir(filp, dirent, filldir);
451                 ZFS_EXIT(zsb);
452                 return (error);
453         }
454
455         error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
456         if (error) {
457                 ZFS_EXIT(zsb);
458                 return (error);
459         }
460
461         crhold(cr);
462         error = -zfs_readdir(ZTOI(dzp), dirent, filldir, &filp->f_pos, cr);
463         crfree(cr);
464
465         iput(ZTOI(dzp));
466         ZFS_EXIT(zsb);
467         ASSERT3S(error, <=, 0);
468
469         return (error);
470 }
471
472 /* ARGSUSED */
473 static int
474 zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
475     struct kstat *stat)
476 {
477         struct inode *ip = dentry->d_inode;
478         zfs_sb_t *zsb = ITOZSB(ip);
479         znode_t *dzp;
480         int error;
481
482         ZFS_ENTER(zsb);
483
484         if (zsb->z_shares_dir == 0) {
485                 error = simple_getattr(mnt, dentry, stat);
486                 stat->nlink = stat->size = 2;
487                 stat->atime = CURRENT_TIME;
488                 ZFS_EXIT(zsb);
489                 return (error);
490         }
491
492         error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
493         if (error == 0)
494                 error = -zfs_getattr_fast(dentry->d_inode, stat);
495
496         iput(ZTOI(dzp));
497         ZFS_EXIT(zsb);
498         ASSERT3S(error, <=, 0);
499
500         return (error);
501 }
502
503 /*
504  * The '.zfs/shares' directory file operations.
505  */
506 const struct file_operations zpl_fops_shares = {
507         .open           = zpl_common_open,
508         .llseek         = generic_file_llseek,
509         .read           = generic_read_dir,
510         .readdir        = zpl_shares_readdir,
511 };
512
513 /*
514  * The '.zfs/shares' directory inode operations.
515  */
516 const struct inode_operations zpl_ops_shares = {
517         .lookup         = zpl_shares_lookup,
518         .getattr        = zpl_shares_getattr,
519 };