1789Sahrens /* 2789Sahrens * CDDL HEADER START 3789Sahrens * 4789Sahrens * The contents of this file are subject to the terms of the 51512Sek110237 * Common Development and Distribution License (the "License"). 61512Sek110237 * You may not use this file except in compliance with the License. 7789Sahrens * 8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9789Sahrens * or http://www.opensolaris.org/os/licensing. 10789Sahrens * See the License for the specific language governing permissions 11789Sahrens * and limitations under the License. 12789Sahrens * 13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15789Sahrens * If applicable, add the following below this CDDL HEADER, with the 16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18789Sahrens * 19789Sahrens * CDDL HEADER END 20789Sahrens */ 21789Sahrens /* 226068Sck153898 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23789Sahrens * Use is subject to license terms. 24789Sahrens */ 25789Sahrens 26789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 27789Sahrens 28789Sahrens /* 29789Sahrens * ZFS control directory (a.k.a. ".zfs") 30789Sahrens * 31789Sahrens * This directory provides a common location for all ZFS meta-objects. 32789Sahrens * Currently, this is only the 'snapshot' directory, but this may expand in the 33789Sahrens * future. The elements are built using the GFS primitives, as the hierarchy 34789Sahrens * does not actually exist on disk. 35789Sahrens * 36789Sahrens * For 'snapshot', we don't want to have all snapshots always mounted, because 37789Sahrens * this would take up a huge amount of space in /etc/mnttab. We have three 38789Sahrens * types of objects: 39789Sahrens * 40789Sahrens * ctldir ------> snapshotdir -------> snapshot 41789Sahrens * | 42789Sahrens * | 43789Sahrens * V 44789Sahrens * mounted fs 45789Sahrens * 46789Sahrens * The 'snapshot' node contains just enough information to lookup '..' and act 47789Sahrens * as a mountpoint for the snapshot. Whenever we lookup a specific snapshot, we 48789Sahrens * perform an automount of the underlying filesystem and return the 49789Sahrens * corresponding vnode. 50789Sahrens * 51789Sahrens * All mounts are handled automatically by the kernel, but unmounts are 52789Sahrens * (currently) handled from user land. The main reason is that there is no 53789Sahrens * reliable way to auto-unmount the filesystem when it's "no longer in use". 54789Sahrens * When the user unmounts a filesystem, we call zfsctl_unmount(), which 55789Sahrens * unmounts any snapshots within the snapshot directory. 565326Sek110237 * 575326Sek110237 * The '.zfs', '.zfs/snapshot', and all directories created under 585326Sek110237 * '.zfs/snapshot' (ie: '.zfs/snapshot/<snapname>') are all GFS nodes and 595326Sek110237 * share the same vfs_t as the head filesystem (what '.zfs' lives under). 605326Sek110237 * 615326Sek110237 * File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>' 625326Sek110237 * (ie: snapshots) are ZFS nodes and have their own unique vfs_t. 635326Sek110237 * However, vnodes within these mounted on file systems have their v_vfsp 645326Sek110237 * fields set to the head filesystem to make NFS happy (see 656068Sck153898 * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t 666068Sck153898 * so that it cannot be freed until all snapshots have been unmounted. 67789Sahrens */ 68789Sahrens 69789Sahrens #include <fs/fs_subr.h> 70789Sahrens #include <sys/zfs_ctldir.h> 71789Sahrens #include <sys/zfs_ioctl.h> 72789Sahrens #include <sys/zfs_vfsops.h> 733898Srsb #include <sys/vfs_opreg.h> 74789Sahrens #include <sys/gfs.h> 75789Sahrens #include <sys/stat.h> 76789Sahrens #include <sys/dmu.h> 774543Smarks #include <sys/dsl_deleg.h> 78789Sahrens #include <sys/mount.h> 796492Stimh #include <sys/sunddi.h> 80789Sahrens 816658Smarks #include "zfs_namecheck.h" 826658Smarks 836068Sck153898 typedef struct zfsctl_node { 846068Sck153898 gfs_dir_t zc_gfs_private; 856068Sck153898 uint64_t zc_id; 866068Sck153898 timestruc_t zc_cmtime; /* ctime and mtime, always the same */ 876068Sck153898 } zfsctl_node_t; 886068Sck153898 896068Sck153898 typedef struct zfsctl_snapdir { 906068Sck153898 zfsctl_node_t sd_node; 916068Sck153898 kmutex_t sd_lock; 926068Sck153898 avl_tree_t sd_snaps; 936068Sck153898 } zfsctl_snapdir_t; 946068Sck153898 95789Sahrens typedef struct { 96789Sahrens char *se_name; 97789Sahrens vnode_t *se_root; 98789Sahrens avl_node_t se_node; 99789Sahrens } zfs_snapentry_t; 100789Sahrens 101789Sahrens static int 102789Sahrens snapentry_compare(const void *a, const void *b) 103789Sahrens { 104789Sahrens const zfs_snapentry_t *sa = a; 105789Sahrens const zfs_snapentry_t *sb = b; 106789Sahrens int ret = strcmp(sa->se_name, sb->se_name); 107789Sahrens 108789Sahrens if (ret < 0) 109789Sahrens return (-1); 110789Sahrens else if (ret > 0) 111789Sahrens return (1); 112789Sahrens else 113789Sahrens return (0); 114789Sahrens } 115789Sahrens 116789Sahrens vnodeops_t *zfsctl_ops_root; 117789Sahrens vnodeops_t *zfsctl_ops_snapdir; 118789Sahrens vnodeops_t *zfsctl_ops_snapshot; 119789Sahrens 120789Sahrens static const fs_operation_def_t zfsctl_tops_root[]; 121789Sahrens static const fs_operation_def_t zfsctl_tops_snapdir[]; 122789Sahrens static const fs_operation_def_t zfsctl_tops_snapshot[]; 123789Sahrens 124789Sahrens static vnode_t *zfsctl_mknode_snapdir(vnode_t *); 125789Sahrens static vnode_t *zfsctl_snapshot_mknode(vnode_t *, uint64_t objset); 1266068Sck153898 static int zfsctl_unmount_snap(zfs_snapentry_t *, int, cred_t *); 127789Sahrens 128789Sahrens static gfs_opsvec_t zfsctl_opsvec[] = { 129789Sahrens { ".zfs", zfsctl_tops_root, &zfsctl_ops_root }, 130789Sahrens { ".zfs/snapshot", zfsctl_tops_snapdir, &zfsctl_ops_snapdir }, 131789Sahrens { ".zfs/snapshot/vnode", zfsctl_tops_snapshot, &zfsctl_ops_snapshot }, 132789Sahrens { NULL } 133789Sahrens }; 134789Sahrens 135789Sahrens /* 136789Sahrens * Root directory elements. We have only a single static entry, 'snapshot'. 137789Sahrens */ 138789Sahrens static gfs_dirent_t zfsctl_root_entries[] = { 139789Sahrens { "snapshot", zfsctl_mknode_snapdir, GFS_CACHE_VNODE }, 140789Sahrens { NULL } 141789Sahrens }; 142789Sahrens 143789Sahrens /* include . and .. in the calculation */ 144789Sahrens #define NROOT_ENTRIES ((sizeof (zfsctl_root_entries) / \ 145789Sahrens sizeof (gfs_dirent_t)) + 1) 146789Sahrens 147789Sahrens 148789Sahrens /* 149789Sahrens * Initialize the various GFS pieces we'll need to create and manipulate .zfs 150789Sahrens * directories. This is called from the ZFS init routine, and initializes the 151789Sahrens * vnode ops vectors that we'll be using. 152789Sahrens */ 153789Sahrens void 154789Sahrens zfsctl_init(void) 155789Sahrens { 156789Sahrens VERIFY(gfs_make_opsvec(zfsctl_opsvec) == 0); 157789Sahrens } 158789Sahrens 159789Sahrens void 160789Sahrens zfsctl_fini(void) 161789Sahrens { 162789Sahrens /* 163789Sahrens * Remove vfsctl vnode ops 164789Sahrens */ 165789Sahrens if (zfsctl_ops_root) 166789Sahrens vn_freevnodeops(zfsctl_ops_root); 167789Sahrens if (zfsctl_ops_snapdir) 168789Sahrens vn_freevnodeops(zfsctl_ops_snapdir); 169789Sahrens if (zfsctl_ops_snapshot) 170789Sahrens vn_freevnodeops(zfsctl_ops_snapshot); 171789Sahrens 172789Sahrens zfsctl_ops_root = NULL; 173789Sahrens zfsctl_ops_snapdir = NULL; 174789Sahrens zfsctl_ops_snapshot = NULL; 175789Sahrens } 176789Sahrens 177789Sahrens /* 178789Sahrens * Return the inode number associated with the 'snapshot' directory. 179789Sahrens */ 180789Sahrens /* ARGSUSED */ 181789Sahrens static ino64_t 182789Sahrens zfsctl_root_inode_cb(vnode_t *vp, int index) 183789Sahrens { 184789Sahrens ASSERT(index == 0); 185789Sahrens return (ZFSCTL_INO_SNAPDIR); 186789Sahrens } 187789Sahrens 188789Sahrens /* 189789Sahrens * Create the '.zfs' directory. This directory is cached as part of the VFS 190789Sahrens * structure. This results in a hold on the vfs_t. The code in zfs_umount() 191789Sahrens * therefore checks against a vfs_count of 2 instead of 1. This reference 192789Sahrens * is removed when the ctldir is destroyed in the unmount. 193789Sahrens */ 194789Sahrens void 195789Sahrens zfsctl_create(zfsvfs_t *zfsvfs) 196789Sahrens { 1971571Sek110237 vnode_t *vp, *rvp; 198789Sahrens zfsctl_node_t *zcp; 199789Sahrens 200789Sahrens ASSERT(zfsvfs->z_ctldir == NULL); 201789Sahrens 202789Sahrens vp = gfs_root_create(sizeof (zfsctl_node_t), zfsvfs->z_vfs, 203789Sahrens zfsctl_ops_root, ZFSCTL_INO_ROOT, zfsctl_root_entries, 204789Sahrens zfsctl_root_inode_cb, MAXNAMELEN, NULL, NULL); 205789Sahrens zcp = vp->v_data; 206789Sahrens zcp->zc_id = ZFSCTL_INO_ROOT; 207789Sahrens 2081571Sek110237 VERIFY(VFS_ROOT(zfsvfs->z_vfs, &rvp) == 0); 2091571Sek110237 ZFS_TIME_DECODE(&zcp->zc_cmtime, VTOZ(rvp)->z_phys->zp_crtime); 2101571Sek110237 VN_RELE(rvp); 2111571Sek110237 212789Sahrens /* 213789Sahrens * We're only faking the fact that we have a root of a filesystem for 214789Sahrens * the sake of the GFS interfaces. Undo the flag manipulation it did 215789Sahrens * for us. 216789Sahrens */ 217789Sahrens vp->v_flag &= ~(VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT); 218789Sahrens 219789Sahrens zfsvfs->z_ctldir = vp; 220789Sahrens } 221789Sahrens 222789Sahrens /* 2231298Sperrin * Destroy the '.zfs' directory. Only called when the filesystem is unmounted. 2241298Sperrin * There might still be more references if we were force unmounted, but only 2251298Sperrin * new zfs_inactive() calls can occur and they don't reference .zfs 226789Sahrens */ 227789Sahrens void 228789Sahrens zfsctl_destroy(zfsvfs_t *zfsvfs) 229789Sahrens { 230789Sahrens VN_RELE(zfsvfs->z_ctldir); 231789Sahrens zfsvfs->z_ctldir = NULL; 232789Sahrens } 233789Sahrens 234789Sahrens /* 235789Sahrens * Given a root znode, retrieve the associated .zfs directory. 236789Sahrens * Add a hold to the vnode and return it. 237789Sahrens */ 238789Sahrens vnode_t * 239789Sahrens zfsctl_root(znode_t *zp) 240789Sahrens { 241789Sahrens ASSERT(zfs_has_ctldir(zp)); 242789Sahrens VN_HOLD(zp->z_zfsvfs->z_ctldir); 243789Sahrens return (zp->z_zfsvfs->z_ctldir); 244789Sahrens } 245789Sahrens 246789Sahrens /* 247789Sahrens * Common open routine. Disallow any write access. 248789Sahrens */ 249789Sahrens /* ARGSUSED */ 250789Sahrens static int 2515331Samw zfsctl_common_open(vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct) 252789Sahrens { 253789Sahrens if (flags & FWRITE) 254789Sahrens return (EACCES); 255789Sahrens 256789Sahrens return (0); 257789Sahrens } 258789Sahrens 259789Sahrens /* 260789Sahrens * Common close routine. Nothing to do here. 261789Sahrens */ 262789Sahrens /* ARGSUSED */ 263789Sahrens static int 264789Sahrens zfsctl_common_close(vnode_t *vpp, int flags, int count, offset_t off, 2655331Samw cred_t *cr, caller_context_t *ct) 266789Sahrens { 267789Sahrens return (0); 268789Sahrens } 269789Sahrens 270789Sahrens /* 271789Sahrens * Common access routine. Disallow writes. 272789Sahrens */ 273789Sahrens /* ARGSUSED */ 274789Sahrens static int 2755331Samw zfsctl_common_access(vnode_t *vp, int mode, int flags, cred_t *cr, 2765331Samw caller_context_t *ct) 277789Sahrens { 278789Sahrens if (mode & VWRITE) 279789Sahrens return (EACCES); 280789Sahrens 281789Sahrens return (0); 282789Sahrens } 283789Sahrens 284789Sahrens /* 285789Sahrens * Common getattr function. Fill in basic information. 286789Sahrens */ 287789Sahrens static void 288789Sahrens zfsctl_common_getattr(vnode_t *vp, vattr_t *vap) 289789Sahrens { 2901571Sek110237 zfsctl_node_t *zcp = vp->v_data; 2911571Sek110237 timestruc_t now; 292789Sahrens 293789Sahrens vap->va_uid = 0; 294789Sahrens vap->va_gid = 0; 295789Sahrens vap->va_rdev = 0; 296789Sahrens /* 297789Sahrens * We are a purly virtual object, so we have no 298789Sahrens * blocksize or allocated blocks. 299789Sahrens */ 300789Sahrens vap->va_blksize = 0; 301789Sahrens vap->va_nblocks = 0; 302789Sahrens vap->va_seq = 0; 303789Sahrens vap->va_fsid = vp->v_vfsp->vfs_dev; 304789Sahrens vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | 305789Sahrens S_IROTH | S_IXOTH; 306789Sahrens vap->va_type = VDIR; 307789Sahrens /* 3081571Sek110237 * We live in the now (for atime). 309789Sahrens */ 310789Sahrens gethrestime(&now); 3111571Sek110237 vap->va_atime = now; 3121571Sek110237 vap->va_mtime = vap->va_ctime = zcp->zc_cmtime; 313789Sahrens } 314789Sahrens 3155331Samw /*ARGSUSED*/ 316789Sahrens static int 3175331Samw zfsctl_common_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) 318789Sahrens { 319789Sahrens zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; 320789Sahrens zfsctl_node_t *zcp = vp->v_data; 321789Sahrens uint64_t object = zcp->zc_id; 322789Sahrens zfid_short_t *zfid; 323789Sahrens int i; 324789Sahrens 325789Sahrens ZFS_ENTER(zfsvfs); 326789Sahrens 327789Sahrens if (fidp->fid_len < SHORT_FID_LEN) { 328789Sahrens fidp->fid_len = SHORT_FID_LEN; 3291512Sek110237 ZFS_EXIT(zfsvfs); 330789Sahrens return (ENOSPC); 331789Sahrens } 332789Sahrens 333789Sahrens zfid = (zfid_short_t *)fidp; 334789Sahrens 335789Sahrens zfid->zf_len = SHORT_FID_LEN; 336789Sahrens 337789Sahrens for (i = 0; i < sizeof (zfid->zf_object); i++) 338789Sahrens zfid->zf_object[i] = (uint8_t)(object >> (8 * i)); 339789Sahrens 340789Sahrens /* .zfs znodes always have a generation number of 0 */ 341789Sahrens for (i = 0; i < sizeof (zfid->zf_gen); i++) 342789Sahrens zfid->zf_gen[i] = 0; 343789Sahrens 344789Sahrens ZFS_EXIT(zfsvfs); 345789Sahrens return (0); 346789Sahrens } 347789Sahrens 348789Sahrens /* 349789Sahrens * .zfs inode namespace 350789Sahrens * 351789Sahrens * We need to generate unique inode numbers for all files and directories 352789Sahrens * within the .zfs pseudo-filesystem. We use the following scheme: 353789Sahrens * 354789Sahrens * ENTRY ZFSCTL_INODE 355789Sahrens * .zfs 1 356789Sahrens * .zfs/snapshot 2 357789Sahrens * .zfs/snapshot/<snap> objectid(snap) 358789Sahrens */ 359789Sahrens 360789Sahrens #define ZFSCTL_INO_SNAP(id) (id) 361789Sahrens 362789Sahrens /* 363789Sahrens * Get root directory attributes. 364789Sahrens */ 365789Sahrens /* ARGSUSED */ 366789Sahrens static int 3675331Samw zfsctl_root_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, 3685331Samw caller_context_t *ct) 369789Sahrens { 370789Sahrens zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; 371789Sahrens 372789Sahrens ZFS_ENTER(zfsvfs); 373789Sahrens vap->va_nodeid = ZFSCTL_INO_ROOT; 374789Sahrens vap->va_nlink = vap->va_size = NROOT_ENTRIES; 375789Sahrens 376789Sahrens zfsctl_common_getattr(vp, vap); 377789Sahrens ZFS_EXIT(zfsvfs); 378789Sahrens 379789Sahrens return (0); 380789Sahrens } 381789Sahrens 382789Sahrens /* 383789Sahrens * Special case the handling of "..". 384789Sahrens */ 385789Sahrens /* ARGSUSED */ 386789Sahrens int 387789Sahrens zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, 3885331Samw int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, 3895331Samw int *direntflags, pathname_t *realpnp) 390789Sahrens { 391789Sahrens zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; 392789Sahrens int err; 393789Sahrens 3945331Samw /* 3955331Samw * No extended attributes allowed under .zfs 3965331Samw */ 3975331Samw if (flags & LOOKUP_XATTR) 3985331Samw return (EINVAL); 3995331Samw 400789Sahrens ZFS_ENTER(zfsvfs); 401789Sahrens 402789Sahrens if (strcmp(nm, "..") == 0) { 403789Sahrens err = VFS_ROOT(dvp->v_vfsp, vpp); 404789Sahrens } else { 4056492Stimh err = gfs_vop_lookup(dvp, nm, vpp, pnp, flags, rdir, 4066492Stimh cr, ct, direntflags, realpnp); 407789Sahrens } 408789Sahrens 409789Sahrens ZFS_EXIT(zfsvfs); 410789Sahrens 411789Sahrens return (err); 412789Sahrens } 413789Sahrens 414789Sahrens static const fs_operation_def_t zfsctl_tops_root[] = { 4153898Srsb { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, 4163898Srsb { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, 4173898Srsb { VOPNAME_IOCTL, { .error = fs_inval } }, 4183898Srsb { VOPNAME_GETATTR, { .vop_getattr = zfsctl_root_getattr } }, 4193898Srsb { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } }, 4203898Srsb { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } }, 4213898Srsb { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_root_lookup } }, 4223898Srsb { VOPNAME_SEEK, { .vop_seek = fs_seek } }, 4233898Srsb { VOPNAME_INACTIVE, { .vop_inactive = gfs_vop_inactive } }, 4243898Srsb { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } }, 425789Sahrens { NULL } 426789Sahrens }; 427789Sahrens 428789Sahrens static int 429789Sahrens zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname) 430789Sahrens { 431789Sahrens objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os; 432789Sahrens 4336658Smarks if (snapshot_namecheck(name, NULL, NULL) != 0) 4346658Smarks return (EILSEQ); 435789Sahrens dmu_objset_name(os, zname); 4361154Smaybee if (strlen(zname) + 1 + strlen(name) >= len) 4371154Smaybee return (ENAMETOOLONG); 438789Sahrens (void) strcat(zname, "@"); 439789Sahrens (void) strcat(zname, name); 440789Sahrens return (0); 441789Sahrens } 442789Sahrens 4436068Sck153898 static int 4446068Sck153898 zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr) 445789Sahrens { 4466068Sck153898 vnode_t *svp = sep->se_root; 4476068Sck153898 int error; 448789Sahrens 4496068Sck153898 ASSERT(vn_ismntpt(svp)); 450789Sahrens 451789Sahrens /* this will be dropped by dounmount() */ 4526068Sck153898 if ((error = vn_vfswlock(svp)) != 0) 4536068Sck153898 return (error); 454789Sahrens 4556068Sck153898 VN_HOLD(svp); 4566068Sck153898 error = dounmount(vn_mountedvfs(svp), fflags, cr); 4576068Sck153898 if (error) { 4586068Sck153898 VN_RELE(svp); 4596068Sck153898 return (error); 4601589Smaybee } 4616068Sck153898 VFS_RELE(svp->v_vfsp); 4626068Sck153898 /* 4636068Sck153898 * We can't use VN_RELE(), as that will try to invoke 4646068Sck153898 * zfsctl_snapdir_inactive(), which would cause us to destroy 4656068Sck153898 * the sd_lock mutex held by our caller. 4666068Sck153898 */ 4676068Sck153898 ASSERT(svp->v_count == 1); 4686068Sck153898 gfs_vop_inactive(svp, cr, NULL); 469789Sahrens 470789Sahrens kmem_free(sep->se_name, strlen(sep->se_name) + 1); 471789Sahrens kmem_free(sep, sizeof (zfs_snapentry_t)); 472789Sahrens 473789Sahrens return (0); 474789Sahrens } 475789Sahrens 4761154Smaybee static void 477789Sahrens zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm) 478789Sahrens { 479789Sahrens avl_index_t where; 480789Sahrens vfs_t *vfsp; 481789Sahrens refstr_t *pathref; 482789Sahrens char newpath[MAXNAMELEN]; 483789Sahrens char *tail; 484789Sahrens 485789Sahrens ASSERT(MUTEX_HELD(&sdp->sd_lock)); 486789Sahrens ASSERT(sep != NULL); 487789Sahrens 488789Sahrens vfsp = vn_mountedvfs(sep->se_root); 489789Sahrens ASSERT(vfsp != NULL); 490789Sahrens 4911154Smaybee vfs_lock_wait(vfsp); 492789Sahrens 493789Sahrens /* 494789Sahrens * Change the name in the AVL tree. 495789Sahrens */ 496789Sahrens avl_remove(&sdp->sd_snaps, sep); 497789Sahrens kmem_free(sep->se_name, strlen(sep->se_name) + 1); 498789Sahrens sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP); 499789Sahrens (void) strcpy(sep->se_name, nm); 500789Sahrens VERIFY(avl_find(&sdp->sd_snaps, sep, &where) == NULL); 501789Sahrens avl_insert(&sdp->sd_snaps, sep, where); 502789Sahrens 503789Sahrens /* 504789Sahrens * Change the current mountpoint info: 505789Sahrens * - update the tail of the mntpoint path 506789Sahrens * - update the tail of the resource path 507789Sahrens */ 508789Sahrens pathref = vfs_getmntpoint(vfsp); 5092417Sahrens (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath)); 5102417Sahrens VERIFY((tail = strrchr(newpath, '/')) != NULL); 5112417Sahrens *(tail+1) = '\0'; 5122417Sahrens ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath)); 513789Sahrens (void) strcat(newpath, nm); 514789Sahrens refstr_rele(pathref); 515789Sahrens vfs_setmntpoint(vfsp, newpath); 516789Sahrens 517789Sahrens pathref = vfs_getresource(vfsp); 5182417Sahrens (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath)); 5192417Sahrens VERIFY((tail = strrchr(newpath, '@')) != NULL); 5202417Sahrens *(tail+1) = '\0'; 5212417Sahrens ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath)); 522789Sahrens (void) strcat(newpath, nm); 523789Sahrens refstr_rele(pathref); 524789Sahrens vfs_setresource(vfsp, newpath); 525789Sahrens 526789Sahrens vfs_unlock(vfsp); 527789Sahrens } 528789Sahrens 5295331Samw /*ARGSUSED*/ 530789Sahrens static int 531789Sahrens zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, 5325331Samw cred_t *cr, caller_context_t *ct, int flags) 533789Sahrens { 534789Sahrens zfsctl_snapdir_t *sdp = sdvp->v_data; 535789Sahrens zfs_snapentry_t search, *sep; 5366492Stimh zfsvfs_t *zfsvfs; 537789Sahrens avl_index_t where; 538789Sahrens char from[MAXNAMELEN], to[MAXNAMELEN]; 5396492Stimh char real[MAXNAMELEN]; 540789Sahrens int err; 541789Sahrens 5426492Stimh zfsvfs = sdvp->v_vfsp->vfs_data; 5436492Stimh ZFS_ENTER(zfsvfs); 5446492Stimh 5456492Stimh if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { 5466492Stimh err = dmu_snapshot_realname(zfsvfs->z_os, snm, real, 5476492Stimh MAXNAMELEN, NULL); 5486492Stimh if (err == 0) { 5496492Stimh snm = real; 5506492Stimh } else if (err != ENOTSUP) { 5516492Stimh ZFS_EXIT(zfsvfs); 5526492Stimh return (err); 5536492Stimh } 5546492Stimh } 5556492Stimh 5566492Stimh ZFS_EXIT(zfsvfs); 5576492Stimh 5581154Smaybee err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from); 5596492Stimh if (!err) 5606492Stimh err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to); 5616492Stimh if (!err) 5626492Stimh err = zfs_secpolicy_rename_perms(from, to, cr); 5631154Smaybee if (err) 5641154Smaybee return (err); 5654543Smarks 566789Sahrens /* 567789Sahrens * Cannot move snapshots out of the snapdir. 568789Sahrens */ 569789Sahrens if (sdvp != tdvp) 570789Sahrens return (EINVAL); 571789Sahrens 572789Sahrens if (strcmp(snm, tnm) == 0) 573789Sahrens return (0); 574789Sahrens 575789Sahrens mutex_enter(&sdp->sd_lock); 576789Sahrens 577789Sahrens search.se_name = (char *)snm; 5781154Smaybee if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) == NULL) { 5791154Smaybee mutex_exit(&sdp->sd_lock); 5801154Smaybee return (ENOENT); 581789Sahrens } 582789Sahrens 5834007Smmusante err = dmu_objset_rename(from, to, B_FALSE); 5841154Smaybee if (err == 0) 5851154Smaybee zfsctl_rename_snap(sdp, sep, tnm); 586789Sahrens 587789Sahrens mutex_exit(&sdp->sd_lock); 588789Sahrens 589789Sahrens return (err); 590789Sahrens } 591789Sahrens 592789Sahrens /* ARGSUSED */ 593789Sahrens static int 5945331Samw zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, 5955331Samw caller_context_t *ct, int flags) 596789Sahrens { 597789Sahrens zfsctl_snapdir_t *sdp = dvp->v_data; 5986068Sck153898 zfs_snapentry_t *sep; 5996068Sck153898 zfs_snapentry_t search; 6006492Stimh zfsvfs_t *zfsvfs; 601789Sahrens char snapname[MAXNAMELEN]; 6026492Stimh char real[MAXNAMELEN]; 603789Sahrens int err; 604789Sahrens 6056492Stimh zfsvfs = dvp->v_vfsp->vfs_data; 6066492Stimh ZFS_ENTER(zfsvfs); 6076492Stimh 6086492Stimh if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { 6096492Stimh 6106492Stimh err = dmu_snapshot_realname(zfsvfs->z_os, name, real, 6116492Stimh MAXNAMELEN, NULL); 6126492Stimh if (err == 0) { 6136492Stimh name = real; 6146492Stimh } else if (err != ENOTSUP) { 6156492Stimh ZFS_EXIT(zfsvfs); 6166492Stimh return (err); 6176492Stimh } 6186492Stimh } 6196492Stimh 6206492Stimh ZFS_EXIT(zfsvfs); 6216492Stimh 6221154Smaybee err = zfsctl_snapshot_zname(dvp, name, MAXNAMELEN, snapname); 6236492Stimh if (!err) 6246492Stimh err = zfs_secpolicy_destroy_perms(snapname, cr); 6251154Smaybee if (err) 6261154Smaybee return (err); 6274543Smarks 628789Sahrens mutex_enter(&sdp->sd_lock); 629789Sahrens 6306068Sck153898 search.se_name = name; 6316068Sck153898 sep = avl_find(&sdp->sd_snaps, &search, NULL); 6326068Sck153898 if (sep) { 6336068Sck153898 avl_remove(&sdp->sd_snaps, sep); 6346068Sck153898 err = zfsctl_unmount_snap(sep, MS_FORCE, cr); 6356068Sck153898 if (err) 6366068Sck153898 avl_add(&sdp->sd_snaps, sep); 6376068Sck153898 else 6386068Sck153898 err = dmu_objset_destroy(snapname); 6396068Sck153898 } else { 6406068Sck153898 err = ENOENT; 641789Sahrens } 642789Sahrens 643789Sahrens mutex_exit(&sdp->sd_lock); 644789Sahrens 645789Sahrens return (err); 646789Sahrens } 647789Sahrens 6485326Sek110237 /* 6495326Sek110237 * This creates a snapshot under '.zfs/snapshot'. 6505326Sek110237 */ 6514543Smarks /* ARGSUSED */ 6524543Smarks static int 6534543Smarks zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, 6545331Samw cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp) 6554543Smarks { 6564543Smarks zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; 6574543Smarks char name[MAXNAMELEN]; 6584543Smarks int err; 6594543Smarks static enum symfollow follow = NO_FOLLOW; 6604543Smarks static enum uio_seg seg = UIO_SYSSPACE; 6614543Smarks 6626658Smarks if (snapshot_namecheck(dirname, NULL, NULL) != 0) 6636658Smarks return (EILSEQ); 6646658Smarks 6654543Smarks dmu_objset_name(zfsvfs->z_os, name); 6664543Smarks 6674543Smarks *vpp = NULL; 6684543Smarks 6694543Smarks err = zfs_secpolicy_snapshot_perms(name, cr); 6704543Smarks if (err) 6714543Smarks return (err); 6724543Smarks 6734543Smarks if (err == 0) { 6744543Smarks err = dmu_objset_snapshot(name, dirname, B_FALSE); 6754543Smarks if (err) 6764543Smarks return (err); 6774543Smarks err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp); 6784543Smarks } 6794543Smarks 6804543Smarks return (err); 6814543Smarks } 6824543Smarks 683789Sahrens /* 684789Sahrens * Lookup entry point for the 'snapshot' directory. Try to open the 685789Sahrens * snapshot if it exist, creating the pseudo filesystem vnode as necessary. 686789Sahrens * Perform a mount of the associated dataset on top of the vnode. 687789Sahrens */ 688789Sahrens /* ARGSUSED */ 689789Sahrens static int 690789Sahrens zfsctl_snapdir_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, 6915331Samw int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, 6925331Samw int *direntflags, pathname_t *realpnp) 693789Sahrens { 694789Sahrens zfsctl_snapdir_t *sdp = dvp->v_data; 695789Sahrens objset_t *snap; 696789Sahrens char snapname[MAXNAMELEN]; 6976492Stimh char real[MAXNAMELEN]; 698789Sahrens char *mountpoint; 699789Sahrens zfs_snapentry_t *sep, search; 700789Sahrens struct mounta margs; 701789Sahrens vfs_t *vfsp; 702789Sahrens size_t mountpoint_len; 703789Sahrens avl_index_t where; 704789Sahrens zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; 705789Sahrens int err; 706789Sahrens 7075331Samw /* 7085331Samw * No extended attributes allowed under .zfs 7095331Samw */ 7105331Samw if (flags & LOOKUP_XATTR) 7115331Samw return (EINVAL); 7125331Samw 713789Sahrens ASSERT(dvp->v_type == VDIR); 714789Sahrens 715789Sahrens if (gfs_lookup_dot(vpp, dvp, zfsvfs->z_ctldir, nm) == 0) 716789Sahrens return (0); 717789Sahrens 718789Sahrens /* 719789Sahrens * If we get a recursive call, that means we got called 720789Sahrens * from the domount() code while it was trying to look up the 721789Sahrens * spec (which looks like a local path for zfs). We need to 722789Sahrens * add some flag to domount() to tell it not to do this lookup. 723789Sahrens */ 724789Sahrens if (MUTEX_HELD(&sdp->sd_lock)) 725789Sahrens return (ENOENT); 726789Sahrens 727789Sahrens ZFS_ENTER(zfsvfs); 728789Sahrens 7296492Stimh if (flags & FIGNORECASE) { 7306492Stimh boolean_t conflict = B_FALSE; 7316492Stimh 7326492Stimh err = dmu_snapshot_realname(zfsvfs->z_os, nm, real, 7336492Stimh MAXNAMELEN, &conflict); 7346492Stimh if (err == 0) { 7356492Stimh nm = real; 7366492Stimh } else if (err != ENOTSUP) { 7376492Stimh ZFS_EXIT(zfsvfs); 7386492Stimh return (err); 7396492Stimh } 7406492Stimh if (realpnp) 7416492Stimh (void) strlcpy(realpnp->pn_buf, nm, 7426492Stimh realpnp->pn_bufsize); 7436492Stimh if (conflict && direntflags) 7446492Stimh *direntflags = ED_CASE_CONFLICT; 7456492Stimh } 7466492Stimh 747789Sahrens mutex_enter(&sdp->sd_lock); 748789Sahrens search.se_name = (char *)nm; 749789Sahrens if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) { 750789Sahrens *vpp = sep->se_root; 751789Sahrens VN_HOLD(*vpp); 7521589Smaybee err = traverse(vpp); 7531589Smaybee if (err) { 7541589Smaybee VN_RELE(*vpp); 7551589Smaybee *vpp = NULL; 7561589Smaybee } else if (*vpp == sep->se_root) { 7571589Smaybee /* 7581589Smaybee * The snapshot was unmounted behind our backs, 7591589Smaybee * try to remount it. 7601589Smaybee */ 761789Sahrens goto domount; 7626068Sck153898 } else { 7636068Sck153898 /* 7646068Sck153898 * VROOT was set during the traverse call. We need 7656068Sck153898 * to clear it since we're pretending to be part 7666068Sck153898 * of our parent's vfs. 7676068Sck153898 */ 7686068Sck153898 (*vpp)->v_flag &= ~VROOT; 7691566Smaybee } 770789Sahrens mutex_exit(&sdp->sd_lock); 771789Sahrens ZFS_EXIT(zfsvfs); 7721589Smaybee return (err); 773789Sahrens } 774789Sahrens 775789Sahrens /* 776789Sahrens * The requested snapshot is not currently mounted, look it up. 777789Sahrens */ 7781154Smaybee err = zfsctl_snapshot_zname(dvp, nm, MAXNAMELEN, snapname); 7791154Smaybee if (err) { 7801154Smaybee mutex_exit(&sdp->sd_lock); 7811154Smaybee ZFS_EXIT(zfsvfs); 782*7229Smarks /* 783*7229Smarks * handle "ls *" or "?" in a graceful manner, 784*7229Smarks * forcing EILSEQ to ENOENT. 785*7229Smarks * Since shell ultimately passes "*" or "?" as name to lookup 786*7229Smarks */ 787*7229Smarks return (err == EILSEQ ? ENOENT : err); 7881154Smaybee } 789789Sahrens if (dmu_objset_open(snapname, DMU_OST_ZFS, 7906689Smaybee DS_MODE_USER | DS_MODE_READONLY, &snap) != 0) { 791789Sahrens mutex_exit(&sdp->sd_lock); 792789Sahrens ZFS_EXIT(zfsvfs); 793789Sahrens return (ENOENT); 794789Sahrens } 795789Sahrens 796789Sahrens sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP); 797789Sahrens sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP); 798789Sahrens (void) strcpy(sep->se_name, nm); 799789Sahrens *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap)); 800789Sahrens avl_insert(&sdp->sd_snaps, sep, where); 801789Sahrens 802789Sahrens dmu_objset_close(snap); 803789Sahrens domount: 804789Sahrens mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) + 805789Sahrens strlen("/.zfs/snapshot/") + strlen(nm) + 1; 806789Sahrens mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP); 807789Sahrens (void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s", 808789Sahrens refstr_value(dvp->v_vfsp->vfs_mntpt), nm); 809789Sahrens 810789Sahrens margs.spec = snapname; 811789Sahrens margs.dir = mountpoint; 812789Sahrens margs.flags = MS_SYSSPACE | MS_NOMNTTAB; 813789Sahrens margs.fstype = "zfs"; 814789Sahrens margs.dataptr = NULL; 815789Sahrens margs.datalen = 0; 816789Sahrens margs.optptr = NULL; 817789Sahrens margs.optlen = 0; 818789Sahrens 819789Sahrens err = domount("zfs", &margs, *vpp, kcred, &vfsp); 820789Sahrens kmem_free(mountpoint, mountpoint_len); 821789Sahrens 822816Smaybee if (err == 0) { 823816Smaybee /* 824816Smaybee * Return the mounted root rather than the covered mount point. 8255326Sek110237 * Takes the GFS vnode at .zfs/snapshot/<snapname> and returns 8265326Sek110237 * the ZFS vnode mounted on top of the GFS node. This ZFS 8275326Sek110237 * vnode is the root the newly created vfsp. 828816Smaybee */ 829816Smaybee VFS_RELE(vfsp); 830816Smaybee err = traverse(vpp); 831816Smaybee } 832789Sahrens 833816Smaybee if (err == 0) { 834816Smaybee /* 8355326Sek110237 * Fix up the root vnode mounted on .zfs/snapshot/<snapname>. 8364736Sek110237 * 8374736Sek110237 * This is where we lie about our v_vfsp in order to 8385326Sek110237 * make .zfs/snapshot/<snapname> accessible over NFS 8395326Sek110237 * without requiring manual mounts of <snapname>. 840816Smaybee */ 841816Smaybee ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs); 842816Smaybee VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs; 843816Smaybee (*vpp)->v_vfsp = zfsvfs->z_vfs; 844816Smaybee (*vpp)->v_flag &= ~VROOT; 845816Smaybee } 846789Sahrens mutex_exit(&sdp->sd_lock); 847789Sahrens ZFS_EXIT(zfsvfs); 848789Sahrens 8491566Smaybee /* 8501566Smaybee * If we had an error, drop our hold on the vnode and 8511566Smaybee * zfsctl_snapshot_inactive() will clean up. 8521566Smaybee */ 8531566Smaybee if (err) { 854816Smaybee VN_RELE(*vpp); 8551566Smaybee *vpp = NULL; 8561566Smaybee } 857816Smaybee return (err); 858789Sahrens } 859789Sahrens 860789Sahrens /* ARGSUSED */ 861789Sahrens static int 8625663Sck153898 zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp, 8635663Sck153898 offset_t *offp, offset_t *nextp, void *data, int flags) 864789Sahrens { 865789Sahrens zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; 866789Sahrens char snapname[MAXNAMELEN]; 867789Sahrens uint64_t id, cookie; 8685663Sck153898 boolean_t case_conflict; 8695663Sck153898 int error; 870789Sahrens 871789Sahrens ZFS_ENTER(zfsvfs); 872789Sahrens 873789Sahrens cookie = *offp; 8745663Sck153898 error = dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, snapname, &id, 8755663Sck153898 &cookie, &case_conflict); 8765663Sck153898 if (error) { 877789Sahrens ZFS_EXIT(zfsvfs); 8785663Sck153898 if (error == ENOENT) { 8795663Sck153898 *eofp = 1; 8805663Sck153898 return (0); 8815663Sck153898 } 8825663Sck153898 return (error); 883789Sahrens } 884789Sahrens 8855663Sck153898 if (flags & V_RDDIR_ENTFLAGS) { 8865663Sck153898 edirent_t *eodp = dp; 8875663Sck153898 8885663Sck153898 (void) strcpy(eodp->ed_name, snapname); 8895663Sck153898 eodp->ed_ino = ZFSCTL_INO_SNAP(id); 8905663Sck153898 eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0; 8915663Sck153898 } else { 8925663Sck153898 struct dirent64 *odp = dp; 8935663Sck153898 8945663Sck153898 (void) strcpy(odp->d_name, snapname); 8955663Sck153898 odp->d_ino = ZFSCTL_INO_SNAP(id); 8965663Sck153898 } 897789Sahrens *nextp = cookie; 898789Sahrens 899789Sahrens ZFS_EXIT(zfsvfs); 900789Sahrens 901789Sahrens return (0); 902789Sahrens } 903789Sahrens 9045326Sek110237 /* 9055326Sek110237 * pvp is the '.zfs' directory (zfsctl_node_t). 9065326Sek110237 * Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t). 9075326Sek110237 * 9085326Sek110237 * This function is the callback to create a GFS vnode for '.zfs/snapshot' 9095326Sek110237 * when a lookup is performed on .zfs for "snapshot". 9105326Sek110237 */ 911789Sahrens vnode_t * 912789Sahrens zfsctl_mknode_snapdir(vnode_t *pvp) 913789Sahrens { 914789Sahrens vnode_t *vp; 915789Sahrens zfsctl_snapdir_t *sdp; 916789Sahrens 917789Sahrens vp = gfs_dir_create(sizeof (zfsctl_snapdir_t), pvp, 918789Sahrens zfsctl_ops_snapdir, NULL, NULL, MAXNAMELEN, 919789Sahrens zfsctl_snapdir_readdir_cb, NULL); 920789Sahrens sdp = vp->v_data; 921789Sahrens sdp->sd_node.zc_id = ZFSCTL_INO_SNAPDIR; 9221571Sek110237 sdp->sd_node.zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime; 923789Sahrens mutex_init(&sdp->sd_lock, NULL, MUTEX_DEFAULT, NULL); 924789Sahrens avl_create(&sdp->sd_snaps, snapentry_compare, 925789Sahrens sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node)); 926789Sahrens return (vp); 927789Sahrens } 928789Sahrens 929789Sahrens /* ARGSUSED */ 930789Sahrens static int 9315331Samw zfsctl_snapdir_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, 9325331Samw caller_context_t *ct) 933789Sahrens { 934789Sahrens zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; 935789Sahrens zfsctl_snapdir_t *sdp = vp->v_data; 936789Sahrens 937789Sahrens ZFS_ENTER(zfsvfs); 938789Sahrens zfsctl_common_getattr(vp, vap); 939789Sahrens vap->va_nodeid = gfs_file_inode(vp); 940789Sahrens vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2; 941789Sahrens ZFS_EXIT(zfsvfs); 942789Sahrens 943789Sahrens return (0); 944789Sahrens } 945789Sahrens 9461566Smaybee /* ARGSUSED */ 947789Sahrens static void 9485331Samw zfsctl_snapdir_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 949789Sahrens { 950789Sahrens zfsctl_snapdir_t *sdp = vp->v_data; 9511566Smaybee void *private; 952789Sahrens 9531566Smaybee private = gfs_dir_inactive(vp); 9541566Smaybee if (private != NULL) { 9551566Smaybee ASSERT(avl_numnodes(&sdp->sd_snaps) == 0); 9561566Smaybee mutex_destroy(&sdp->sd_lock); 9571566Smaybee avl_destroy(&sdp->sd_snaps); 9581566Smaybee kmem_free(private, sizeof (zfsctl_snapdir_t)); 9591566Smaybee } 960789Sahrens } 961789Sahrens 962789Sahrens static const fs_operation_def_t zfsctl_tops_snapdir[] = { 9633898Srsb { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, 9643898Srsb { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, 9653898Srsb { VOPNAME_IOCTL, { .error = fs_inval } }, 9663898Srsb { VOPNAME_GETATTR, { .vop_getattr = zfsctl_snapdir_getattr } }, 9673898Srsb { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } }, 9683898Srsb { VOPNAME_RENAME, { .vop_rename = zfsctl_snapdir_rename } }, 9693898Srsb { VOPNAME_RMDIR, { .vop_rmdir = zfsctl_snapdir_remove } }, 9704543Smarks { VOPNAME_MKDIR, { .vop_mkdir = zfsctl_snapdir_mkdir } }, 9713898Srsb { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } }, 9723898Srsb { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_snapdir_lookup } }, 9733898Srsb { VOPNAME_SEEK, { .vop_seek = fs_seek } }, 9743898Srsb { VOPNAME_INACTIVE, { .vop_inactive = zfsctl_snapdir_inactive } }, 9753898Srsb { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } }, 976789Sahrens { NULL } 977789Sahrens }; 978789Sahrens 9795326Sek110237 /* 9805326Sek110237 * pvp is the GFS vnode '.zfs/snapshot'. 9815326Sek110237 * 9825326Sek110237 * This creates a GFS node under '.zfs/snapshot' representing each 9835326Sek110237 * snapshot. This newly created GFS node is what we mount snapshot 9845326Sek110237 * vfs_t's ontop of. 9855326Sek110237 */ 986789Sahrens static vnode_t * 987789Sahrens zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset) 988789Sahrens { 989789Sahrens vnode_t *vp; 990789Sahrens zfsctl_node_t *zcp; 991789Sahrens 992789Sahrens vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, 993789Sahrens zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL); 994789Sahrens zcp = vp->v_data; 995789Sahrens zcp->zc_id = objset; 9966068Sck153898 VFS_HOLD(vp->v_vfsp); 997789Sahrens 998789Sahrens return (vp); 999789Sahrens } 1000789Sahrens 1001789Sahrens static void 10025331Samw zfsctl_snapshot_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 1003789Sahrens { 1004789Sahrens zfsctl_snapdir_t *sdp; 1005789Sahrens zfs_snapentry_t *sep, *next; 1006789Sahrens vnode_t *dvp; 1007789Sahrens 10086492Stimh VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0); 1009789Sahrens sdp = dvp->v_data; 1010789Sahrens 1011789Sahrens mutex_enter(&sdp->sd_lock); 1012789Sahrens 1013789Sahrens if (vp->v_count > 1) { 1014789Sahrens mutex_exit(&sdp->sd_lock); 1015789Sahrens return; 1016789Sahrens } 1017789Sahrens ASSERT(!vn_ismntpt(vp)); 1018789Sahrens 1019789Sahrens sep = avl_first(&sdp->sd_snaps); 1020789Sahrens while (sep != NULL) { 1021789Sahrens next = AVL_NEXT(&sdp->sd_snaps, sep); 1022789Sahrens 1023789Sahrens if (sep->se_root == vp) { 1024789Sahrens avl_remove(&sdp->sd_snaps, sep); 1025789Sahrens kmem_free(sep->se_name, strlen(sep->se_name) + 1); 1026789Sahrens kmem_free(sep, sizeof (zfs_snapentry_t)); 1027789Sahrens break; 1028789Sahrens } 1029789Sahrens sep = next; 1030789Sahrens } 1031789Sahrens ASSERT(sep != NULL); 1032789Sahrens 1033789Sahrens mutex_exit(&sdp->sd_lock); 1034789Sahrens VN_RELE(dvp); 10356068Sck153898 VFS_RELE(vp->v_vfsp); 1036789Sahrens 10371566Smaybee /* 10381566Smaybee * Dispose of the vnode for the snapshot mount point. 10391566Smaybee * This is safe to do because once this entry has been removed 10401566Smaybee * from the AVL tree, it can't be found again, so cannot become 10411566Smaybee * "active". If we lookup the same name again we will end up 10421566Smaybee * creating a new vnode. 10431566Smaybee */ 10445331Samw gfs_vop_inactive(vp, cr, ct); 1045789Sahrens } 1046789Sahrens 1047789Sahrens 1048789Sahrens /* 1049789Sahrens * These VP's should never see the light of day. They should always 1050789Sahrens * be covered. 1051789Sahrens */ 1052789Sahrens static const fs_operation_def_t zfsctl_tops_snapshot[] = { 10533898Srsb VOPNAME_INACTIVE, { .vop_inactive = zfsctl_snapshot_inactive }, 1054789Sahrens NULL, NULL 1055789Sahrens }; 1056789Sahrens 1057789Sahrens int 1058789Sahrens zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp) 1059789Sahrens { 1060789Sahrens zfsvfs_t *zfsvfs = vfsp->vfs_data; 1061789Sahrens vnode_t *dvp, *vp; 1062789Sahrens zfsctl_snapdir_t *sdp; 1063789Sahrens zfsctl_node_t *zcp; 1064789Sahrens zfs_snapentry_t *sep; 1065789Sahrens int error; 1066789Sahrens 1067789Sahrens ASSERT(zfsvfs->z_ctldir != NULL); 1068789Sahrens error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, 10695331Samw NULL, 0, NULL, kcred, NULL, NULL, NULL); 1070789Sahrens if (error != 0) 1071789Sahrens return (error); 1072789Sahrens sdp = dvp->v_data; 1073789Sahrens 1074789Sahrens mutex_enter(&sdp->sd_lock); 1075789Sahrens sep = avl_first(&sdp->sd_snaps); 1076789Sahrens while (sep != NULL) { 1077789Sahrens vp = sep->se_root; 1078789Sahrens zcp = vp->v_data; 1079789Sahrens if (zcp->zc_id == objsetid) 1080789Sahrens break; 1081789Sahrens 1082789Sahrens sep = AVL_NEXT(&sdp->sd_snaps, sep); 1083789Sahrens } 1084789Sahrens 1085789Sahrens if (sep != NULL) { 1086789Sahrens VN_HOLD(vp); 10875326Sek110237 /* 10885326Sek110237 * Return the mounted root rather than the covered mount point. 10895326Sek110237 * Takes the GFS vnode at .zfs/snapshot/<snapshot objsetid> 10905326Sek110237 * and returns the ZFS vnode mounted on top of the GFS node. 10915326Sek110237 * This ZFS vnode is the root of the vfs for objset 'objsetid'. 10925326Sek110237 */ 1093789Sahrens error = traverse(&vp); 10941589Smaybee if (error == 0) { 10951589Smaybee if (vp == sep->se_root) 10961589Smaybee error = EINVAL; 10971589Smaybee else 10981589Smaybee *zfsvfsp = VTOZ(vp)->z_zfsvfs; 10991589Smaybee } 11001572Snd150628 mutex_exit(&sdp->sd_lock); 1101789Sahrens VN_RELE(vp); 1102789Sahrens } else { 1103789Sahrens error = EINVAL; 11041572Snd150628 mutex_exit(&sdp->sd_lock); 1105789Sahrens } 1106789Sahrens 1107789Sahrens VN_RELE(dvp); 1108789Sahrens 1109789Sahrens return (error); 1110789Sahrens } 1111789Sahrens 1112789Sahrens /* 1113789Sahrens * Unmount any snapshots for the given filesystem. This is called from 1114789Sahrens * zfs_umount() - if we have a ctldir, then go through and unmount all the 1115789Sahrens * snapshots. 1116789Sahrens */ 1117789Sahrens int 1118789Sahrens zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr) 1119789Sahrens { 1120789Sahrens zfsvfs_t *zfsvfs = vfsp->vfs_data; 11216068Sck153898 vnode_t *dvp; 1122789Sahrens zfsctl_snapdir_t *sdp; 1123789Sahrens zfs_snapentry_t *sep, *next; 1124789Sahrens int error; 1125789Sahrens 1126789Sahrens ASSERT(zfsvfs->z_ctldir != NULL); 1127789Sahrens error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, 11285331Samw NULL, 0, NULL, cr, NULL, NULL, NULL); 1129789Sahrens if (error != 0) 1130789Sahrens return (error); 1131789Sahrens sdp = dvp->v_data; 1132789Sahrens 1133789Sahrens mutex_enter(&sdp->sd_lock); 1134789Sahrens 1135789Sahrens sep = avl_first(&sdp->sd_snaps); 1136789Sahrens while (sep != NULL) { 1137789Sahrens next = AVL_NEXT(&sdp->sd_snaps, sep); 1138789Sahrens 1139789Sahrens /* 1140789Sahrens * If this snapshot is not mounted, then it must 1141789Sahrens * have just been unmounted by somebody else, and 1142789Sahrens * will be cleaned up by zfsctl_snapdir_inactive(). 1143789Sahrens */ 11446068Sck153898 if (vn_ismntpt(sep->se_root)) { 11456068Sck153898 avl_remove(&sdp->sd_snaps, sep); 11466068Sck153898 error = zfsctl_unmount_snap(sep, fflags, cr); 1147789Sahrens if (error) { 11486068Sck153898 avl_add(&sdp->sd_snaps, sep); 11496068Sck153898 break; 1150789Sahrens } 1151789Sahrens } 1152789Sahrens sep = next; 1153789Sahrens } 11546068Sck153898 1155789Sahrens mutex_exit(&sdp->sd_lock); 1156789Sahrens VN_RELE(dvp); 1157789Sahrens 1158789Sahrens return (error); 1159789Sahrens } 1160