Home | History | Annotate | Download | only in zfs
      1    789    ahrens /*
      2    789    ahrens  * CDDL HEADER START
      3    789    ahrens  *
      4    789    ahrens  * The contents of this file are subject to the terms of the
      5   1512  ek110237  * Common Development and Distribution License (the "License").
      6   1512  ek110237  * You may not use this file except in compliance with the License.
      7    789    ahrens  *
      8    789    ahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9    789    ahrens  * or http://www.opensolaris.org/os/licensing.
     10    789    ahrens  * See the License for the specific language governing permissions
     11    789    ahrens  * and limitations under the License.
     12    789    ahrens  *
     13    789    ahrens  * When distributing Covered Code, include this CDDL HEADER in each
     14    789    ahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15    789    ahrens  * If applicable, add the following below this CDDL HEADER, with the
     16    789    ahrens  * fields enclosed by brackets "[]" replaced with your own identifying
     17    789    ahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
     18    789    ahrens  *
     19    789    ahrens  * CDDL HEADER END
     20    789    ahrens  */
     21    789    ahrens /*
     22   8547      Mark  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23    789    ahrens  * Use is subject to license terms.
     24    789    ahrens  */
     25    789    ahrens 
     26    789    ahrens /*
     27    789    ahrens  * ZFS control directory (a.k.a. ".zfs")
     28    789    ahrens  *
     29    789    ahrens  * This directory provides a common location for all ZFS meta-objects.
     30    789    ahrens  * Currently, this is only the 'snapshot' directory, but this may expand in the
     31    789    ahrens  * future.  The elements are built using the GFS primitives, as the hierarchy
     32    789    ahrens  * does not actually exist on disk.
     33    789    ahrens  *
     34    789    ahrens  * For 'snapshot', we don't want to have all snapshots always mounted, because
     35    789    ahrens  * this would take up a huge amount of space in /etc/mnttab.  We have three
     36    789    ahrens  * types of objects:
     37    789    ahrens  *
     38    789    ahrens  * 	ctldir ------> snapshotdir -------> snapshot
     39    789    ahrens  *                                             |
     40    789    ahrens  *                                             |
     41    789    ahrens  *                                             V
     42    789    ahrens  *                                         mounted fs
     43    789    ahrens  *
     44    789    ahrens  * The 'snapshot' node contains just enough information to lookup '..' and act
     45    789    ahrens  * as a mountpoint for the snapshot.  Whenever we lookup a specific snapshot, we
     46    789    ahrens  * perform an automount of the underlying filesystem and return the
     47    789    ahrens  * corresponding vnode.
     48    789    ahrens  *
     49    789    ahrens  * All mounts are handled automatically by the kernel, but unmounts are
     50    789    ahrens  * (currently) handled from user land.  The main reason is that there is no
     51    789    ahrens  * reliable way to auto-unmount the filesystem when it's "no longer in use".
     52    789    ahrens  * When the user unmounts a filesystem, we call zfsctl_unmount(), which
     53    789    ahrens  * unmounts any snapshots within the snapshot directory.
     54   5326  ek110237  *
     55   5326  ek110237  * The '.zfs', '.zfs/snapshot', and all directories created under
     56   5326  ek110237  * '.zfs/snapshot' (ie: '.zfs/snapshot/<snapname>') are all GFS nodes and
     57   5326  ek110237  * share the same vfs_t as the head filesystem (what '.zfs' lives under).
     58   5326  ek110237  *
     59   5326  ek110237  * File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>'
     60   5326  ek110237  * (ie: snapshots) are ZFS nodes and have their own unique vfs_t.
     61   5326  ek110237  * However, vnodes within these mounted on file systems have their v_vfsp
     62   5326  ek110237  * fields set to the head filesystem to make NFS happy (see
     63   6068  ck153898  * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t
     64   6068  ck153898  * so that it cannot be freed until all snapshots have been unmounted.
     65    789    ahrens  */
     66    789    ahrens 
     67    789    ahrens #include <fs/fs_subr.h>
     68    789    ahrens #include <sys/zfs_ctldir.h>
     69    789    ahrens #include <sys/zfs_ioctl.h>
     70    789    ahrens #include <sys/zfs_vfsops.h>
     71   3898       rsb #include <sys/vfs_opreg.h>
     72    789    ahrens #include <sys/gfs.h>
     73    789    ahrens #include <sys/stat.h>
     74    789    ahrens #include <sys/dmu.h>
     75   4543     marks #include <sys/dsl_deleg.h>
     76    789    ahrens #include <sys/mount.h>
     77   6492      timh #include <sys/sunddi.h>
     78   6658     marks 
     79   6658     marks #include "zfs_namecheck.h"
     80   6068  ck153898 
     81   6068  ck153898 typedef struct zfsctl_node {
     82   6068  ck153898 	gfs_dir_t	zc_gfs_private;
     83   6068  ck153898 	uint64_t	zc_id;
     84   6068  ck153898 	timestruc_t	zc_cmtime;	/* ctime and mtime, always the same */
     85   6068  ck153898 } zfsctl_node_t;
     86   6068  ck153898 
     87   6068  ck153898 typedef struct zfsctl_snapdir {
     88   6068  ck153898 	zfsctl_node_t	sd_node;
     89   6068  ck153898 	kmutex_t	sd_lock;
     90   6068  ck153898 	avl_tree_t	sd_snaps;
     91   6068  ck153898 } zfsctl_snapdir_t;
     92    789    ahrens 
     93    789    ahrens typedef struct {
     94    789    ahrens 	char		*se_name;
     95    789    ahrens 	vnode_t		*se_root;
     96    789    ahrens 	avl_node_t	se_node;
     97    789    ahrens } zfs_snapentry_t;
     98    789    ahrens 
     99    789    ahrens static int
    100    789    ahrens snapentry_compare(const void *a, const void *b)
    101    789    ahrens {
    102    789    ahrens 	const zfs_snapentry_t *sa = a;
    103    789    ahrens 	const zfs_snapentry_t *sb = b;
    104    789    ahrens 	int ret = strcmp(sa->se_name, sb->se_name);
    105    789    ahrens 
    106    789    ahrens 	if (ret < 0)
    107    789    ahrens 		return (-1);
    108    789    ahrens 	else if (ret > 0)
    109    789    ahrens 		return (1);
    110    789    ahrens 	else
    111    789    ahrens 		return (0);
    112    789    ahrens }
    113    789    ahrens 
    114    789    ahrens vnodeops_t *zfsctl_ops_root;
    115    789    ahrens vnodeops_t *zfsctl_ops_snapdir;
    116    789    ahrens vnodeops_t *zfsctl_ops_snapshot;
    117   8845       amw vnodeops_t *zfsctl_ops_shares;
    118   8845       amw vnodeops_t *zfsctl_ops_shares_dir;
    119    789    ahrens 
    120    789    ahrens static const fs_operation_def_t zfsctl_tops_root[];
    121    789    ahrens static const fs_operation_def_t zfsctl_tops_snapdir[];
    122    789    ahrens static const fs_operation_def_t zfsctl_tops_snapshot[];
    123   8845       amw static const fs_operation_def_t zfsctl_tops_shares[];
    124    789    ahrens 
    125    789    ahrens static vnode_t *zfsctl_mknode_snapdir(vnode_t *);
    126   8845       amw static vnode_t *zfsctl_mknode_shares(vnode_t *);
    127    789    ahrens static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset);
    128   6068  ck153898 static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *);
    129    789    ahrens 
    130    789    ahrens static gfs_opsvec_t zfsctl_opsvec[] = {
    131    789    ahrens 	{ ".zfs", zfsctl_tops_root, &zfsctl_ops_root },
    132    789    ahrens 	{ ".zfs/snapshot", zfsctl_tops_snapdir, &zfsctl_ops_snapdir },
    133    789    ahrens 	{ ".zfs/snapshot/vnode", zfsctl_tops_snapshot, &zfsctl_ops_snapshot },
    134   8845       amw 	{ ".zfs/shares", zfsctl_tops_shares, &zfsctl_ops_shares_dir },
    135   8845       amw 	{ ".zfs/shares/vnode", zfsctl_tops_shares, &zfsctl_ops_shares },
    136    789    ahrens 	{ NULL }
    137    789    ahrens };
    138    789    ahrens 
    139    789    ahrens /*
    140   8845       amw  * Root directory elements.  We only have two entries
    141   8845       amw  * snapshot and shares.
    142    789    ahrens  */
    143    789    ahrens static gfs_dirent_t zfsctl_root_entries[] = {
    144    789    ahrens 	{ "snapshot", zfsctl_mknode_snapdir, GFS_CACHE_VNODE },
    145   8845       amw 	{ "shares", zfsctl_mknode_shares, GFS_CACHE_VNODE },
    146    789    ahrens 	{ NULL }
    147    789    ahrens };
    148    789    ahrens 
    149    789    ahrens /* include . and .. in the calculation */
    150    789    ahrens #define	NROOT_ENTRIES	((sizeof (zfsctl_root_entries) / \
    151    789    ahrens     sizeof (gfs_dirent_t)) + 1)
    152    789    ahrens 
    153    789    ahrens 
    154    789    ahrens /*
    155    789    ahrens  * Initialize the various GFS pieces we'll need to create and manipulate .zfs
    156    789    ahrens  * directories.  This is called from the ZFS init routine, and initializes the
    157    789    ahrens  * vnode ops vectors that we'll be using.
    158    789    ahrens  */
    159    789    ahrens void
    160    789    ahrens zfsctl_init(void)
    161    789    ahrens {
    162    789    ahrens 	VERIFY(gfs_make_opsvec(zfsctl_opsvec) == 0);
    163    789    ahrens }
    164    789    ahrens 
    165    789    ahrens void
    166    789    ahrens zfsctl_fini(void)
    167    789    ahrens {
    168    789    ahrens 	/*
    169    789    ahrens 	 * Remove vfsctl vnode ops
    170    789    ahrens 	 */
    171    789    ahrens 	if (zfsctl_ops_root)
    172    789    ahrens 		vn_freevnodeops(zfsctl_ops_root);
    173    789    ahrens 	if (zfsctl_ops_snapdir)
    174    789    ahrens 		vn_freevnodeops(zfsctl_ops_snapdir);
    175    789    ahrens 	if (zfsctl_ops_snapshot)
    176    789    ahrens 		vn_freevnodeops(zfsctl_ops_snapshot);
    177   8845       amw 	if (zfsctl_ops_shares)
    178   8845       amw 		vn_freevnodeops(zfsctl_ops_shares);
    179   8845       amw 	if (zfsctl_ops_shares_dir)
    180   8845       amw 		vn_freevnodeops(zfsctl_ops_shares_dir);
    181    789    ahrens 
    182    789    ahrens 	zfsctl_ops_root = NULL;
    183    789    ahrens 	zfsctl_ops_snapdir = NULL;
    184    789    ahrens 	zfsctl_ops_snapshot = NULL;
    185   8845       amw 	zfsctl_ops_shares = NULL;
    186   8845       amw 	zfsctl_ops_shares_dir = NULL;
    187    789    ahrens }
    188    789    ahrens 
    189    789    ahrens /*
    190   8845       amw  * Return the inode number associated with the 'snapshot' or
    191   8845       amw  * 'shares' directory.
    192    789    ahrens  */
    193    789    ahrens /* ARGSUSED */
    194    789    ahrens static ino64_t
    195    789    ahrens zfsctl_root_inode_cb(vnode_t *vp, int index)
    196    789    ahrens {
    197   8845       amw 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
    198   8845       amw 
    199   8845       amw 	ASSERT(index <= 2);
    200   8845       amw 
    201   8845       amw 	if (index == 0)
    202   8845       amw 		return (ZFSCTL_INO_SNAPDIR);
    203   8845       amw 
    204   8845       amw 	return (zfsvfs->z_shares_dir);
    205    789    ahrens }
    206    789    ahrens 
    207    789    ahrens /*
    208    789    ahrens  * Create the '.zfs' directory.  This directory is cached as part of the VFS
    209    789    ahrens  * structure.  This results in a hold on the vfs_t.  The code in zfs_umount()
    210    789    ahrens  * therefore checks against a vfs_count of 2 instead of 1.  This reference
    211    789    ahrens  * is removed when the ctldir is destroyed in the unmount.
    212    789    ahrens  */
    213    789    ahrens void
    214    789    ahrens zfsctl_create(zfsvfs_t *zfsvfs)
    215    789    ahrens {
    216   1571  ek110237 	vnode_t *vp, *rvp;
    217    789    ahrens 	zfsctl_node_t *zcp;
    218    789    ahrens 
    219    789    ahrens 	ASSERT(zfsvfs->z_ctldir == NULL);
    220    789    ahrens 
    221    789    ahrens 	vp = gfs_root_create(sizeof (zfsctl_node_t), zfsvfs->z_vfs,
    222    789    ahrens 	    zfsctl_ops_root, ZFSCTL_INO_ROOT, zfsctl_root_entries,
    223    789    ahrens 	    zfsctl_root_inode_cb, MAXNAMELEN, NULL, NULL);
    224    789    ahrens 	zcp = vp->v_data;
    225    789    ahrens 	zcp->zc_id = ZFSCTL_INO_ROOT;
    226   1571  ek110237 
    227   1571  ek110237 	VERIFY(VFS_ROOT(zfsvfs->z_vfs, &rvp) == 0);
    228   1571  ek110237 	ZFS_TIME_DECODE(&zcp->zc_cmtime, VTOZ(rvp)->z_phys->zp_crtime);
    229   1571  ek110237 	VN_RELE(rvp);
    230    789    ahrens 
    231    789    ahrens 	/*
    232    789    ahrens 	 * We're only faking the fact that we have a root of a filesystem for
    233    789    ahrens 	 * the sake of the GFS interfaces.  Undo the flag manipulation it did
    234    789    ahrens 	 * for us.
    235    789    ahrens 	 */
    236    789    ahrens 	vp->v_flag &= ~(VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT);
    237    789    ahrens 
    238    789    ahrens 	zfsvfs->z_ctldir = vp;
    239    789    ahrens }
    240    789    ahrens 
    241    789    ahrens /*
    242   1298    perrin  * Destroy the '.zfs' directory.  Only called when the filesystem is unmounted.
    243   1298    perrin  * There might still be more references if we were force unmounted, but only
    244   1298    perrin  * new zfs_inactive() calls can occur and they don't reference .zfs
    245    789    ahrens  */
    246    789    ahrens void
    247    789    ahrens zfsctl_destroy(zfsvfs_t *zfsvfs)
    248    789    ahrens {
    249    789    ahrens 	VN_RELE(zfsvfs->z_ctldir);
    250    789    ahrens 	zfsvfs->z_ctldir = NULL;
    251    789    ahrens }
    252    789    ahrens 
    253    789    ahrens /*
    254    789    ahrens  * Given a root znode, retrieve the associated .zfs directory.
    255    789    ahrens  * Add a hold to the vnode and return it.
    256    789    ahrens  */
    257    789    ahrens vnode_t *
    258    789    ahrens zfsctl_root(znode_t *zp)
    259    789    ahrens {
    260    789    ahrens 	ASSERT(zfs_has_ctldir(zp));
    261    789    ahrens 	VN_HOLD(zp->z_zfsvfs->z_ctldir);
    262    789    ahrens 	return (zp->z_zfsvfs->z_ctldir);
    263    789    ahrens }
    264    789    ahrens 
    265    789    ahrens /*
    266    789    ahrens  * Common open routine.  Disallow any write access.
    267    789    ahrens  */
    268    789    ahrens /* ARGSUSED */
    269    789    ahrens static int
    270   5331       amw zfsctl_common_open(vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct)
    271    789    ahrens {
    272    789    ahrens 	if (flags & FWRITE)
    273    789    ahrens 		return (EACCES);
    274    789    ahrens 
    275    789    ahrens 	return (0);
    276    789    ahrens }
    277    789    ahrens 
    278    789    ahrens /*
    279    789    ahrens  * Common close routine.  Nothing to do here.
    280    789    ahrens  */
    281    789    ahrens /* ARGSUSED */
    282    789    ahrens static int
    283    789    ahrens zfsctl_common_close(vnode_t *vpp, int flags, int count, offset_t off,
    284   5331       amw     cred_t *cr, caller_context_t *ct)
    285    789    ahrens {
    286    789    ahrens 	return (0);
    287    789    ahrens }
    288    789    ahrens 
    289    789    ahrens /*
    290    789    ahrens  * Common access routine.  Disallow writes.
    291    789    ahrens  */
    292    789    ahrens /* ARGSUSED */
    293    789    ahrens static int
    294   5331       amw zfsctl_common_access(vnode_t *vp, int mode, int flags, cred_t *cr,
    295   5331       amw     caller_context_t *ct)
    296    789    ahrens {
    297   8547      Mark 	if (flags & V_ACE_MASK) {
    298   8547      Mark 		if (mode & ACE_ALL_WRITE_PERMS)
    299   8547      Mark 			return (EACCES);
    300   8547      Mark 	} else {
    301   8547      Mark 		if (mode & VWRITE)
    302   8547      Mark 			return (EACCES);
    303   8547      Mark 	}
    304    789    ahrens 
    305    789    ahrens 	return (0);
    306    789    ahrens }
    307    789    ahrens 
    308    789    ahrens /*
    309    789    ahrens  * Common getattr function.  Fill in basic information.
    310    789    ahrens  */
    311    789    ahrens static void
    312    789    ahrens zfsctl_common_getattr(vnode_t *vp, vattr_t *vap)
    313    789    ahrens {
    314   1571  ek110237 	timestruc_t	now;
    315    789    ahrens 
    316    789    ahrens 	vap->va_uid = 0;
    317    789    ahrens 	vap->va_gid = 0;
    318    789    ahrens 	vap->va_rdev = 0;
    319    789    ahrens 	/*
    320  10373     chris 	 * We are a purely virtual object, so we have no
    321    789    ahrens 	 * blocksize or allocated blocks.
    322    789    ahrens 	 */
    323    789    ahrens 	vap->va_blksize = 0;
    324    789    ahrens 	vap->va_nblocks = 0;
    325    789    ahrens 	vap->va_seq = 0;
    326    789    ahrens 	vap->va_fsid = vp->v_vfsp->vfs_dev;
    327    789    ahrens 	vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP |
    328    789    ahrens 	    S_IROTH | S_IXOTH;
    329    789    ahrens 	vap->va_type = VDIR;
    330    789    ahrens 	/*
    331   1571  ek110237 	 * We live in the now (for atime).
    332    789    ahrens 	 */
    333    789    ahrens 	gethrestime(&now);
    334   1571  ek110237 	vap->va_atime = now;
    335    789    ahrens }
    336    789    ahrens 
    337   5331       amw /*ARGSUSED*/
    338    789    ahrens static int
    339   5331       amw zfsctl_common_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
    340    789    ahrens {
    341    789    ahrens 	zfsvfs_t	*zfsvfs = vp->v_vfsp->vfs_data;
    342    789    ahrens 	zfsctl_node_t	*zcp = vp->v_data;
    343    789    ahrens 	uint64_t	object = zcp->zc_id;
    344    789    ahrens 	zfid_short_t	*zfid;
    345    789    ahrens 	int		i;
    346    789    ahrens 
    347    789    ahrens 	ZFS_ENTER(zfsvfs);
    348    789    ahrens 
    349    789    ahrens 	if (fidp->fid_len < SHORT_FID_LEN) {
    350    789    ahrens 		fidp->fid_len = SHORT_FID_LEN;
    351   1512  ek110237 		ZFS_EXIT(zfsvfs);
    352    789    ahrens 		return (ENOSPC);
    353    789    ahrens 	}
    354    789    ahrens 
    355    789    ahrens 	zfid = (zfid_short_t *)fidp;
    356    789    ahrens 
    357    789    ahrens 	zfid->zf_len = SHORT_FID_LEN;
    358    789    ahrens 
    359    789    ahrens 	for (i = 0; i < sizeof (zfid->zf_object); i++)
    360    789    ahrens 		zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
    361    789    ahrens 
    362    789    ahrens 	/* .zfs znodes always have a generation number of 0 */
    363    789    ahrens 	for (i = 0; i < sizeof (zfid->zf_gen); i++)
    364    789    ahrens 		zfid->zf_gen[i] = 0;
    365    789    ahrens 
    366    789    ahrens 	ZFS_EXIT(zfsvfs);
    367    789    ahrens 	return (0);
    368    789    ahrens }
    369    789    ahrens 
    370   8845       amw 
    371   8845       amw /*ARGSUSED*/
    372   8845       amw static int
    373   8845       amw zfsctl_shares_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
    374   8845       amw {
    375   8845       amw 	zfsvfs_t	*zfsvfs = vp->v_vfsp->vfs_data;
    376   8845       amw 	znode_t		*dzp;
    377   8845       amw 	int		error;
    378   8845       amw 
    379   8845       amw 	ZFS_ENTER(zfsvfs);
    380   9030      Mark 
    381   9030      Mark 	if (zfsvfs->z_shares_dir == 0) {
    382   9030      Mark 		ZFS_EXIT(zfsvfs);
    383   9030      Mark 		return (ENOTSUP);
    384   9030      Mark 	}
    385   9030      Mark 
    386   8845       amw 	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
    387   8845       amw 		error = VOP_FID(ZTOV(dzp), fidp, ct);
    388   8845       amw 		VN_RELE(ZTOV(dzp));
    389   8845       amw 	}
    390   8845       amw 
    391   8845       amw 	ZFS_EXIT(zfsvfs);
    392   8845       amw 	return (error);
    393   8845       amw }
    394    789    ahrens /*
    395    789    ahrens  * .zfs inode namespace
    396    789    ahrens  *
    397    789    ahrens  * We need to generate unique inode numbers for all files and directories
    398    789    ahrens  * within the .zfs pseudo-filesystem.  We use the following scheme:
    399    789    ahrens  *
    400    789    ahrens  * 	ENTRY			ZFSCTL_INODE
    401    789    ahrens  * 	.zfs			1
    402    789    ahrens  * 	.zfs/snapshot		2
    403    789    ahrens  * 	.zfs/snapshot/<snap>	objectid(snap)
    404    789    ahrens  */
    405    789    ahrens 
    406    789    ahrens #define	ZFSCTL_INO_SNAP(id)	(id)
    407    789    ahrens 
    408    789    ahrens /*
    409    789    ahrens  * Get root directory attributes.
    410    789    ahrens  */
    411    789    ahrens /* ARGSUSED */
    412    789    ahrens static int
    413   5331       amw zfsctl_root_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
    414   5331       amw     caller_context_t *ct)
    415    789    ahrens {
    416    789    ahrens 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
    417  10373     chris 	zfsctl_node_t *zcp = vp->v_data;
    418    789    ahrens 
    419    789    ahrens 	ZFS_ENTER(zfsvfs);
    420    789    ahrens 	vap->va_nodeid = ZFSCTL_INO_ROOT;
    421    789    ahrens 	vap->va_nlink = vap->va_size = NROOT_ENTRIES;
    422  10373     chris 	vap->va_mtime = vap->va_ctime = zcp->zc_cmtime;
    423    789    ahrens 
    424    789    ahrens 	zfsctl_common_getattr(vp, vap);
    425    789    ahrens 	ZFS_EXIT(zfsvfs);
    426    789    ahrens 
    427    789    ahrens 	return (0);
    428    789    ahrens }
    429    789    ahrens 
    430    789    ahrens /*
    431    789    ahrens  * Special case the handling of "..".
    432    789    ahrens  */
    433    789    ahrens /* ARGSUSED */
    434    789    ahrens int
    435    789    ahrens zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
    436   5331       amw     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
    437   5331       amw     int *direntflags, pathname_t *realpnp)
    438    789    ahrens {
    439    789    ahrens 	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
    440    789    ahrens 	int err;
    441   5331       amw 
    442   5331       amw 	/*
    443   5331       amw 	 * No extended attributes allowed under .zfs
    444   5331       amw 	 */
    445   5331       amw 	if (flags & LOOKUP_XATTR)
    446   5331       amw 		return (EINVAL);
    447    789    ahrens 
    448    789    ahrens 	ZFS_ENTER(zfsvfs);
    449    789    ahrens 
    450    789    ahrens 	if (strcmp(nm, "..") == 0) {
    451    789    ahrens 		err = VFS_ROOT(dvp->v_vfsp, vpp);
    452    789    ahrens 	} else {
    453   6492      timh 		err = gfs_vop_lookup(dvp, nm, vpp, pnp, flags, rdir,
    454   6492      timh 		    cr, ct, direntflags, realpnp);
    455    789    ahrens 	}
    456    789    ahrens 
    457    789    ahrens 	ZFS_EXIT(zfsvfs);
    458    789    ahrens 
    459    789    ahrens 	return (err);
    460    789    ahrens }
    461    789    ahrens 
    462   8547      Mark static int
    463   8547      Mark zfsctl_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
    464   8547      Mark     caller_context_t *ct)
    465   8547      Mark {
    466   8547      Mark 	/*
    467   8547      Mark 	 * We only care about ACL_ENABLED so that libsec can
    468   8547      Mark 	 * display ACL correctly and not default to POSIX draft.
    469   8547      Mark 	 */
    470   8547      Mark 	if (cmd == _PC_ACL_ENABLED) {
    471   8547      Mark 		*valp = _ACL_ACE_ENABLED;
    472   8547      Mark 		return (0);
    473   8547      Mark 	}
    474   8547      Mark 
    475   8547      Mark 	return (fs_pathconf(vp, cmd, valp, cr, ct));
    476   8547      Mark }
    477   8547      Mark 
    478    789    ahrens static const fs_operation_def_t zfsctl_tops_root[] = {
    479   3898       rsb 	{ VOPNAME_OPEN,		{ .vop_open = zfsctl_common_open }	},
    480   3898       rsb 	{ VOPNAME_CLOSE,	{ .vop_close = zfsctl_common_close }	},
    481   3898       rsb 	{ VOPNAME_IOCTL,	{ .error = fs_inval }			},
    482   3898       rsb 	{ VOPNAME_GETATTR,	{ .vop_getattr = zfsctl_root_getattr }	},
    483   3898       rsb 	{ VOPNAME_ACCESS,	{ .vop_access = zfsctl_common_access }	},
    484   3898       rsb 	{ VOPNAME_READDIR,	{ .vop_readdir = gfs_vop_readdir } 	},
    485   3898       rsb 	{ VOPNAME_LOOKUP,	{ .vop_lookup = zfsctl_root_lookup }	},
    486   3898       rsb 	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek }			},
    487   3898       rsb 	{ VOPNAME_INACTIVE,	{ .vop_inactive = gfs_vop_inactive }	},
    488   8547      Mark 	{ VOPNAME_PATHCONF,	{ .vop_pathconf = zfsctl_pathconf }	},
    489   3898       rsb 	{ VOPNAME_FID,		{ .vop_fid = zfsctl_common_fid	}	},
    490    789    ahrens 	{ NULL }
    491    789    ahrens };
    492    789    ahrens 
    493    789    ahrens static int
    494    789    ahrens zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname)
    495    789    ahrens {
    496    789    ahrens 	objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os;
    497    789    ahrens 
    498   6658     marks 	if (snapshot_namecheck(name, NULL, NULL) != 0)
    499   6658     marks 		return (EILSEQ);
    500    789    ahrens 	dmu_objset_name(os, zname);
    501   1154    maybee 	if (strlen(zname) + 1 + strlen(name) >= len)
    502   1154    maybee 		return (ENAMETOOLONG);
    503    789    ahrens 	(void) strcat(zname, "@");
    504    789    ahrens 	(void) strcat(zname, name);
    505    789    ahrens 	return (0);
    506    789    ahrens }
    507    789    ahrens 
    508   6068  ck153898 static int
    509   6068  ck153898 zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr)
    510    789    ahrens {
    511   6068  ck153898 	vnode_t *svp = sep->se_root;
    512   6068  ck153898 	int error;
    513    789    ahrens 
    514   6068  ck153898 	ASSERT(vn_ismntpt(svp));
    515    789    ahrens 
    516    789    ahrens 	/* this will be dropped by dounmount() */
    517   6068  ck153898 	if ((error = vn_vfswlock(svp)) != 0)
    518   6068  ck153898 		return (error);
    519    789    ahrens 
    520   6068  ck153898 	VN_HOLD(svp);
    521   6068  ck153898 	error = dounmount(vn_mountedvfs(svp), fflags, cr);
    522   6068  ck153898 	if (error) {
    523   6068  ck153898 		VN_RELE(svp);
    524   6068  ck153898 		return (error);
    525   1589    maybee 	}
    526   9214     chris 
    527   6068  ck153898 	/*
    528   6068  ck153898 	 * We can't use VN_RELE(), as that will try to invoke
    529   6068  ck153898 	 * zfsctl_snapdir_inactive(), which would cause us to destroy
    530   6068  ck153898 	 * the sd_lock mutex held by our caller.
    531   6068  ck153898 	 */
    532   6068  ck153898 	ASSERT(svp->v_count == 1);
    533   6068  ck153898 	gfs_vop_inactive(svp, cr, NULL);
    534    789    ahrens 
    535    789    ahrens 	kmem_free(sep->se_name, strlen(sep->se_name) + 1);
    536    789    ahrens 	kmem_free(sep, sizeof (zfs_snapentry_t));
    537    789    ahrens 
    538    789    ahrens 	return (0);
    539    789    ahrens }
    540    789    ahrens 
    541   1154    maybee static void
    542    789    ahrens zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm)
    543    789    ahrens {
    544    789    ahrens 	avl_index_t where;
    545    789    ahrens 	vfs_t *vfsp;
    546    789    ahrens 	refstr_t *pathref;
    547    789    ahrens 	char newpath[MAXNAMELEN];
    548    789    ahrens 	char *tail;
    549    789    ahrens 
    550    789    ahrens 	ASSERT(MUTEX_HELD(&sdp->sd_lock));
    551    789    ahrens 	ASSERT(sep != NULL);
    552    789    ahrens 
    553    789    ahrens 	vfsp = vn_mountedvfs(sep->se_root);
    554    789    ahrens 	ASSERT(vfsp != NULL);
    555    789    ahrens 
    556   1154    maybee 	vfs_lock_wait(vfsp);
    557    789    ahrens 
    558    789    ahrens 	/*
    559    789    ahrens 	 * Change the name in the AVL tree.
    560    789    ahrens 	 */
    561    789    ahrens 	avl_remove(&sdp->sd_snaps, sep);
    562    789    ahrens 	kmem_free(sep->se_name, strlen(sep->se_name) + 1);
    563    789    ahrens 	sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
    564    789    ahrens 	(void) strcpy(sep->se_name, nm);
    565    789    ahrens 	VERIFY(avl_find(&sdp->sd_snaps, sep, &where) == NULL);
    566    789    ahrens 	avl_insert(&sdp->sd_snaps, sep, where);
    567    789    ahrens 
    568    789    ahrens 	/*
    569    789    ahrens 	 * Change the current mountpoint info:
    570    789    ahrens 	 * 	- update the tail of the mntpoint path
    571    789    ahrens 	 *	- update the tail of the resource path
    572    789    ahrens 	 */
    573    789    ahrens 	pathref = vfs_getmntpoint(vfsp);
    574   2417    ahrens 	(void) strncpy(newpath, refstr_value(pathref), sizeof (newpath));
    575   2417    ahrens 	VERIFY((tail = strrchr(newpath, '/')) != NULL);
    576   2417    ahrens 	*(tail+1) = '\0';
    577   2417    ahrens 	ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath));
    578    789    ahrens 	(void) strcat(newpath, nm);
    579    789    ahrens 	refstr_rele(pathref);
    580    789    ahrens 	vfs_setmntpoint(vfsp, newpath);
    581    789    ahrens 
    582    789    ahrens 	pathref = vfs_getresource(vfsp);
    583   2417    ahrens 	(void) strncpy(newpath, refstr_value(pathref), sizeof (newpath));
    584   2417    ahrens 	VERIFY((tail = strrchr(newpath, '@')) != NULL);
    585   2417    ahrens 	*(tail+1) = '\0';
    586   2417    ahrens 	ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath));
    587    789    ahrens 	(void) strcat(newpath, nm);
    588    789    ahrens 	refstr_rele(pathref);
    589    789    ahrens 	vfs_setresource(vfsp, newpath);
    590    789    ahrens 
    591    789    ahrens 	vfs_unlock(vfsp);
    592    789    ahrens }
    593    789    ahrens 
    594   5331       amw /*ARGSUSED*/
    595    789    ahrens static int
    596    789    ahrens zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
    597   5331       amw     cred_t *cr, caller_context_t *ct, int flags)
    598    789    ahrens {
    599    789    ahrens 	zfsctl_snapdir_t *sdp = sdvp->v_data;
    600    789    ahrens 	zfs_snapentry_t search, *sep;
    601   6492      timh 	zfsvfs_t *zfsvfs;
    602    789    ahrens 	avl_index_t where;
    603    789    ahrens 	char from[MAXNAMELEN], to[MAXNAMELEN];
    604   6492      timh 	char real[MAXNAMELEN];
    605    789    ahrens 	int err;
    606    789    ahrens 
    607   6492      timh 	zfsvfs = sdvp->v_vfsp->vfs_data;
    608   6492      timh 	ZFS_ENTER(zfsvfs);
    609   6492      timh 
    610   6492      timh 	if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
    611   6492      timh 		err = dmu_snapshot_realname(zfsvfs->z_os, snm, real,
    612   6492      timh 		    MAXNAMELEN, NULL);
    613   6492      timh 		if (err == 0) {
    614   6492      timh 			snm = real;
    615   6492      timh 		} else if (err != ENOTSUP) {
    616   6492      timh 			ZFS_EXIT(zfsvfs);
    617   6492      timh 			return (err);
    618   6492      timh 		}
    619   6492      timh 	}
    620   6492      timh 
    621   6492      timh 	ZFS_EXIT(zfsvfs);
    622   6492      timh 
    623   1154    maybee 	err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from);
    624   6492      timh 	if (!err)
    625   6492      timh 		err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to);
    626   6492      timh 	if (!err)
    627   6492      timh 		err = zfs_secpolicy_rename_perms(from, to, cr);
    628   1154    maybee 	if (err)
    629   1154    maybee 		return (err);
    630   4543     marks 
    631    789    ahrens 	/*
    632    789    ahrens 	 * Cannot move snapshots out of the snapdir.
    633    789    ahrens 	 */
    634    789    ahrens 	if (sdvp != tdvp)
    635    789    ahrens 		return (EINVAL);
    636    789    ahrens 
    637    789    ahrens 	if (strcmp(snm, tnm) == 0)
    638    789    ahrens 		return (0);
    639   1154    maybee 
    640    789    ahrens 	mutex_enter(&sdp->sd_lock);
    641    789    ahrens 
    642    789    ahrens 	search.se_name = (char *)snm;
    643   1154    maybee 	if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) == NULL) {
    644   1154    maybee 		mutex_exit(&sdp->sd_lock);
    645   1154    maybee 		return (ENOENT);
    646    789    ahrens 	}
    647    789    ahrens 
    648   4007  mmusante 	err = dmu_objset_rename(from, to, B_FALSE);
    649   1154    maybee 	if (err == 0)
    650   1154    maybee 		zfsctl_rename_snap(sdp, sep, tnm);
    651    789    ahrens 
    652    789    ahrens 	mutex_exit(&sdp->sd_lock);
    653    789    ahrens 
    654    789    ahrens 	return (err);
    655    789    ahrens }
    656    789    ahrens 
    657    789    ahrens /* ARGSUSED */
    658    789    ahrens static int
    659   5331       amw zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr,
    660   5331       amw     caller_context_t *ct, int flags)
    661    789    ahrens {
    662    789    ahrens 	zfsctl_snapdir_t *sdp = dvp->v_data;
    663   6068  ck153898 	zfs_snapentry_t *sep;
    664   6068  ck153898 	zfs_snapentry_t search;
    665   6492      timh 	zfsvfs_t *zfsvfs;
    666    789    ahrens 	char snapname[MAXNAMELEN];
    667   6492      timh 	char real[MAXNAMELEN];
    668    789    ahrens 	int err;
    669    789    ahrens 
    670   6492      timh 	zfsvfs = dvp->v_vfsp->vfs_data;
    671   6492      timh 	ZFS_ENTER(zfsvfs);
    672   6492      timh 
    673   6492      timh 	if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
    674   6492      timh 
    675   6492      timh 		err = dmu_snapshot_realname(zfsvfs->z_os, name, real,
    676   6492      timh 		    MAXNAMELEN, NULL);
    677   6492      timh 		if (err == 0) {
    678   6492      timh 			name = real;
    679   6492      timh 		} else if (err != ENOTSUP) {
    680   6492      timh 			ZFS_EXIT(zfsvfs);
    681   6492      timh 			return (err);
    682   6492      timh 		}
    683   6492      timh 	}
    684   6492      timh 
    685   6492      timh 	ZFS_EXIT(zfsvfs);
    686   6492      timh 
    687   1154    maybee 	err = zfsctl_snapshot_zname(dvp, name, MAXNAMELEN, snapname);
    688   6492      timh 	if (!err)
    689   6492      timh 		err = zfs_secpolicy_destroy_perms(snapname, cr);
    690   1154    maybee 	if (err)
    691    789    ahrens 		return (err);
    692    789    ahrens 
    693    789    ahrens 	mutex_enter(&sdp->sd_lock);
    694    789    ahrens 
    695   6068  ck153898 	search.se_name = name;
    696   6068  ck153898 	sep = avl_find(&sdp->sd_snaps, &search, NULL);
    697   6068  ck153898 	if (sep) {
    698   6068  ck153898 		avl_remove(&sdp->sd_snaps, sep);
    699   6068  ck153898 		err = zfsctl_unmount_snap(sep, MS_FORCE, cr);
    700   6068  ck153898 		if (err)
    701   6068  ck153898 			avl_add(&sdp->sd_snaps, sep);
    702   6068  ck153898 		else
    703  10242     chris 			err = dmu_objset_destroy(snapname, B_FALSE);
    704   6068  ck153898 	} else {
    705   6068  ck153898 		err = ENOENT;
    706    789    ahrens 	}
    707    789    ahrens 
    708    789    ahrens 	mutex_exit(&sdp->sd_lock);
    709   4543     marks 
    710   4543     marks 	return (err);
    711   4543     marks }
    712   4543     marks 
    713   5326  ek110237 /*
    714   5326  ek110237  * This creates a snapshot under '.zfs/snapshot'.
    715   5326  ek110237  */
    716   4543     marks /* ARGSUSED */
    717   4543     marks static int
    718   4543     marks zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t  **vpp,
    719   5331       amw     cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
    720   4543     marks {
    721   4543     marks 	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
    722   4543     marks 	char name[MAXNAMELEN];
    723   4543     marks 	int err;
    724   4543     marks 	static enum symfollow follow = NO_FOLLOW;
    725   4543     marks 	static enum uio_seg seg = UIO_SYSSPACE;
    726   6658     marks 
    727   6658     marks 	if (snapshot_namecheck(dirname, NULL, NULL) != 0)
    728   6658     marks 		return (EILSEQ);
    729   4543     marks 
    730   4543     marks 	dmu_objset_name(zfsvfs->z_os, name);
    731   4543     marks 
    732   4543     marks 	*vpp = NULL;
    733   4543     marks 
    734   4543     marks 	err = zfs_secpolicy_snapshot_perms(name, cr);
    735   4543     marks 	if (err)
    736   4543     marks 		return (err);
    737   4543     marks 
    738   4543     marks 	if (err == 0) {
    739   9355   Matthew 		err = dmu_objset_snapshot(name, dirname, NULL, B_FALSE);
    740   4543     marks 		if (err)
    741   4543     marks 			return (err);
    742   4543     marks 		err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
    743   4543     marks 	}
    744    789    ahrens 
    745    789    ahrens 	return (err);
    746    789    ahrens }
    747    789    ahrens 
    748    789    ahrens /*
    749    789    ahrens  * Lookup entry point for the 'snapshot' directory.  Try to open the
    750    789    ahrens  * snapshot if it exist, creating the pseudo filesystem vnode as necessary.
    751    789    ahrens  * Perform a mount of the associated dataset on top of the vnode.
    752    789    ahrens  */
    753    789    ahrens /* ARGSUSED */
    754    789    ahrens static int
    755    789    ahrens zfsctl_snapdir_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
    756   5331       amw     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
    757   5331       amw     int *direntflags, pathname_t *realpnp)
    758    789    ahrens {
    759    789    ahrens 	zfsctl_snapdir_t *sdp = dvp->v_data;
    760    789    ahrens 	objset_t *snap;
    761    789    ahrens 	char snapname[MAXNAMELEN];
    762   6492      timh 	char real[MAXNAMELEN];
    763    789    ahrens 	char *mountpoint;
    764    789    ahrens 	zfs_snapentry_t *sep, search;
    765    789    ahrens 	struct mounta margs;
    766    789    ahrens 	vfs_t *vfsp;
    767    789    ahrens 	size_t mountpoint_len;
    768    789    ahrens 	avl_index_t where;
    769    789    ahrens 	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
    770    789    ahrens 	int err;
    771   5331       amw 
    772   5331       amw 	/*
    773   5331       amw 	 * No extended attributes allowed under .zfs
    774   5331       amw 	 */
    775   5331       amw 	if (flags & LOOKUP_XATTR)
    776   5331       amw 		return (EINVAL);
    777    789    ahrens 
    778    789    ahrens 	ASSERT(dvp->v_type == VDIR);
    779    789    ahrens 
    780    789    ahrens 	/*
    781    789    ahrens 	 * If we get a recursive call, that means we got called
    782    789    ahrens 	 * from the domount() code while it was trying to look up the
    783    789    ahrens 	 * spec (which looks like a local path for zfs).  We need to
    784    789    ahrens 	 * add some flag to domount() to tell it not to do this lookup.
    785    789    ahrens 	 */
    786    789    ahrens 	if (MUTEX_HELD(&sdp->sd_lock))
    787    789    ahrens 		return (ENOENT);
    788    789    ahrens 
    789    789    ahrens 	ZFS_ENTER(zfsvfs);
    790   9214     chris 
    791   9214     chris 	if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) {
    792   9214     chris 		ZFS_EXIT(zfsvfs);
    793   9214     chris 		return (0);
    794   9214     chris 	}
    795   6492      timh 
    796   6492      timh 	if (flags & FIGNORECASE) {
    797   6492      timh 		boolean_t conflict = B_FALSE;
    798   6492      timh 
    799   6492      timh 		err = dmu_snapshot_realname(zfsvfs->z_os, nm, real,
    800   6492      timh 		    MAXNAMELEN, &conflict);
    801   6492      timh 		if (err == 0) {
    802   6492      timh 			nm = real;
    803   6492      timh 		} else if (err != ENOTSUP) {
    804   6492      timh 			ZFS_EXIT(zfsvfs);
    805   6492      timh 			return (err);
    806   6492      timh 		}
    807   6492      timh 		if (realpnp)
    808   6492      timh 			(void) strlcpy(realpnp->pn_buf, nm,
    809   6492      timh 			    realpnp->pn_bufsize);
    810   6492      timh 		if (conflict && direntflags)
    811   6492      timh 			*direntflags = ED_CASE_CONFLICT;
    812   6492      timh 	}
    813    789    ahrens 
    814    789    ahrens 	mutex_enter(&sdp->sd_lock);
    815    789    ahrens 	search.se_name = (char *)nm;
    816    789    ahrens 	if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) {
    817    789    ahrens 		*vpp = sep->se_root;
    818    789    ahrens 		VN_HOLD(*vpp);
    819   1589    maybee 		err = traverse(vpp);
    820   1589    maybee 		if (err) {
    821   1589    maybee 			VN_RELE(*vpp);
    822   1589    maybee 			*vpp = NULL;
    823   1589    maybee 		} else if (*vpp == sep->se_root) {
    824   1589    maybee 			/*
    825   1589    maybee 			 * The snapshot was unmounted behind our backs,
    826   1589    maybee 			 * try to remount it.
    827   1589    maybee 			 */
    828    789    ahrens 			goto domount;
    829   6068  ck153898 		} else {
    830   6068  ck153898 			/*
    831   6068  ck153898 			 * VROOT was set during the traverse call.  We need
    832   6068  ck153898 			 * to clear it since we're pretending to be part
    833   6068  ck153898 			 * of our parent's vfs.
    834   6068  ck153898 			 */
    835   6068  ck153898 			(*vpp)->v_flag &= ~VROOT;
    836   1566    maybee 		}
    837    789    ahrens 		mutex_exit(&sdp->sd_lock);
    838    789    ahrens 		ZFS_EXIT(zfsvfs);
    839   1589    maybee 		return (err);
    840    789    ahrens 	}
    841    789    ahrens 
    842    789    ahrens 	/*
    843    789    ahrens 	 * The requested snapshot is not currently mounted, look it up.
    844    789    ahrens 	 */
    845   1154    maybee 	err = zfsctl_snapshot_zname(dvp, nm, MAXNAMELEN, snapname);
    846   1154    maybee 	if (err) {
    847   1154    maybee 		mutex_exit(&sdp->sd_lock);
    848   1154    maybee 		ZFS_EXIT(zfsvfs);
    849   7229     marks 		/*
    850   7229     marks 		 * handle "ls *" or "?" in a graceful manner,
    851   7229     marks 		 * forcing EILSEQ to ENOENT.
    852   7229     marks 		 * Since shell ultimately passes "*" or "?" as name to lookup
    853   7229     marks 		 */
    854   7229     marks 		return (err == EILSEQ ? ENOENT : err);
    855   1154    maybee 	}
    856  10298   Matthew 	if (dmu_objset_hold(snapname, FTAG, &snap) != 0) {
    857    789    ahrens 		mutex_exit(&sdp->sd_lock);
    858    789    ahrens 		ZFS_EXIT(zfsvfs);
    859    789    ahrens 		return (ENOENT);
    860    789    ahrens 	}
    861    789    ahrens 
    862    789    ahrens 	sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP);
    863    789    ahrens 	sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
    864    789    ahrens 	(void) strcpy(sep->se_name, nm);
    865    789    ahrens 	*vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
    866    789    ahrens 	avl_insert(&sdp->sd_snaps, sep, where);
    867    789    ahrens 
    868  10298   Matthew 	dmu_objset_rele(snap, FTAG);
    869    789    ahrens domount:
    870    789    ahrens 	mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) +
    871    789    ahrens 	    strlen("/.zfs/snapshot/") + strlen(nm) + 1;
    872    789    ahrens 	mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
    873    789    ahrens 	(void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s",
    874    789    ahrens 	    refstr_value(dvp->v_vfsp->vfs_mntpt), nm);
    875    789    ahrens 
    876    789    ahrens 	margs.spec = snapname;
    877    789    ahrens 	margs.dir = mountpoint;
    878    789    ahrens 	margs.flags = MS_SYSSPACE | MS_NOMNTTAB;
    879    789    ahrens 	margs.fstype = "zfs";
    880    789    ahrens 	margs.dataptr = NULL;
    881    789    ahrens 	margs.datalen = 0;
    882    789    ahrens 	margs.optptr = NULL;
    883    789    ahrens 	margs.optlen = 0;
    884    789    ahrens 
    885    789    ahrens 	err = domount("zfs", &margs, *vpp, kcred, &vfsp);
    886    789    ahrens 	kmem_free(mountpoint, mountpoint_len);
    887    789    ahrens 
    888    816    maybee 	if (err == 0) {
    889    816    maybee 		/*
    890    816    maybee 		 * Return the mounted root rather than the covered mount point.
    891   5326  ek110237 		 * Takes the GFS vnode at .zfs/snapshot/<snapname> and returns
    892   5326  ek110237 		 * the ZFS vnode mounted on top of the GFS node.  This ZFS
    893   9214     chris 		 * vnode is the root of the newly created vfsp.
    894    816    maybee 		 */
    895    816    maybee 		VFS_RELE(vfsp);
    896    816    maybee 		err = traverse(vpp);
    897    816    maybee 	}
    898    789    ahrens 
    899    816    maybee 	if (err == 0) {
    900    816    maybee 		/*
    901   5326  ek110237 		 * Fix up the root vnode mounted on .zfs/snapshot/<snapname>.
    902   4736  ek110237 		 *
    903   4736  ek110237 		 * This is where we lie about our v_vfsp in order to
    904   5326  ek110237 		 * make .zfs/snapshot/<snapname> accessible over NFS
    905   5326  ek110237 		 * without requiring manual mounts of <snapname>.
    906    816    maybee 		 */
    907    816    maybee 		ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs);
    908    816    maybee 		VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs;
    909    816    maybee 		(*vpp)->v_vfsp = zfsvfs->z_vfs;
    910    816    maybee 		(*vpp)->v_flag &= ~VROOT;
    911    816    maybee 	}
    912    789    ahrens 	mutex_exit(&sdp->sd_lock);
    913    789    ahrens 	ZFS_EXIT(zfsvfs);
    914    789    ahrens 
    915   1566    maybee 	/*
    916   1566    maybee 	 * If we had an error, drop our hold on the vnode and
    917   1566    maybee 	 * zfsctl_snapshot_inactive() will clean up.
    918   1566    maybee 	 */
    919   1566    maybee 	if (err) {
    920    816    maybee 		VN_RELE(*vpp);
    921   1566    maybee 		*vpp = NULL;
    922   1566    maybee 	}
    923    816    maybee 	return (err);
    924    789    ahrens }
    925    789    ahrens 
    926    789    ahrens /* ARGSUSED */
    927    789    ahrens static int
    928   8845       amw zfsctl_shares_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
    929   8845       amw     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
    930   8845       amw     int *direntflags, pathname_t *realpnp)
    931   8845       amw {
    932   8845       amw 	zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
    933   8845       amw 	znode_t *dzp;
    934   8845       amw 	int error;
    935   8845       amw 
    936   8845       amw 	ZFS_ENTER(zfsvfs);
    937   8845       amw 
    938   8845       amw 	if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) {
    939   8845       amw 		ZFS_EXIT(zfsvfs);
    940   8845       amw 		return (0);
    941   8845       amw 	}
    942   8845       amw 
    943   9030      Mark 	if (zfsvfs->z_shares_dir == 0) {
    944   9030      Mark 		ZFS_EXIT(zfsvfs);
    945   9030      Mark 		return (ENOTSUP);
    946   9030      Mark 	}
    947   8845       amw 	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0)
    948   8845       amw 		error = VOP_LOOKUP(ZTOV(dzp), nm, vpp, pnp,
    949   8845       amw 		    flags, rdir, cr, ct, direntflags, realpnp);
    950   8845       amw 
    951   8845       amw 	VN_RELE(ZTOV(dzp));
    952   8845       amw 	ZFS_EXIT(zfsvfs);
    953   8845       amw 
    954   8845       amw 	return (error);
    955   8845       amw }
    956   8845       amw 
    957   8845       amw /* ARGSUSED */
    958   8845       amw static int
    959   5663  ck153898 zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp,
    960   5663  ck153898     offset_t *offp, offset_t *nextp, void *data, int flags)
    961    789    ahrens {
    962    789    ahrens 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
    963    789    ahrens 	char snapname[MAXNAMELEN];
    964    789    ahrens 	uint64_t id, cookie;
    965   5663  ck153898 	boolean_t case_conflict;
    966   5663  ck153898 	int error;
    967    789    ahrens 
    968    789    ahrens 	ZFS_ENTER(zfsvfs);
    969    789    ahrens 
    970    789    ahrens 	cookie = *offp;
    971   5663  ck153898 	error = dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, snapname, &id,
    972   5663  ck153898 	    &cookie, &case_conflict);
    973   5663  ck153898 	if (error) {
    974    789    ahrens 		ZFS_EXIT(zfsvfs);
    975   5663  ck153898 		if (error == ENOENT) {
    976   5663  ck153898 			*eofp = 1;
    977   5663  ck153898 			return (0);
    978   5663  ck153898 		}
    979   5663  ck153898 		return (error);
    980    789    ahrens 	}
    981    789    ahrens 
    982   5663  ck153898 	if (flags & V_RDDIR_ENTFLAGS) {
    983   5663  ck153898 		edirent_t *eodp = dp;
    984   5663  ck153898 
    985   5663  ck153898 		(void) strcpy(eodp->ed_name, snapname);
    986   5663  ck153898 		eodp->ed_ino = ZFSCTL_INO_SNAP(id);
    987   5663  ck153898 		eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0;
    988   5663  ck153898 	} else {
    989   5663  ck153898 		struct dirent64 *odp = dp;
    990   5663  ck153898 
    991   5663  ck153898 		(void) strcpy(odp->d_name, snapname);
    992   5663  ck153898 		odp->d_ino = ZFSCTL_INO_SNAP(id);
    993   5663  ck153898 	}
    994    789    ahrens 	*nextp = cookie;
    995    789    ahrens 
    996    789    ahrens 	ZFS_EXIT(zfsvfs);
    997    789    ahrens 
    998    789    ahrens 	return (0);
    999    789    ahrens }
   1000    789    ahrens 
   1001   8845       amw /* ARGSUSED */
   1002   8845       amw static int
   1003   8845       amw zfsctl_shares_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
   1004   8845       amw     caller_context_t *ct, int flags)
   1005   8845       amw {
   1006   8845       amw 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
   1007   8845       amw 	znode_t *dzp;
   1008   8845       amw 	int error;
   1009   8845       amw 
   1010   8845       amw 	ZFS_ENTER(zfsvfs);
   1011   8845       amw 
   1012   9030      Mark 	if (zfsvfs->z_shares_dir == 0) {
   1013   9030      Mark 		ZFS_EXIT(zfsvfs);
   1014   9030      Mark 		return (ENOTSUP);
   1015   9030      Mark 	}
   1016   8845       amw 	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
   1017   8845       amw 		error = VOP_READDIR(ZTOV(dzp), uiop, cr, eofp, ct, flags);
   1018   8845       amw 		VN_RELE(ZTOV(dzp));
   1019   8845       amw 	} else {
   1020   8845       amw 		*eofp = 1;
   1021   8845       amw 		error = ENOENT;
   1022   8845       amw 	}
   1023   8845       amw 
   1024   8845       amw 	ZFS_EXIT(zfsvfs);
   1025   8845       amw 	return (error);
   1026   8845       amw }
   1027   8845       amw 
   1028   5326  ek110237 /*
   1029   5326  ek110237  * pvp is the '.zfs' directory (zfsctl_node_t).
   1030   5326  ek110237  * Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t).
   1031   5326  ek110237  *
   1032   5326  ek110237  * This function is the callback to create a GFS vnode for '.zfs/snapshot'
   1033   5326  ek110237  * when a lookup is performed on .zfs for "snapshot".
   1034   5326  ek110237  */
   1035    789    ahrens vnode_t *
   1036    789    ahrens zfsctl_mknode_snapdir(vnode_t *pvp)
   1037    789    ahrens {
   1038    789    ahrens 	vnode_t *vp;
   1039    789    ahrens 	zfsctl_snapdir_t *sdp;
   1040    789    ahrens 
   1041    789    ahrens 	vp = gfs_dir_create(sizeof (zfsctl_snapdir_t), pvp,
   1042    789    ahrens 	    zfsctl_ops_snapdir, NULL, NULL, MAXNAMELEN,
   1043    789    ahrens 	    zfsctl_snapdir_readdir_cb, NULL);
   1044    789    ahrens 	sdp = vp->v_data;
   1045    789    ahrens 	sdp->sd_node.zc_id = ZFSCTL_INO_SNAPDIR;
   1046   1571  ek110237 	sdp->sd_node.zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime;
   1047    789    ahrens 	mutex_init(&sdp->sd_lock, NULL, MUTEX_DEFAULT, NULL);
   1048    789    ahrens 	avl_create(&sdp->sd_snaps, snapentry_compare,
   1049    789    ahrens 	    sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node));
   1050    789    ahrens 	return (vp);
   1051   8845       amw }
   1052   8845       amw 
   1053   8845       amw vnode_t *
   1054   8845       amw zfsctl_mknode_shares(vnode_t *pvp)
   1055   8845       amw {
   1056   8845       amw 	vnode_t *vp;
   1057   8845       amw 	zfsctl_node_t *sdp;
   1058   8845       amw 
   1059   8845       amw 	vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp,
   1060   8845       amw 	    zfsctl_ops_shares, NULL, NULL, MAXNAMELEN,
   1061   8845       amw 	    NULL, NULL);
   1062   8845       amw 	sdp = vp->v_data;
   1063   8845       amw 	sdp->zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime;
   1064   8845       amw 	return (vp);
   1065   8845       amw 
   1066   8845       amw }
   1067   8845       amw 
   1068   8845       amw /* ARGSUSED */
   1069   8845       amw static int
   1070   8845       amw zfsctl_shares_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
   1071   8845       amw     caller_context_t *ct)
   1072   8845       amw {
   1073   8845       amw 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
   1074   8845       amw 	znode_t *dzp;
   1075   8845       amw 	int error;
   1076   8845       amw 
   1077   8845       amw 	ZFS_ENTER(zfsvfs);
   1078   9030      Mark 	if (zfsvfs->z_shares_dir == 0) {
   1079   9030      Mark 		ZFS_EXIT(zfsvfs);
   1080   9030      Mark 		return (ENOTSUP);
   1081   9030      Mark 	}
   1082   8845       amw 	if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
   1083   8845       amw 		error = VOP_GETATTR(ZTOV(dzp), vap, flags, cr, ct);
   1084   8845       amw 		VN_RELE(ZTOV(dzp));
   1085   8845       amw 	}
   1086   8845       amw 	ZFS_EXIT(zfsvfs);
   1087   8845       amw 	return (error);
   1088   8845       amw 
   1089   8845       amw 
   1090    789    ahrens }
   1091    789    ahrens 
   1092    789    ahrens /* ARGSUSED */
   1093    789    ahrens static int
   1094   5331       amw zfsctl_snapdir_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
   1095   5331       amw     caller_context_t *ct)
   1096    789    ahrens {
   1097    789    ahrens 	zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
   1098    789    ahrens 	zfsctl_snapdir_t *sdp = vp->v_data;
   1099    789    ahrens 
   1100    789    ahrens 	ZFS_ENTER(zfsvfs);
   1101    789    ahrens 	zfsctl_common_getattr(vp, vap);
   1102    789    ahrens 	vap->va_nodeid = gfs_file_inode(vp);
   1103    789    ahrens 	vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2;
   1104  10373     chris 	vap->va_ctime = vap->va_mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
   1105    789    ahrens 	ZFS_EXIT(zfsvfs);
   1106    789    ahrens 
   1107    789    ahrens 	return (0);
   1108    789    ahrens }
   1109    789    ahrens 
   1110   1566    maybee /* ARGSUSED */
   1111    789    ahrens static void
   1112   5331       amw zfsctl_snapdir_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
   1113    789    ahrens {
   1114    789    ahrens 	zfsctl_snapdir_t *sdp = vp->v_data;
   1115   1566    maybee 	void *private;
   1116    789    ahrens 
   1117   1566    maybee 	private = gfs_dir_inactive(vp);
   1118   1566    maybee 	if (private != NULL) {
   1119   1566    maybee 		ASSERT(avl_numnodes(&sdp->sd_snaps) == 0);
   1120   1566    maybee 		mutex_destroy(&sdp->sd_lock);
   1121   1566    maybee 		avl_destroy(&sdp->sd_snaps);
   1122   1566    maybee 		kmem_free(private, sizeof (zfsctl_snapdir_t));
   1123   1566    maybee 	}
   1124    789    ahrens }
   1125    789    ahrens 
   1126    789    ahrens static const fs_operation_def_t zfsctl_tops_snapdir[] = {
   1127   3898       rsb 	{ VOPNAME_OPEN,		{ .vop_open = zfsctl_common_open }	},
   1128   3898       rsb 	{ VOPNAME_CLOSE,	{ .vop_close = zfsctl_common_close }	},
   1129   3898       rsb 	{ VOPNAME_IOCTL,	{ .error = fs_inval }			},
   1130   3898       rsb 	{ VOPNAME_GETATTR,	{ .vop_getattr = zfsctl_snapdir_getattr } },
   1131   3898       rsb 	{ VOPNAME_ACCESS,	{ .vop_access = zfsctl_common_access }	},
   1132   3898       rsb 	{ VOPNAME_RENAME,	{ .vop_rename = zfsctl_snapdir_rename }	},
   1133   3898       rsb 	{ VOPNAME_RMDIR,	{ .vop_rmdir = zfsctl_snapdir_remove }	},
   1134   4543     marks 	{ VOPNAME_MKDIR,	{ .vop_mkdir = zfsctl_snapdir_mkdir }	},
   1135   3898       rsb 	{ VOPNAME_READDIR,	{ .vop_readdir = gfs_vop_readdir }	},
   1136   3898       rsb 	{ VOPNAME_LOOKUP,	{ .vop_lookup = zfsctl_snapdir_lookup }	},
   1137   3898       rsb 	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek }			},
   1138   3898       rsb 	{ VOPNAME_INACTIVE,	{ .vop_inactive = zfsctl_snapdir_inactive } },
   1139   3898       rsb 	{ VOPNAME_FID,		{ .vop_fid = zfsctl_common_fid }	},
   1140   8845       amw 	{ NULL }
   1141   8845       amw };
   1142   8845       amw 
   1143   8845       amw static const fs_operation_def_t zfsctl_tops_shares[] = {
   1144   8845       amw 	{ VOPNAME_OPEN,		{ .vop_open = zfsctl_common_open }	},
   1145   8845       amw 	{ VOPNAME_CLOSE,	{ .vop_close = zfsctl_common_close }	},
   1146   8845       amw 	{ VOPNAME_IOCTL,	{ .error = fs_inval }			},
   1147   8845       amw 	{ VOPNAME_GETATTR,	{ .vop_getattr = zfsctl_shares_getattr } },
   1148   8845       amw 	{ VOPNAME_ACCESS,	{ .vop_access = zfsctl_common_access }	},
   1149   8845       amw 	{ VOPNAME_READDIR,	{ .vop_readdir = zfsctl_shares_readdir } },
   1150   8845       amw 	{ VOPNAME_LOOKUP,	{ .vop_lookup = zfsctl_shares_lookup }	},
   1151   8845       amw 	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek }			},
   1152   8845       amw 	{ VOPNAME_INACTIVE,	{ .vop_inactive = gfs_vop_inactive } },
   1153   8845       amw 	{ VOPNAME_FID,		{ .vop_fid = zfsctl_shares_fid } },
   1154    789    ahrens 	{ NULL }
   1155    789    ahrens };
   1156    789    ahrens 
   1157   5326  ek110237 /*
   1158   5326  ek110237  * pvp is the GFS vnode '.zfs/snapshot'.
   1159   5326  ek110237  *
   1160   5326  ek110237  * This creates a GFS node under '.zfs/snapshot' representing each
   1161   5326  ek110237  * snapshot.  This newly created GFS node is what we mount snapshot
   1162   5326  ek110237  * vfs_t's ontop of.
   1163   5326  ek110237  */
   1164    789    ahrens static vnode_t *
   1165    789    ahrens zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset)
   1166    789    ahrens {
   1167    789    ahrens 	vnode_t *vp;
   1168    789    ahrens 	zfsctl_node_t *zcp;
   1169    789    ahrens 
   1170    789    ahrens 	vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp,
   1171    789    ahrens 	    zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL);
   1172    789    ahrens 	zcp = vp->v_data;
   1173    789    ahrens 	zcp->zc_id = objset;
   1174    789    ahrens 
   1175    789    ahrens 	return (vp);
   1176    789    ahrens }
   1177    789    ahrens 
   1178    789    ahrens static void
   1179   5331       amw zfsctl_snapshot_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
   1180    789    ahrens {
   1181    789    ahrens 	zfsctl_snapdir_t *sdp;
   1182    789    ahrens 	zfs_snapentry_t *sep, *next;
   1183    789    ahrens 	vnode_t *dvp;
   1184    789    ahrens 
   1185   6492      timh 	VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0);
   1186    789    ahrens 	sdp = dvp->v_data;
   1187    789    ahrens 
   1188    789    ahrens 	mutex_enter(&sdp->sd_lock);
   1189    789    ahrens 
   1190    789    ahrens 	if (vp->v_count > 1) {
   1191    789    ahrens 		mutex_exit(&sdp->sd_lock);
   1192    789    ahrens 		return;
   1193    789    ahrens 	}
   1194    789    ahrens 	ASSERT(!vn_ismntpt(vp));
   1195    789    ahrens 
   1196    789    ahrens 	sep = avl_first(&sdp->sd_snaps);
   1197    789    ahrens 	while (sep != NULL) {
   1198    789    ahrens 		next = AVL_NEXT(&sdp->sd_snaps, sep);
   1199    789    ahrens 
   1200    789    ahrens 		if (sep->se_root == vp) {
   1201    789    ahrens 			avl_remove(&sdp->sd_snaps, sep);
   1202    789    ahrens 			kmem_free(sep->se_name, strlen(sep->se_name) + 1);
   1203    789    ahrens 			kmem_free(sep, sizeof (zfs_snapentry_t));
   1204    789    ahrens 			break;
   1205    789    ahrens 		}
   1206    789    ahrens 		sep = next;
   1207    789    ahrens 	}
   1208    789    ahrens 	ASSERT(sep != NULL);
   1209    789    ahrens 
   1210    789    ahrens 	mutex_exit(&sdp->sd_lock);
   1211    789    ahrens 	VN_RELE(dvp);
   1212    789    ahrens 
   1213   1566    maybee 	/*
   1214   1566    maybee 	 * Dispose of the vnode for the snapshot mount point.
   1215   1566    maybee 	 * This is safe to do because once this entry has been removed
   1216   1566    maybee 	 * from the AVL tree, it can't be found again, so cannot become
   1217   1566    maybee 	 * "active".  If we lookup the same name again we will end up
   1218   1566    maybee 	 * creating a new vnode.
   1219   1566    maybee 	 */
   1220   5331       amw 	gfs_vop_inactive(vp, cr, ct);
   1221    789    ahrens }
   1222    789    ahrens 
   1223    789    ahrens 
   1224    789    ahrens /*
   1225    789    ahrens  * These VP's should never see the light of day.  They should always
   1226    789    ahrens  * be covered.
   1227    789    ahrens  */
   1228    789    ahrens static const fs_operation_def_t zfsctl_tops_snapshot[] = {
   1229   3898       rsb 	VOPNAME_INACTIVE, { .vop_inactive =  zfsctl_snapshot_inactive },
   1230    789    ahrens 	NULL, NULL
   1231    789    ahrens };
   1232    789    ahrens 
   1233    789    ahrens int
   1234    789    ahrens zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp)
   1235    789    ahrens {
   1236    789    ahrens 	zfsvfs_t *zfsvfs = vfsp->vfs_data;
   1237    789    ahrens 	vnode_t *dvp, *vp;
   1238    789    ahrens 	zfsctl_snapdir_t *sdp;
   1239    789    ahrens 	zfsctl_node_t *zcp;
   1240    789    ahrens 	zfs_snapentry_t *sep;
   1241    789    ahrens 	int error;
   1242    789    ahrens 
   1243    789    ahrens 	ASSERT(zfsvfs->z_ctldir != NULL);
   1244    789    ahrens 	error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
   1245   5331       amw 	    NULL, 0, NULL, kcred, NULL, NULL, NULL);
   1246    789    ahrens 	if (error != 0)
   1247    789    ahrens 		return (error);
   1248    789    ahrens 	sdp = dvp->v_data;
   1249    789    ahrens 
   1250    789    ahrens 	mutex_enter(&sdp->sd_lock);
   1251    789    ahrens 	sep = avl_first(&sdp->sd_snaps);
   1252    789    ahrens 	while (sep != NULL) {
   1253    789    ahrens 		vp = sep->se_root;
   1254    789    ahrens 		zcp = vp->v_data;
   1255    789    ahrens 		if (zcp->zc_id == objsetid)
   1256    789    ahrens 			break;
   1257    789    ahrens 
   1258    789    ahrens 		sep = AVL_NEXT(&sdp->sd_snaps, sep);
   1259    789    ahrens 	}
   1260    789    ahrens 
   1261    789    ahrens 	if (sep != NULL) {
   1262    789    ahrens 		VN_HOLD(vp);
   1263   5326  ek110237 		/*
   1264   5326  ek110237 		 * Return the mounted root rather than the covered mount point.
   1265   5326  ek110237 		 * Takes the GFS vnode at .zfs/snapshot/<snapshot objsetid>
   1266   5326  ek110237 		 * and returns the ZFS vnode mounted on top of the GFS node.
   1267   5326  ek110237 		 * This ZFS vnode is the root of the vfs for objset 'objsetid'.
   1268   5326  ek110237 		 */
   1269    789    ahrens 		error = traverse(&vp);
   1270   1589    maybee 		if (error == 0) {
   1271   1589    maybee 			if (vp == sep->se_root)
   1272   1589    maybee 				error = EINVAL;
   1273   1589    maybee 			else
   1274   1589    maybee 				*zfsvfsp = VTOZ(vp)->z_zfsvfs;
   1275   1589    maybee 		}
   1276   1572  nd150628 		mutex_exit(&sdp->sd_lock);
   1277    789    ahrens 		VN_RELE(vp);
   1278    789    ahrens 	} else {
   1279    789    ahrens 		error = EINVAL;
   1280   1572  nd150628 		mutex_exit(&sdp->sd_lock);
   1281    789    ahrens 	}
   1282    789    ahrens 
   1283    789    ahrens 	VN_RELE(dvp);
   1284    789    ahrens 
   1285    789    ahrens 	return (error);
   1286    789    ahrens }
   1287    789    ahrens 
   1288    789    ahrens /*
   1289    789    ahrens  * Unmount any snapshots for the given filesystem.  This is called from
   1290    789    ahrens  * zfs_umount() - if we have a ctldir, then go through and unmount all the
   1291    789    ahrens  * snapshots.
   1292    789    ahrens  */
   1293    789    ahrens int
   1294    789    ahrens zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr)
   1295    789    ahrens {
   1296    789    ahrens 	zfsvfs_t *zfsvfs = vfsp->vfs_data;
   1297   6068  ck153898 	vnode_t *dvp;
   1298    789    ahrens 	zfsctl_snapdir_t *sdp;
   1299    789    ahrens 	zfs_snapentry_t *sep, *next;
   1300    789    ahrens 	int error;
   1301    789    ahrens 
   1302    789    ahrens 	ASSERT(zfsvfs->z_ctldir != NULL);
   1303    789    ahrens 	error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
   1304   5331       amw 	    NULL, 0, NULL, cr, NULL, NULL, NULL);
   1305    789    ahrens 	if (error != 0)
   1306    789    ahrens 		return (error);
   1307    789    ahrens 	sdp = dvp->v_data;
   1308    789    ahrens 
   1309    789    ahrens 	mutex_enter(&sdp->sd_lock);
   1310    789    ahrens 
   1311    789    ahrens 	sep = avl_first(&sdp->sd_snaps);
   1312    789    ahrens 	while (sep != NULL) {
   1313    789    ahrens 		next = AVL_NEXT(&sdp->sd_snaps, sep);
   1314    789    ahrens 
   1315    789    ahrens 		/*
   1316    789    ahrens 		 * If this snapshot is not mounted, then it must
   1317    789    ahrens 		 * have just been unmounted by somebody else, and
   1318    789    ahrens 		 * will be cleaned up by zfsctl_snapdir_inactive().
   1319    789    ahrens 		 */
   1320   6068  ck153898 		if (vn_ismntpt(sep->se_root)) {
   1321   6068  ck153898 			avl_remove(&sdp->sd_snaps, sep);
   1322   6068  ck153898 			error = zfsctl_unmount_snap(sep, fflags, cr);
   1323    789    ahrens 			if (error) {
   1324   6068  ck153898 				avl_add(&sdp->sd_snaps, sep);
   1325   6068  ck153898 				break;
   1326    789    ahrens 			}
   1327    789    ahrens 		}
   1328    789    ahrens 		sep = next;
   1329    789    ahrens 	}
   1330   6068  ck153898 
   1331    789    ahrens 	mutex_exit(&sdp->sd_lock);
   1332    789    ahrens 	VN_RELE(dvp);
   1333    789    ahrens 
   1334    789    ahrens 	return (error);
   1335    789    ahrens }
   1336