]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
MFC r299947: fix locking in zfsctl_root_lookup
[FreeBSD/stable/9.git] / sys / cddl / contrib / opensolaris / uts / common / fs / zfs / zfs_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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright (c) 2013 by Delphix. All rights reserved.
24  */
25
26 /*
27  * ZFS control directory (a.k.a. ".zfs")
28  *
29  * This directory provides a common location for all ZFS meta-objects.
30  * Currently, this is only the 'snapshot' directory, but this may expand in the
31  * future.  The elements are built using the GFS primitives, as the hierarchy
32  * does not actually exist on disk.
33  *
34  * For 'snapshot', we don't want to have all snapshots always mounted, because
35  * this would take up a huge amount of space in /etc/mnttab.  We have three
36  * types of objects:
37  *
38  *      ctldir ------> snapshotdir -------> snapshot
39  *                                             |
40  *                                             |
41  *                                             V
42  *                                         mounted fs
43  *
44  * The 'snapshot' node contains just enough information to lookup '..' and act
45  * as a mountpoint for the snapshot.  Whenever we lookup a specific snapshot, we
46  * perform an automount of the underlying filesystem and return the
47  * corresponding vnode.
48  *
49  * All mounts are handled automatically by the kernel, but unmounts are
50  * (currently) handled from user land.  The main reason is that there is no
51  * reliable way to auto-unmount the filesystem when it's "no longer in use".
52  * When the user unmounts a filesystem, we call zfsctl_unmount(), which
53  * unmounts any snapshots within the snapshot directory.
54  *
55  * The '.zfs', '.zfs/snapshot', and all directories created under
56  * '.zfs/snapshot' (ie: '.zfs/snapshot/<snapname>') are all GFS nodes and
57  * share the same vfs_t as the head filesystem (what '.zfs' lives under).
58  *
59  * File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>'
60  * (ie: snapshots) are ZFS nodes and have their own unique vfs_t.
61  * However, vnodes within these mounted on file systems have their v_vfsp
62  * fields set to the head filesystem to make NFS happy (see
63  * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t
64  * so that it cannot be freed until all snapshots have been unmounted.
65  */
66
67 #include <sys/zfs_context.h>
68 #include <sys/zfs_ctldir.h>
69 #include <sys/zfs_ioctl.h>
70 #include <sys/zfs_vfsops.h>
71 #include <sys/namei.h>
72 #include <sys/gfs.h>
73 #include <sys/stat.h>
74 #include <sys/dmu.h>
75 #include <sys/dsl_destroy.h>
76 #include <sys/dsl_deleg.h>
77 #include <sys/mount.h>
78 #include <sys/sunddi.h>
79
80 #include "zfs_namecheck.h"
81
82 typedef struct zfsctl_node {
83         gfs_dir_t       zc_gfs_private;
84         uint64_t        zc_id;
85         timestruc_t     zc_cmtime;      /* ctime and mtime, always the same */
86 } zfsctl_node_t;
87
88 typedef struct zfsctl_snapdir {
89         zfsctl_node_t   sd_node;
90         kmutex_t        sd_lock;
91         avl_tree_t      sd_snaps;
92 } zfsctl_snapdir_t;
93
94 typedef struct {
95         char            *se_name;
96         vnode_t         *se_root;
97         avl_node_t      se_node;
98 } zfs_snapentry_t;
99
100 static int
101 snapentry_compare(const void *a, const void *b)
102 {
103         const zfs_snapentry_t *sa = a;
104         const zfs_snapentry_t *sb = b;
105         int ret = strcmp(sa->se_name, sb->se_name);
106
107         if (ret < 0)
108                 return (-1);
109         else if (ret > 0)
110                 return (1);
111         else
112                 return (0);
113 }
114
115 #ifdef sun
116 vnodeops_t *zfsctl_ops_root;
117 vnodeops_t *zfsctl_ops_snapdir;
118 vnodeops_t *zfsctl_ops_snapshot;
119 vnodeops_t *zfsctl_ops_shares;
120 vnodeops_t *zfsctl_ops_shares_dir;
121
122 static const fs_operation_def_t zfsctl_tops_root[];
123 static const fs_operation_def_t zfsctl_tops_snapdir[];
124 static const fs_operation_def_t zfsctl_tops_snapshot[];
125 static const fs_operation_def_t zfsctl_tops_shares[];
126 #else   /* !sun */
127 static struct vop_vector zfsctl_ops_root;
128 static struct vop_vector zfsctl_ops_snapdir;
129 static struct vop_vector zfsctl_ops_snapshot;
130 static struct vop_vector zfsctl_ops_shares;
131 static struct vop_vector zfsctl_ops_shares_dir;
132 #endif  /* !sun */
133
134 static vnode_t *zfsctl_mknode_snapdir(vnode_t *);
135 static vnode_t *zfsctl_mknode_shares(vnode_t *);
136 static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset);
137 static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *);
138
139 #ifdef sun
140 static gfs_opsvec_t zfsctl_opsvec[] = {
141         { ".zfs", zfsctl_tops_root, &zfsctl_ops_root },
142         { ".zfs/snapshot", zfsctl_tops_snapdir, &zfsctl_ops_snapdir },
143         { ".zfs/snapshot/vnode", zfsctl_tops_snapshot, &zfsctl_ops_snapshot },
144         { ".zfs/shares", zfsctl_tops_shares, &zfsctl_ops_shares_dir },
145         { ".zfs/shares/vnode", zfsctl_tops_shares, &zfsctl_ops_shares },
146         { NULL }
147 };
148 #endif  /* sun */
149
150 /*
151  * Root directory elements.  We only have two entries
152  * snapshot and shares.
153  */
154 static gfs_dirent_t zfsctl_root_entries[] = {
155         { "snapshot", zfsctl_mknode_snapdir, GFS_CACHE_VNODE },
156         { "shares", zfsctl_mknode_shares, GFS_CACHE_VNODE },
157         { NULL }
158 };
159
160 /* include . and .. in the calculation */
161 #define NROOT_ENTRIES   ((sizeof (zfsctl_root_entries) / \
162     sizeof (gfs_dirent_t)) + 1)
163
164
165 /*
166  * Initialize the various GFS pieces we'll need to create and manipulate .zfs
167  * directories.  This is called from the ZFS init routine, and initializes the
168  * vnode ops vectors that we'll be using.
169  */
170 void
171 zfsctl_init(void)
172 {
173 #ifdef sun
174         VERIFY(gfs_make_opsvec(zfsctl_opsvec) == 0);
175 #endif
176 }
177
178 void
179 zfsctl_fini(void)
180 {
181 #ifdef sun
182         /*
183          * Remove vfsctl vnode ops
184          */
185         if (zfsctl_ops_root)
186                 vn_freevnodeops(zfsctl_ops_root);
187         if (zfsctl_ops_snapdir)
188                 vn_freevnodeops(zfsctl_ops_snapdir);
189         if (zfsctl_ops_snapshot)
190                 vn_freevnodeops(zfsctl_ops_snapshot);
191         if (zfsctl_ops_shares)
192                 vn_freevnodeops(zfsctl_ops_shares);
193         if (zfsctl_ops_shares_dir)
194                 vn_freevnodeops(zfsctl_ops_shares_dir);
195
196         zfsctl_ops_root = NULL;
197         zfsctl_ops_snapdir = NULL;
198         zfsctl_ops_snapshot = NULL;
199         zfsctl_ops_shares = NULL;
200         zfsctl_ops_shares_dir = NULL;
201 #endif  /* sun */
202 }
203
204 boolean_t
205 zfsctl_is_node(vnode_t *vp)
206 {
207         return (vn_matchops(vp, zfsctl_ops_root) ||
208             vn_matchops(vp, zfsctl_ops_snapdir) ||
209             vn_matchops(vp, zfsctl_ops_snapshot) ||
210             vn_matchops(vp, zfsctl_ops_shares) ||
211             vn_matchops(vp, zfsctl_ops_shares_dir));
212
213 }
214
215 /*
216  * Return the inode number associated with the 'snapshot' or
217  * 'shares' directory.
218  */
219 /* ARGSUSED */
220 static ino64_t
221 zfsctl_root_inode_cb(vnode_t *vp, int index)
222 {
223         zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
224
225         ASSERT(index < 2);
226
227         if (index == 0)
228                 return (ZFSCTL_INO_SNAPDIR);
229
230         return (zfsvfs->z_shares_dir);
231 }
232
233 /*
234  * Create the '.zfs' directory.  This directory is cached as part of the VFS
235  * structure.  This results in a hold on the vfs_t.  The code in zfs_umount()
236  * therefore checks against a vfs_count of 2 instead of 1.  This reference
237  * is removed when the ctldir is destroyed in the unmount.
238  */
239 void
240 zfsctl_create(zfsvfs_t *zfsvfs)
241 {
242         vnode_t *vp, *rvp;
243         zfsctl_node_t *zcp;
244         uint64_t crtime[2];
245
246         ASSERT(zfsvfs->z_ctldir == NULL);
247
248         vp = gfs_root_create(sizeof (zfsctl_node_t), zfsvfs->z_vfs,
249             &zfsctl_ops_root, ZFSCTL_INO_ROOT, zfsctl_root_entries,
250             zfsctl_root_inode_cb, MAXNAMELEN, NULL, NULL);
251         zcp = vp->v_data;
252         zcp->zc_id = ZFSCTL_INO_ROOT;
253
254         VERIFY(VFS_ROOT(zfsvfs->z_vfs, LK_EXCLUSIVE, &rvp) == 0);
255         VERIFY(0 == sa_lookup(VTOZ(rvp)->z_sa_hdl, SA_ZPL_CRTIME(zfsvfs),
256             &crtime, sizeof (crtime)));
257         ZFS_TIME_DECODE(&zcp->zc_cmtime, crtime);
258         VN_URELE(rvp);
259
260         /*
261          * We're only faking the fact that we have a root of a filesystem for
262          * the sake of the GFS interfaces.  Undo the flag manipulation it did
263          * for us.
264          */
265         vp->v_vflag &= ~VV_ROOT;
266
267         zfsvfs->z_ctldir = vp;
268
269         VOP_UNLOCK(vp, 0);
270 }
271
272 /*
273  * Destroy the '.zfs' directory.  Only called when the filesystem is unmounted.
274  * There might still be more references if we were force unmounted, but only
275  * new zfs_inactive() calls can occur and they don't reference .zfs
276  */
277 void
278 zfsctl_destroy(zfsvfs_t *zfsvfs)
279 {
280         VN_RELE(zfsvfs->z_ctldir);
281         zfsvfs->z_ctldir = NULL;
282 }
283
284 /*
285  * Given a root znode, retrieve the associated .zfs directory.
286  * Add a hold to the vnode and return it.
287  */
288 vnode_t *
289 zfsctl_root(znode_t *zp)
290 {
291         ASSERT(zfs_has_ctldir(zp));
292         VN_HOLD(zp->z_zfsvfs->z_ctldir);
293         return (zp->z_zfsvfs->z_ctldir);
294 }
295
296 /*
297  * Common open routine.  Disallow any write access.
298  */
299 /* ARGSUSED */
300 static int
301 zfsctl_common_open(struct vop_open_args *ap)
302 {
303         int flags = ap->a_mode;
304
305         if (flags & FWRITE)
306                 return (SET_ERROR(EACCES));
307
308         return (0);
309 }
310
311 /*
312  * Common close routine.  Nothing to do here.
313  */
314 /* ARGSUSED */
315 static int
316 zfsctl_common_close(struct vop_close_args *ap)
317 {
318         return (0);
319 }
320
321 /*
322  * Common access routine.  Disallow writes.
323  */
324 /* ARGSUSED */
325 static int
326 zfsctl_common_access(ap)
327         struct vop_access_args /* {
328                 struct vnode *a_vp;
329                 accmode_t a_accmode;
330                 struct ucred *a_cred;
331                 struct thread *a_td;
332         } */ *ap;
333 {
334         accmode_t accmode = ap->a_accmode;
335
336 #ifdef TODO
337         if (flags & V_ACE_MASK) {
338                 if (accmode & ACE_ALL_WRITE_PERMS)
339                         return (SET_ERROR(EACCES));
340         } else {
341 #endif
342                 if (accmode & VWRITE)
343                         return (SET_ERROR(EACCES));
344 #ifdef TODO
345         }
346 #endif
347
348         return (0);
349 }
350
351 /*
352  * Common getattr function.  Fill in basic information.
353  */
354 static void
355 zfsctl_common_getattr(vnode_t *vp, vattr_t *vap)
356 {
357         timestruc_t     now;
358
359         vap->va_uid = 0;
360         vap->va_gid = 0;
361         vap->va_rdev = 0;
362         /*
363          * We are a purely virtual object, so we have no
364          * blocksize or allocated blocks.
365          */
366         vap->va_blksize = 0;
367         vap->va_nblocks = 0;
368         vap->va_seq = 0;
369         vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
370         vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP |
371             S_IROTH | S_IXOTH;
372         vap->va_type = VDIR;
373         /*
374          * We live in the now (for atime).
375          */
376         gethrestime(&now);
377         vap->va_atime = now;
378         /* FreeBSD: Reset chflags(2) flags. */
379         vap->va_flags = 0;
380 }
381
382 /*ARGSUSED*/
383 static int
384 zfsctl_common_fid(ap)
385         struct vop_fid_args /* {
386                 struct vnode *a_vp;
387                 struct fid *a_fid;
388         } */ *ap;
389 {
390         vnode_t         *vp = ap->a_vp;
391         fid_t           *fidp = (void *)ap->a_fid;
392         zfsvfs_t        *zfsvfs = vp->v_vfsp->vfs_data;
393         zfsctl_node_t   *zcp = vp->v_data;
394         uint64_t        object = zcp->zc_id;
395         zfid_short_t    *zfid;
396         int             i;
397
398         ZFS_ENTER(zfsvfs);
399
400 #ifdef illumos
401         if (fidp->fid_len < SHORT_FID_LEN) {
402                 fidp->fid_len = SHORT_FID_LEN;
403                 ZFS_EXIT(zfsvfs);
404                 return (SET_ERROR(ENOSPC));
405         }
406 #endif
407
408         zfid = (zfid_short_t *)fidp;
409
410         zfid->zf_len = SHORT_FID_LEN;
411
412         for (i = 0; i < sizeof (zfid->zf_object); i++)
413                 zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
414
415         /* .zfs znodes always have a generation number of 0 */
416         for (i = 0; i < sizeof (zfid->zf_gen); i++)
417                 zfid->zf_gen[i] = 0;
418
419         ZFS_EXIT(zfsvfs);
420         return (0);
421 }
422
423
424 /*ARGSUSED*/
425 static int
426 zfsctl_shares_fid(ap)
427         struct vop_fid_args /* {
428                 struct vnode *a_vp;
429                 struct fid *a_fid;
430         } */ *ap;
431 {
432         vnode_t         *vp = ap->a_vp;
433         fid_t           *fidp = (void *)ap->a_fid;
434         zfsvfs_t        *zfsvfs = vp->v_vfsp->vfs_data;
435         znode_t         *dzp;
436         int             error;
437
438         ZFS_ENTER(zfsvfs);
439
440         if (zfsvfs->z_shares_dir == 0) {
441                 ZFS_EXIT(zfsvfs);
442                 return (SET_ERROR(ENOTSUP));
443         }
444
445         if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
446                 error = VOP_FID(ZTOV(dzp), fidp);
447                 VN_RELE(ZTOV(dzp));
448         }
449
450         ZFS_EXIT(zfsvfs);
451         return (error);
452 }
453
454 static int
455 zfsctl_common_reclaim(ap)
456         struct vop_reclaim_args /* {
457                 struct vnode *a_vp;
458                 struct thread *a_td;
459         } */ *ap;
460 {
461         vnode_t *vp = ap->a_vp;
462
463         /*
464          * Destroy the vm object and flush associated pages.
465          */
466         vnode_destroy_vobject(vp);
467         VI_LOCK(vp);
468         vp->v_data = NULL;
469         VI_UNLOCK(vp);
470         return (0);
471 }
472
473 /*
474  * .zfs inode namespace
475  *
476  * We need to generate unique inode numbers for all files and directories
477  * within the .zfs pseudo-filesystem.  We use the following scheme:
478  *
479  *      ENTRY                   ZFSCTL_INODE
480  *      .zfs                    1
481  *      .zfs/snapshot           2
482  *      .zfs/snapshot/<snap>    objectid(snap)
483  */
484
485 #define ZFSCTL_INO_SNAP(id)     (id)
486
487 /*
488  * Get root directory attributes.
489  */
490 /* ARGSUSED */
491 static int
492 zfsctl_root_getattr(ap)
493         struct vop_getattr_args /* {
494                 struct vnode *a_vp;
495                 struct vattr *a_vap;
496                 struct ucred *a_cred;
497         } */ *ap;
498 {
499         struct vnode *vp = ap->a_vp;
500         struct vattr *vap = ap->a_vap;
501         zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
502         zfsctl_node_t *zcp = vp->v_data;
503
504         ZFS_ENTER(zfsvfs);
505         vap->va_nodeid = ZFSCTL_INO_ROOT;
506         vap->va_nlink = vap->va_size = NROOT_ENTRIES;
507         vap->va_mtime = vap->va_ctime = zcp->zc_cmtime;
508         vap->va_birthtime = vap->va_ctime;
509
510         zfsctl_common_getattr(vp, vap);
511         ZFS_EXIT(zfsvfs);
512
513         return (0);
514 }
515
516 /*
517  * Special case the handling of "..".
518  */
519 /* ARGSUSED */
520 int
521 zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
522     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
523     int *direntflags, pathname_t *realpnp)
524 {
525         zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
526         int err;
527
528         /*
529          * No extended attributes allowed under .zfs
530          */
531         if (flags & LOOKUP_XATTR)
532                 return (SET_ERROR(EINVAL));
533
534         ZFS_ENTER(zfsvfs);
535
536         if (strcmp(nm, "..") == 0) {
537 #ifdef illumos
538                 err = VFS_ROOT(dvp->v_vfsp, LK_EXCLUSIVE, vpp);
539 #else
540                 /*
541                  * NB: can not use VFS_ROOT here as it would acquire
542                  * the vnode lock of the parent (root) vnode while
543                  * holding the child's (.zfs) lock.
544                  */
545                 znode_t *rootzp;
546
547                 err = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
548                 if (err == 0)
549                         *vpp = ZTOV(rootzp);
550 #endif
551         } else {
552                 err = gfs_vop_lookup(dvp, nm, vpp, pnp, flags, rdir,
553                     cr, ct, direntflags, realpnp);
554         }
555
556         ZFS_EXIT(zfsvfs);
557
558         return (err);
559 }
560
561 #ifdef sun
562 static int
563 zfsctl_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
564     caller_context_t *ct)
565 {
566         /*
567          * We only care about ACL_ENABLED so that libsec can
568          * display ACL correctly and not default to POSIX draft.
569          */
570         if (cmd == _PC_ACL_ENABLED) {
571                 *valp = _ACL_ACE_ENABLED;
572                 return (0);
573         }
574
575         return (fs_pathconf(vp, cmd, valp, cr, ct));
576 }
577 #endif  /* sun */
578
579 #ifdef sun
580 static const fs_operation_def_t zfsctl_tops_root[] = {
581         { VOPNAME_OPEN,         { .vop_open = zfsctl_common_open }      },
582         { VOPNAME_CLOSE,        { .vop_close = zfsctl_common_close }    },
583         { VOPNAME_IOCTL,        { .error = fs_inval }                   },
584         { VOPNAME_GETATTR,      { .vop_getattr = zfsctl_root_getattr }  },
585         { VOPNAME_ACCESS,       { .vop_access = zfsctl_common_access }  },
586         { VOPNAME_READDIR,      { .vop_readdir = gfs_vop_readdir }      },
587         { VOPNAME_LOOKUP,       { .vop_lookup = zfsctl_root_lookup }    },
588         { VOPNAME_SEEK,         { .vop_seek = fs_seek }                 },
589         { VOPNAME_INACTIVE,     { .vop_inactive = gfs_vop_inactive }    },
590         { VOPNAME_PATHCONF,     { .vop_pathconf = zfsctl_pathconf }     },
591         { VOPNAME_FID,          { .vop_fid = zfsctl_common_fid  }       },
592         { NULL }
593 };
594 #endif  /* sun */
595
596 /*
597  * Special case the handling of "..".
598  */
599 /* ARGSUSED */
600 int
601 zfsctl_freebsd_root_lookup(ap)
602         struct vop_lookup_args /* {
603                 struct vnode *a_dvp;
604                 struct vnode **a_vpp;
605                 struct componentname *a_cnp;
606         } */ *ap;
607 {
608         vnode_t *dvp = ap->a_dvp;
609         vnode_t **vpp = ap->a_vpp;
610         cred_t *cr = ap->a_cnp->cn_cred;
611         int flags = ap->a_cnp->cn_flags;
612         int lkflags = ap->a_cnp->cn_lkflags;
613         int nameiop = ap->a_cnp->cn_nameiop;
614         char nm[NAME_MAX + 1];
615         int err;
616
617         if ((flags & ISLASTCN) && (nameiop == RENAME || nameiop == CREATE))
618                 return (EOPNOTSUPP);
619
620         ASSERT(ap->a_cnp->cn_namelen < sizeof(nm));
621         strlcpy(nm, ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen + 1);
622
623         err = zfsctl_root_lookup(dvp, nm, vpp, NULL, 0, NULL, cr, NULL, NULL, NULL);
624         if (err == 0 && (nm[0] != '.' || nm[1] != '\0')) {
625                 if (flags & ISDOTDOT)
626                         VOP_UNLOCK(dvp, 0);
627                 err = vn_lock(*vpp, lkflags);
628                 if (err != 0) {
629                         vrele(*vpp);
630                         *vpp = NULL;
631                 }
632                 if (flags & ISDOTDOT)
633                         vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
634         }
635
636         return (err);
637 }
638
639 static struct vop_vector zfsctl_ops_root = {
640         .vop_default =  &default_vnodeops,
641         .vop_open =     zfsctl_common_open,
642         .vop_close =    zfsctl_common_close,
643         .vop_ioctl =    VOP_EINVAL,
644         .vop_getattr =  zfsctl_root_getattr,
645         .vop_access =   zfsctl_common_access,
646         .vop_readdir =  gfs_vop_readdir,
647         .vop_lookup =   zfsctl_freebsd_root_lookup,
648         .vop_inactive = gfs_vop_inactive,
649         .vop_reclaim =  zfsctl_common_reclaim,
650 #ifdef TODO
651         .vop_pathconf = zfsctl_pathconf,
652 #endif
653         .vop_fid =      zfsctl_common_fid,
654 };
655
656 /*
657  * Gets the full dataset name that corresponds to the given snapshot name
658  * Example:
659  *      zfsctl_snapshot_zname("snap1") -> "mypool/myfs@snap1"
660  */
661 static int
662 zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname)
663 {
664         objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os;
665
666         if (zfs_component_namecheck(name, NULL, NULL) != 0)
667                 return (SET_ERROR(EILSEQ));
668         dmu_objset_name(os, zname);
669         if (strlen(zname) + 1 + strlen(name) >= len)
670                 return (SET_ERROR(ENAMETOOLONG));
671         (void) strcat(zname, "@");
672         (void) strcat(zname, name);
673         return (0);
674 }
675
676 static int
677 zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr)
678 {
679         vnode_t *svp = sep->se_root;
680         int error;
681
682         ASSERT(vn_ismntpt(svp));
683
684         /* this will be dropped by dounmount() */
685         if ((error = vn_vfswlock(svp)) != 0)
686                 return (error);
687
688 #ifdef sun
689         VN_HOLD(svp);
690         error = dounmount(vn_mountedvfs(svp), fflags, cr);
691         if (error) {
692                 VN_RELE(svp);
693                 return (error);
694         }
695
696         /*
697          * We can't use VN_RELE(), as that will try to invoke
698          * zfsctl_snapdir_inactive(), which would cause us to destroy
699          * the sd_lock mutex held by our caller.
700          */
701         ASSERT(svp->v_count == 1);
702         gfs_vop_inactive(svp, cr, NULL);
703
704         kmem_free(sep->se_name, strlen(sep->se_name) + 1);
705         kmem_free(sep, sizeof (zfs_snapentry_t));
706
707         return (0);
708 #else   /* !sun */
709         return (dounmount(vn_mountedvfs(svp), fflags, curthread));
710 #endif  /* !sun */
711 }
712
713 #ifdef sun
714 static void
715 zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm)
716 {
717         avl_index_t where;
718         vfs_t *vfsp;
719         refstr_t *pathref;
720         char newpath[MAXNAMELEN];
721         char *tail;
722
723         ASSERT(MUTEX_HELD(&sdp->sd_lock));
724         ASSERT(sep != NULL);
725
726         vfsp = vn_mountedvfs(sep->se_root);
727         ASSERT(vfsp != NULL);
728
729         vfs_lock_wait(vfsp);
730
731         /*
732          * Change the name in the AVL tree.
733          */
734         avl_remove(&sdp->sd_snaps, sep);
735         kmem_free(sep->se_name, strlen(sep->se_name) + 1);
736         sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
737         (void) strcpy(sep->se_name, nm);
738         VERIFY(avl_find(&sdp->sd_snaps, sep, &where) == NULL);
739         avl_insert(&sdp->sd_snaps, sep, where);
740
741         /*
742          * Change the current mountpoint info:
743          *      - update the tail of the mntpoint path
744          *      - update the tail of the resource path
745          */
746         pathref = vfs_getmntpoint(vfsp);
747         (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath));
748         VERIFY((tail = strrchr(newpath, '/')) != NULL);
749         *(tail+1) = '\0';
750         ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath));
751         (void) strcat(newpath, nm);
752         refstr_rele(pathref);
753         vfs_setmntpoint(vfsp, newpath, 0);
754
755         pathref = vfs_getresource(vfsp);
756         (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath));
757         VERIFY((tail = strrchr(newpath, '@')) != NULL);
758         *(tail+1) = '\0';
759         ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath));
760         (void) strcat(newpath, nm);
761         refstr_rele(pathref);
762         vfs_setresource(vfsp, newpath, 0);
763
764         vfs_unlock(vfsp);
765 }
766 #endif  /* sun */
767
768 #ifdef sun
769 /*ARGSUSED*/
770 static int
771 zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
772     cred_t *cr, caller_context_t *ct, int flags)
773 {
774         zfsctl_snapdir_t *sdp = sdvp->v_data;
775         zfs_snapentry_t search, *sep;
776         zfsvfs_t *zfsvfs;
777         avl_index_t where;
778         char from[MAXNAMELEN], to[MAXNAMELEN];
779         char real[MAXNAMELEN], fsname[MAXNAMELEN];
780         int err;
781
782         zfsvfs = sdvp->v_vfsp->vfs_data;
783         ZFS_ENTER(zfsvfs);
784
785         if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
786                 err = dmu_snapshot_realname(zfsvfs->z_os, snm, real,
787                     MAXNAMELEN, NULL);
788                 if (err == 0) {
789                         snm = real;
790                 } else if (err != ENOTSUP) {
791                         ZFS_EXIT(zfsvfs);
792                         return (err);
793                 }
794         }
795
796         ZFS_EXIT(zfsvfs);
797
798         dmu_objset_name(zfsvfs->z_os, fsname);
799
800         err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from);
801         if (err == 0)
802                 err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to);
803         if (err == 0)
804                 err = zfs_secpolicy_rename_perms(from, to, cr);
805         if (err != 0)
806                 return (err);
807
808         /*
809          * Cannot move snapshots out of the snapdir.
810          */
811         if (sdvp != tdvp)
812                 return (SET_ERROR(EINVAL));
813
814         if (strcmp(snm, tnm) == 0)
815                 return (0);
816
817         mutex_enter(&sdp->sd_lock);
818
819         search.se_name = (char *)snm;
820         if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) == NULL) {
821                 mutex_exit(&sdp->sd_lock);
822                 return (SET_ERROR(ENOENT));
823         }
824
825         err = dsl_dataset_rename_snapshot(fsname, snm, tnm, 0);
826         if (err == 0)
827                 zfsctl_rename_snap(sdp, sep, tnm);
828
829         mutex_exit(&sdp->sd_lock);
830
831         return (err);
832 }
833 #endif  /* sun */
834
835 #ifdef sun
836 /* ARGSUSED */
837 static int
838 zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr,
839     caller_context_t *ct, int flags)
840 {
841         zfsctl_snapdir_t *sdp = dvp->v_data;
842         zfs_snapentry_t *sep;
843         zfs_snapentry_t search;
844         zfsvfs_t *zfsvfs;
845         char snapname[MAXNAMELEN];
846         char real[MAXNAMELEN];
847         int err;
848
849         zfsvfs = dvp->v_vfsp->vfs_data;
850         ZFS_ENTER(zfsvfs);
851
852         if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
853
854                 err = dmu_snapshot_realname(zfsvfs->z_os, name, real,
855                     MAXNAMELEN, NULL);
856                 if (err == 0) {
857                         name = real;
858                 } else if (err != ENOTSUP) {
859                         ZFS_EXIT(zfsvfs);
860                         return (err);
861                 }
862         }
863
864         ZFS_EXIT(zfsvfs);
865
866         err = zfsctl_snapshot_zname(dvp, name, MAXNAMELEN, snapname);
867         if (err == 0)
868                 err = zfs_secpolicy_destroy_perms(snapname, cr);
869         if (err != 0)
870                 return (err);
871
872         mutex_enter(&sdp->sd_lock);
873
874         search.se_name = name;
875         sep = avl_find(&sdp->sd_snaps, &search, NULL);
876         if (sep) {
877                 avl_remove(&sdp->sd_snaps, sep);
878                 err = zfsctl_unmount_snap(sep, MS_FORCE, cr);
879                 if (err != 0)
880                         avl_add(&sdp->sd_snaps, sep);
881                 else
882                         err = dsl_destroy_snapshot(snapname, B_FALSE);
883         } else {
884                 err = SET_ERROR(ENOENT);
885         }
886
887         mutex_exit(&sdp->sd_lock);
888
889         return (err);
890 }
891 #endif  /* sun */
892
893 /*
894  * This creates a snapshot under '.zfs/snapshot'.
895  */
896 /* ARGSUSED */
897 static int
898 zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t  **vpp,
899     cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
900 {
901         zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
902         char name[MAXNAMELEN];
903         int err;
904         static enum symfollow follow = NO_FOLLOW;
905         static enum uio_seg seg = UIO_SYSSPACE;
906
907         if (zfs_component_namecheck(dirname, NULL, NULL) != 0)
908                 return (SET_ERROR(EILSEQ));
909
910         dmu_objset_name(zfsvfs->z_os, name);
911
912         *vpp = NULL;
913
914         err = zfs_secpolicy_snapshot_perms(name, cr);
915         if (err != 0)
916                 return (err);
917
918         if (err == 0) {
919                 err = dmu_objset_snapshot_one(name, dirname);
920                 if (err != 0)
921                         return (err);
922                 err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
923         }
924
925         return (err);
926 }
927
928 static int
929 zfsctl_freebsd_snapdir_mkdir(ap)
930         struct vop_mkdir_args /* {
931                 struct vnode *a_dvp;
932                 struct vnode **a_vpp;
933                 struct componentname *a_cnp;
934                 struct vattr *a_vap;
935         } */ *ap;
936 {
937
938         ASSERT(ap->a_cnp->cn_flags & SAVENAME);
939
940         return (zfsctl_snapdir_mkdir(ap->a_dvp, ap->a_cnp->cn_nameptr, NULL,
941             ap->a_vpp, ap->a_cnp->cn_cred, NULL, 0, NULL));
942 }
943
944 /*
945  * Lookup entry point for the 'snapshot' directory.  Try to open the
946  * snapshot if it exist, creating the pseudo filesystem vnode as necessary.
947  * Perform a mount of the associated dataset on top of the vnode.
948  */
949 /* ARGSUSED */
950 int
951 zfsctl_snapdir_lookup(ap)
952         struct vop_lookup_args /* {
953                 struct vnode *a_dvp;
954                 struct vnode **a_vpp;
955                 struct componentname *a_cnp;
956         } */ *ap;
957 {
958         vnode_t *dvp = ap->a_dvp;
959         vnode_t **vpp = ap->a_vpp;
960         struct componentname *cnp = ap->a_cnp;
961         char nm[NAME_MAX + 1];
962         zfsctl_snapdir_t *sdp = dvp->v_data;
963         objset_t *snap;
964         char snapname[MAXNAMELEN];
965         char real[MAXNAMELEN];
966         char *mountpoint;
967         zfs_snapentry_t *sep, search;
968         size_t mountpoint_len;
969         avl_index_t where;
970         zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
971         int err;
972         int flags = 0;
973
974         /*
975          * No extended attributes allowed under .zfs
976          */
977         if (flags & LOOKUP_XATTR)
978                 return (SET_ERROR(EINVAL));
979         ASSERT(ap->a_cnp->cn_namelen < sizeof(nm));
980         strlcpy(nm, ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen + 1);
981
982         ASSERT(dvp->v_type == VDIR);
983
984         *vpp = NULL;
985
986         /*
987          * If we get a recursive call, that means we got called
988          * from the domount() code while it was trying to look up the
989          * spec (which looks like a local path for zfs).  We need to
990          * add some flag to domount() to tell it not to do this lookup.
991          */
992         if (MUTEX_HELD(&sdp->sd_lock))
993                 return (SET_ERROR(ENOENT));
994
995         ZFS_ENTER(zfsvfs);
996
997         if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) {
998                 if (nm[0] == '.' && nm[1] == '.' && nm[2] =='\0') {
999                         VOP_UNLOCK(dvp, 0);
1000                         VERIFY0(vn_lock(*vpp, LK_EXCLUSIVE));
1001                         VERIFY0(vn_lock(dvp, LK_EXCLUSIVE));
1002                 }
1003                 ZFS_EXIT(zfsvfs);
1004                 return (0);
1005         }
1006
1007         if (flags & FIGNORECASE) {
1008                 boolean_t conflict = B_FALSE;
1009
1010                 err = dmu_snapshot_realname(zfsvfs->z_os, nm, real,
1011                     MAXNAMELEN, &conflict);
1012                 if (err == 0) {
1013                         strlcpy(nm, real, sizeof(nm));
1014                 } else if (err != ENOTSUP) {
1015                         ZFS_EXIT(zfsvfs);
1016                         return (err);
1017                 }
1018 #if 0
1019                 if (realpnp)
1020                         (void) strlcpy(realpnp->pn_buf, nm,
1021                             realpnp->pn_bufsize);
1022                 if (conflict && direntflags)
1023                         *direntflags = ED_CASE_CONFLICT;
1024 #endif
1025         }
1026
1027 relookup:
1028         mutex_enter(&sdp->sd_lock);
1029         search.se_name = (char *)nm;
1030         if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) {
1031                 *vpp = sep->se_root;
1032                 VN_HOLD(*vpp);
1033                 err = traverse(vpp, LK_EXCLUSIVE | LK_RETRY);
1034                 if (err != 0) {
1035                         *vpp = NULL;
1036                 } else if (*vpp == sep->se_root) {
1037                         /*
1038                          * The snapshot was unmounted behind our backs,
1039                          * try to remount it.
1040                          */
1041                         VERIFY(zfsctl_snapshot_zname(dvp, nm, MAXNAMELEN, snapname) == 0);
1042                         goto domount;
1043                 }
1044                 mutex_exit(&sdp->sd_lock);
1045                 ZFS_EXIT(zfsvfs);
1046                 return (err);
1047         }
1048
1049         /*
1050          * The requested snapshot is not currently mounted, look it up.
1051          */
1052         err = zfsctl_snapshot_zname(dvp, nm, MAXNAMELEN, snapname);
1053         if (err != 0) {
1054                 mutex_exit(&sdp->sd_lock);
1055                 ZFS_EXIT(zfsvfs);
1056                 /*
1057                  * handle "ls *" or "?" in a graceful manner,
1058                  * forcing EILSEQ to ENOENT.
1059                  * Since shell ultimately passes "*" or "?" as name to lookup
1060                  */
1061                 return (err == EILSEQ ? ENOENT : err);
1062         }
1063         if (dmu_objset_hold(snapname, FTAG, &snap) != 0) {
1064                 mutex_exit(&sdp->sd_lock);
1065 #ifdef illumos
1066                 ZFS_EXIT(zfsvfs);
1067                 return (SET_ERROR(ENOENT));
1068 #else   /* !illumos */
1069                 /* Translate errors and add SAVENAME when needed. */
1070                 if ((cnp->cn_flags & ISLASTCN) && cnp->cn_nameiop == CREATE) {
1071                         err = EJUSTRETURN;
1072                         cnp->cn_flags |= SAVENAME;
1073                 } else {
1074                         err = SET_ERROR(ENOENT);
1075                 }
1076                 ZFS_EXIT(zfsvfs);
1077                 return (err);
1078 #endif  /* !illumos */
1079         }
1080
1081         sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP);
1082         sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
1083         (void) strcpy(sep->se_name, nm);
1084         *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
1085         avl_insert(&sdp->sd_snaps, sep, where);
1086
1087         dmu_objset_rele(snap, FTAG);
1088 domount:
1089         mountpoint_len = strlen(dvp->v_vfsp->mnt_stat.f_mntonname) +
1090             strlen("/" ZFS_CTLDIR_NAME "/snapshot/") + strlen(nm) + 1;
1091         mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
1092         (void) snprintf(mountpoint, mountpoint_len,
1093             "%s/" ZFS_CTLDIR_NAME "/snapshot/%s",
1094             dvp->v_vfsp->mnt_stat.f_mntonname, nm);
1095         mutex_exit(&sdp->sd_lock);
1096
1097         /*
1098          * The vnode may get reclaimed between dropping sd_lock and
1099          * getting the vnode lock.
1100          * */
1101         err = vn_lock(*vpp, LK_EXCLUSIVE);
1102         if (err == ENOENT)
1103                 goto relookup;
1104         VERIFY0(err);
1105         err = mount_snapshot(curthread, vpp, "zfs", mountpoint, snapname, 0);
1106         kmem_free(mountpoint, mountpoint_len);
1107         if (err == 0) {
1108                 /*
1109                  * Fix up the root vnode mounted on .zfs/snapshot/<snapname>.
1110                  *
1111                  * This is where we lie about our v_vfsp in order to
1112                  * make .zfs/snapshot/<snapname> accessible over NFS
1113                  * without requiring manual mounts of <snapname>.
1114                  */
1115                 ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs);
1116                 VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs;
1117         }
1118         ZFS_EXIT(zfsvfs);
1119
1120 #ifdef illumos
1121         /*
1122          * If we had an error, drop our hold on the vnode and
1123          * zfsctl_snapshot_inactive() will clean up.
1124          */
1125         if (err != 0) {
1126                 VN_RELE(*vpp);
1127                 *vpp = NULL;
1128         }
1129 #else
1130         if (err != 0)
1131                 *vpp = NULL;
1132 #endif
1133         return (err);
1134 }
1135
1136 /* ARGSUSED */
1137 int
1138 zfsctl_shares_lookup(ap)
1139         struct vop_lookup_args /* {
1140                 struct vnode *a_dvp;
1141                 struct vnode **a_vpp;
1142                 struct componentname *a_cnp;
1143         } */ *ap;
1144 {
1145         vnode_t *dvp = ap->a_dvp;
1146         vnode_t **vpp = ap->a_vpp;
1147         struct componentname *cnp = ap->a_cnp;
1148         zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
1149         char nm[NAME_MAX + 1];
1150         znode_t *dzp;
1151         int error;
1152
1153         ZFS_ENTER(zfsvfs);
1154
1155         ASSERT(cnp->cn_namelen < sizeof(nm));
1156         strlcpy(nm, cnp->cn_nameptr, cnp->cn_namelen + 1);
1157
1158         if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) {
1159                 if (nm[0] == '.' && nm[1] == '.' && nm[2] =='\0') {
1160                         VOP_UNLOCK(dvp, 0);
1161                         VERIFY0(vn_lock(*vpp, LK_EXCLUSIVE));
1162                         VERIFY0(vn_lock(dvp, LK_EXCLUSIVE));
1163                 }
1164                 ZFS_EXIT(zfsvfs);
1165                 return (0);
1166         }
1167
1168         if (zfsvfs->z_shares_dir == 0) {
1169                 ZFS_EXIT(zfsvfs);
1170                 return (SET_ERROR(ENOTSUP));
1171         }
1172         if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0)
1173                 error = VOP_LOOKUP(ZTOV(dzp), vpp, cnp);
1174
1175         VN_RELE(ZTOV(dzp));
1176         ZFS_EXIT(zfsvfs);
1177
1178         return (error);
1179 }
1180
1181 /* ARGSUSED */
1182 static int
1183 zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp,
1184     offset_t *offp, offset_t *nextp, void *data, int flags)
1185 {
1186         zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
1187         char snapname[MAXNAMELEN];
1188         uint64_t id, cookie;
1189         boolean_t case_conflict;
1190         int error;
1191
1192         ZFS_ENTER(zfsvfs);
1193
1194         cookie = *offp;
1195         dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
1196         error = dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, snapname, &id,
1197             &cookie, &case_conflict);
1198         dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
1199         if (error) {
1200                 ZFS_EXIT(zfsvfs);
1201                 if (error == ENOENT) {
1202                         *eofp = 1;
1203                         return (0);
1204                 }
1205                 return (error);
1206         }
1207
1208         if (flags & V_RDDIR_ENTFLAGS) {
1209                 edirent_t *eodp = dp;
1210
1211                 (void) strcpy(eodp->ed_name, snapname);
1212                 eodp->ed_ino = ZFSCTL_INO_SNAP(id);
1213                 eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0;
1214         } else {
1215                 struct dirent64 *odp = dp;
1216
1217                 (void) strcpy(odp->d_name, snapname);
1218                 odp->d_ino = ZFSCTL_INO_SNAP(id);
1219         }
1220         *nextp = cookie;
1221
1222         ZFS_EXIT(zfsvfs);
1223
1224         return (0);
1225 }
1226
1227 /* ARGSUSED */
1228 static int
1229 zfsctl_shares_readdir(ap)
1230         struct vop_readdir_args /* {
1231                 struct vnode *a_vp;
1232                 struct uio *a_uio;
1233                 struct ucred *a_cred;
1234                 int *a_eofflag;
1235                 int *a_ncookies;
1236                 u_long **a_cookies;
1237         } */ *ap;
1238 {
1239         vnode_t *vp = ap->a_vp;
1240         uio_t *uiop = ap->a_uio;
1241         cred_t *cr = ap->a_cred;
1242         int *eofp = ap->a_eofflag;
1243         zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
1244         znode_t *dzp;
1245         int error;
1246
1247         ZFS_ENTER(zfsvfs);
1248
1249         if (zfsvfs->z_shares_dir == 0) {
1250                 ZFS_EXIT(zfsvfs);
1251                 return (SET_ERROR(ENOTSUP));
1252         }
1253         if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
1254                 vn_lock(ZTOV(dzp), LK_SHARED | LK_RETRY);
1255                 error = VOP_READDIR(ZTOV(dzp), uiop, cr, eofp, ap->a_ncookies, ap->a_cookies);
1256                 VN_URELE(ZTOV(dzp));
1257         } else {
1258                 *eofp = 1;
1259                 error = SET_ERROR(ENOENT);
1260         }
1261
1262         ZFS_EXIT(zfsvfs);
1263         return (error);
1264 }
1265
1266 /*
1267  * pvp is the '.zfs' directory (zfsctl_node_t).
1268  *
1269  * Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t).
1270  *
1271  * This function is the callback to create a GFS vnode for '.zfs/snapshot'
1272  * when a lookup is performed on .zfs for "snapshot".
1273  */
1274 vnode_t *
1275 zfsctl_mknode_snapdir(vnode_t *pvp)
1276 {
1277         vnode_t *vp;
1278         zfsctl_snapdir_t *sdp;
1279
1280         vp = gfs_dir_create(sizeof (zfsctl_snapdir_t), pvp, pvp->v_vfsp,
1281             &zfsctl_ops_snapdir, NULL, NULL, MAXNAMELEN,
1282             zfsctl_snapdir_readdir_cb, NULL);
1283         sdp = vp->v_data;
1284         sdp->sd_node.zc_id = ZFSCTL_INO_SNAPDIR;
1285         sdp->sd_node.zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime;
1286         mutex_init(&sdp->sd_lock, NULL, MUTEX_DEFAULT, NULL);
1287         avl_create(&sdp->sd_snaps, snapentry_compare,
1288             sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node));
1289         VOP_UNLOCK(vp, 0);
1290         return (vp);
1291 }
1292
1293 vnode_t *
1294 zfsctl_mknode_shares(vnode_t *pvp)
1295 {
1296         vnode_t *vp;
1297         zfsctl_node_t *sdp;
1298
1299         vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, pvp->v_vfsp,
1300             &zfsctl_ops_shares, NULL, NULL, MAXNAMELEN,
1301             NULL, NULL);
1302         sdp = vp->v_data;
1303         sdp->zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime;
1304         VOP_UNLOCK(vp, 0);
1305         return (vp);
1306
1307 }
1308
1309 /* ARGSUSED */
1310 static int
1311 zfsctl_shares_getattr(ap)
1312         struct vop_getattr_args /* {
1313                 struct vnode *a_vp;
1314                 struct vattr *a_vap;
1315                 struct ucred *a_cred;
1316                 struct thread *a_td;
1317         } */ *ap;
1318 {
1319         vnode_t *vp = ap->a_vp;
1320         vattr_t *vap = ap->a_vap;
1321         cred_t *cr = ap->a_cred;
1322         zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
1323         znode_t *dzp;
1324         int error;
1325
1326         ZFS_ENTER(zfsvfs);
1327         if (zfsvfs->z_shares_dir == 0) {
1328                 ZFS_EXIT(zfsvfs);
1329                 return (SET_ERROR(ENOTSUP));
1330         }
1331         if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
1332                 vn_lock(ZTOV(dzp), LK_SHARED | LK_RETRY);
1333                 error = VOP_GETATTR(ZTOV(dzp), vap, cr);
1334                 VN_URELE(ZTOV(dzp));
1335         }
1336         ZFS_EXIT(zfsvfs);
1337         return (error);
1338
1339
1340 }
1341
1342 /* ARGSUSED */
1343 static int
1344 zfsctl_snapdir_getattr(ap)
1345         struct vop_getattr_args /* {
1346                 struct vnode *a_vp;
1347                 struct vattr *a_vap;
1348                 struct ucred *a_cred;
1349         } */ *ap;
1350 {
1351         vnode_t *vp = ap->a_vp;
1352         vattr_t *vap = ap->a_vap;
1353         zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
1354         zfsctl_snapdir_t *sdp = vp->v_data;
1355
1356         ZFS_ENTER(zfsvfs);
1357         zfsctl_common_getattr(vp, vap);
1358         vap->va_nodeid = gfs_file_inode(vp);
1359         vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2;
1360         vap->va_ctime = vap->va_mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
1361         vap->va_birthtime = vap->va_ctime;
1362         ZFS_EXIT(zfsvfs);
1363
1364         return (0);
1365 }
1366
1367 /* ARGSUSED */
1368 static int
1369 zfsctl_snapdir_inactive(ap)
1370         struct vop_inactive_args /* {
1371                 struct vnode *a_vp;
1372                 struct thread *a_td;
1373         } */ *ap;
1374 {
1375         vnode_t *vp = ap->a_vp;
1376         zfsctl_snapdir_t *sdp = vp->v_data;
1377         zfs_snapentry_t *sep;
1378
1379         /*
1380          * On forced unmount we have to free snapshots from here.
1381          */
1382         mutex_enter(&sdp->sd_lock);
1383         while ((sep = avl_first(&sdp->sd_snaps)) != NULL) {
1384                 avl_remove(&sdp->sd_snaps, sep);
1385                 kmem_free(sep->se_name, strlen(sep->se_name) + 1);
1386                 kmem_free(sep, sizeof (zfs_snapentry_t));
1387         }
1388         mutex_exit(&sdp->sd_lock);
1389         gfs_dir_inactive(vp);
1390         ASSERT(avl_numnodes(&sdp->sd_snaps) == 0);
1391         mutex_destroy(&sdp->sd_lock);
1392         avl_destroy(&sdp->sd_snaps);
1393         kmem_free(sdp, sizeof (zfsctl_snapdir_t));
1394
1395         return (0);
1396 }
1397
1398 #ifdef sun
1399 static const fs_operation_def_t zfsctl_tops_snapdir[] = {
1400         { VOPNAME_OPEN,         { .vop_open = zfsctl_common_open }      },
1401         { VOPNAME_CLOSE,        { .vop_close = zfsctl_common_close }    },
1402         { VOPNAME_IOCTL,        { .error = fs_inval }                   },
1403         { VOPNAME_GETATTR,      { .vop_getattr = zfsctl_snapdir_getattr } },
1404         { VOPNAME_ACCESS,       { .vop_access = zfsctl_common_access }  },
1405         { VOPNAME_RENAME,       { .vop_rename = zfsctl_snapdir_rename } },
1406         { VOPNAME_RMDIR,        { .vop_rmdir = zfsctl_snapdir_remove }  },
1407         { VOPNAME_MKDIR,        { .vop_mkdir = zfsctl_snapdir_mkdir }   },
1408         { VOPNAME_READDIR,      { .vop_readdir = gfs_vop_readdir }      },
1409         { VOPNAME_LOOKUP,       { .vop_lookup = zfsctl_snapdir_lookup } },
1410         { VOPNAME_SEEK,         { .vop_seek = fs_seek }                 },
1411         { VOPNAME_INACTIVE,     { .vop_inactive = zfsctl_snapdir_inactive } },
1412         { VOPNAME_FID,          { .vop_fid = zfsctl_common_fid }        },
1413         { NULL }
1414 };
1415
1416 static const fs_operation_def_t zfsctl_tops_shares[] = {
1417         { VOPNAME_OPEN,         { .vop_open = zfsctl_common_open }      },
1418         { VOPNAME_CLOSE,        { .vop_close = zfsctl_common_close }    },
1419         { VOPNAME_IOCTL,        { .error = fs_inval }                   },
1420         { VOPNAME_GETATTR,      { .vop_getattr = zfsctl_shares_getattr } },
1421         { VOPNAME_ACCESS,       { .vop_access = zfsctl_common_access }  },
1422         { VOPNAME_READDIR,      { .vop_readdir = zfsctl_shares_readdir } },
1423         { VOPNAME_LOOKUP,       { .vop_lookup = zfsctl_shares_lookup }  },
1424         { VOPNAME_SEEK,         { .vop_seek = fs_seek }                 },
1425         { VOPNAME_INACTIVE,     { .vop_inactive = gfs_vop_inactive } },
1426         { VOPNAME_FID,          { .vop_fid = zfsctl_shares_fid } },
1427         { NULL }
1428 };
1429 #else   /* !sun */
1430 static struct vop_vector zfsctl_ops_snapdir = {
1431         .vop_default =  &default_vnodeops,
1432         .vop_open =     zfsctl_common_open,
1433         .vop_close =    zfsctl_common_close,
1434         .vop_ioctl =    VOP_EINVAL,
1435         .vop_getattr =  zfsctl_snapdir_getattr,
1436         .vop_access =   zfsctl_common_access,
1437         .vop_mkdir =    zfsctl_freebsd_snapdir_mkdir,
1438         .vop_readdir =  gfs_vop_readdir,
1439         .vop_lookup =   zfsctl_snapdir_lookup,
1440         .vop_inactive = zfsctl_snapdir_inactive,
1441         .vop_reclaim =  zfsctl_common_reclaim,
1442         .vop_fid =      zfsctl_common_fid,
1443 };
1444
1445 static struct vop_vector zfsctl_ops_shares = {
1446         .vop_default =  &default_vnodeops,
1447         .vop_open =     zfsctl_common_open,
1448         .vop_close =    zfsctl_common_close,
1449         .vop_ioctl =    VOP_EINVAL,
1450         .vop_getattr =  zfsctl_shares_getattr,
1451         .vop_access =   zfsctl_common_access,
1452         .vop_readdir =  zfsctl_shares_readdir,
1453         .vop_lookup =   zfsctl_shares_lookup,
1454         .vop_inactive = gfs_vop_inactive,
1455         .vop_reclaim =  zfsctl_common_reclaim,
1456         .vop_fid =      zfsctl_shares_fid,
1457 };
1458 #endif  /* !sun */
1459
1460 /*
1461  * pvp is the GFS vnode '.zfs/snapshot'.
1462  *
1463  * This creates a GFS node under '.zfs/snapshot' representing each
1464  * snapshot.  This newly created GFS node is what we mount snapshot
1465  * vfs_t's ontop of.
1466  */
1467 static vnode_t *
1468 zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset)
1469 {
1470         vnode_t *vp;
1471         zfsctl_node_t *zcp;
1472
1473         vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, pvp->v_vfsp,
1474             &zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL);
1475         zcp = vp->v_data;
1476         zcp->zc_id = objset;
1477         VOP_UNLOCK(vp, 0);
1478
1479         return (vp);
1480 }
1481
1482 static int
1483 zfsctl_snapshot_inactive(ap)
1484         struct vop_inactive_args /* {
1485                 struct vnode *a_vp;
1486                 struct thread *a_td;
1487         } */ *ap;
1488 {
1489         vnode_t *vp = ap->a_vp;
1490         cred_t *cr = ap->a_td->td_ucred;
1491         struct vop_inactive_args iap;
1492         zfsctl_snapdir_t *sdp;
1493         zfs_snapentry_t *sep, *next;
1494         int locked;
1495         vnode_t *dvp;
1496
1497         if (vp->v_count > 0)
1498                 goto end;
1499
1500         VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0);
1501         sdp = dvp->v_data;
1502
1503         if (!(locked = MUTEX_HELD(&sdp->sd_lock)))
1504                 mutex_enter(&sdp->sd_lock);
1505
1506         ASSERT(!vn_ismntpt(vp));
1507
1508         sep = avl_first(&sdp->sd_snaps);
1509         while (sep != NULL) {
1510                 next = AVL_NEXT(&sdp->sd_snaps, sep);
1511
1512                 if (sep->se_root == vp) {
1513                         avl_remove(&sdp->sd_snaps, sep);
1514                         kmem_free(sep->se_name, strlen(sep->se_name) + 1);
1515                         kmem_free(sep, sizeof (zfs_snapentry_t));
1516                         break;
1517                 }
1518                 sep = next;
1519         }
1520         ASSERT(sep != NULL);
1521
1522         if (!locked)
1523                 mutex_exit(&sdp->sd_lock);
1524         VN_RELE(dvp);
1525
1526 end:
1527         /*
1528          * Dispose of the vnode for the snapshot mount point.
1529          * This is safe to do because once this entry has been removed
1530          * from the AVL tree, it can't be found again, so cannot become
1531          * "active".  If we lookup the same name again we will end up
1532          * creating a new vnode.
1533          */
1534         iap.a_vp = vp;
1535         return (gfs_vop_inactive(&iap));
1536 }
1537
1538 static int
1539 zfsctl_snapshot_vptocnp(struct vop_vptocnp_args *ap)
1540 {
1541         zfsvfs_t *zfsvfs = ap->a_vp->v_vfsp->vfs_data;
1542         vnode_t *dvp, *vp;
1543         zfsctl_snapdir_t *sdp;
1544         zfs_snapentry_t *sep;
1545         int error;
1546
1547         ASSERT(zfsvfs->z_ctldir != NULL);
1548         error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
1549             NULL, 0, NULL, kcred, NULL, NULL, NULL);
1550         if (error != 0)
1551                 return (error);
1552         sdp = dvp->v_data;
1553
1554         mutex_enter(&sdp->sd_lock);
1555         sep = avl_first(&sdp->sd_snaps);
1556         while (sep != NULL) {
1557                 vp = sep->se_root;
1558                 if (vp == ap->a_vp)
1559                         break;
1560                 sep = AVL_NEXT(&sdp->sd_snaps, sep);
1561         }
1562         if (sep == NULL) {
1563                 mutex_exit(&sdp->sd_lock);
1564                 error = ENOENT;
1565         } else {
1566                 size_t len;
1567
1568                 len = strlen(sep->se_name);
1569                 *ap->a_buflen -= len;
1570                 bcopy(sep->se_name, ap->a_buf + *ap->a_buflen, len);
1571                 mutex_exit(&sdp->sd_lock);
1572                 vref(dvp);
1573                 *ap->a_vpp = dvp;
1574         }
1575         VN_RELE(dvp);
1576
1577         return (error);
1578 }
1579
1580 /*
1581  * These VP's should never see the light of day.  They should always
1582  * be covered.
1583  */
1584 static struct vop_vector zfsctl_ops_snapshot = {
1585         .vop_default =  &default_vnodeops,
1586         .vop_inactive = zfsctl_snapshot_inactive,
1587         .vop_reclaim =  zfsctl_common_reclaim,
1588         .vop_vptocnp =  zfsctl_snapshot_vptocnp,
1589 };
1590
1591 int
1592 zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp)
1593 {
1594         zfsvfs_t *zfsvfs = vfsp->vfs_data;
1595         vnode_t *dvp, *vp;
1596         zfsctl_snapdir_t *sdp;
1597         zfsctl_node_t *zcp;
1598         zfs_snapentry_t *sep;
1599         int error;
1600
1601         ASSERT(zfsvfs->z_ctldir != NULL);
1602         error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
1603             NULL, 0, NULL, kcred, NULL, NULL, NULL);
1604         if (error != 0)
1605                 return (error);
1606         sdp = dvp->v_data;
1607
1608         mutex_enter(&sdp->sd_lock);
1609         sep = avl_first(&sdp->sd_snaps);
1610         while (sep != NULL) {
1611                 vp = sep->se_root;
1612                 zcp = vp->v_data;
1613                 if (zcp->zc_id == objsetid)
1614                         break;
1615
1616                 sep = AVL_NEXT(&sdp->sd_snaps, sep);
1617         }
1618
1619         if (sep != NULL) {
1620                 VN_HOLD(vp);
1621                 /*
1622                  * Return the mounted root rather than the covered mount point.
1623                  * Takes the GFS vnode at .zfs/snapshot/<snapshot objsetid>
1624                  * and returns the ZFS vnode mounted on top of the GFS node.
1625                  * This ZFS vnode is the root of the vfs for objset 'objsetid'.
1626                  */
1627                 error = traverse(&vp, LK_SHARED | LK_RETRY);
1628                 if (error == 0) {
1629                         if (vp == sep->se_root) {
1630                                 VN_RELE(vp);    /* release covered vp */
1631                                 error = SET_ERROR(EINVAL);
1632                         } else {
1633                                 *zfsvfsp = VTOZ(vp)->z_zfsvfs;
1634                                 VN_URELE(vp);   /* put snapshot's root vp */
1635                         }
1636                 }
1637                 mutex_exit(&sdp->sd_lock);
1638         } else {
1639                 error = SET_ERROR(EINVAL);
1640                 mutex_exit(&sdp->sd_lock);
1641         }
1642
1643         VN_RELE(dvp);
1644
1645         return (error);
1646 }
1647
1648 /*
1649  * Unmount any snapshots for the given filesystem.  This is called from
1650  * zfs_umount() - if we have a ctldir, then go through and unmount all the
1651  * snapshots.
1652  */
1653 int
1654 zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr)
1655 {
1656         zfsvfs_t *zfsvfs = vfsp->vfs_data;
1657         vnode_t *dvp;
1658         zfsctl_snapdir_t *sdp;
1659         zfs_snapentry_t *sep, *next;
1660         int error;
1661
1662         ASSERT(zfsvfs->z_ctldir != NULL);
1663         error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
1664             NULL, 0, NULL, cr, NULL, NULL, NULL);
1665         if (error != 0)
1666                 return (error);
1667         sdp = dvp->v_data;
1668
1669         mutex_enter(&sdp->sd_lock);
1670
1671         sep = avl_first(&sdp->sd_snaps);
1672         while (sep != NULL) {
1673                 next = AVL_NEXT(&sdp->sd_snaps, sep);
1674
1675                 /*
1676                  * If this snapshot is not mounted, then it must
1677                  * have just been unmounted by somebody else, and
1678                  * will be cleaned up by zfsctl_snapdir_inactive().
1679                  */
1680                 if (vn_ismntpt(sep->se_root)) {
1681                         error = zfsctl_unmount_snap(sep, fflags, cr);
1682                         if (error) {
1683                                 avl_index_t where;
1684
1685                                 /*
1686                                  * Before reinserting snapshot to the tree,
1687                                  * check if it was actually removed. For example
1688                                  * when snapshot mount point is busy, we will
1689                                  * have an error here, but there will be no need
1690                                  * to reinsert snapshot.
1691                                  */
1692                                 if (avl_find(&sdp->sd_snaps, sep, &where) == NULL)
1693                                         avl_insert(&sdp->sd_snaps, sep, where);
1694                                 break;
1695                         }
1696                 }
1697                 sep = next;
1698         }
1699
1700         mutex_exit(&sdp->sd_lock);
1701         VN_RELE(dvp);
1702
1703         return (error);
1704 }