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 81*6658Smarks #include "zfs_namecheck.h" 82*6658Smarks 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 433*6658Smarks if (snapshot_namecheck(name, NULL, NULL) != 0) 434*6658Smarks 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 662*6658Smarks if (snapshot_namecheck(dirname, NULL, NULL) != 0) 663*6658Smarks return (EILSEQ); 664*6658Smarks 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); 7821154Smaybee return (err); 7831154Smaybee } 784789Sahrens if (dmu_objset_open(snapname, DMU_OST_ZFS, 785789Sahrens DS_MODE_STANDARD | DS_MODE_READONLY, &snap) != 0) { 786789Sahrens mutex_exit(&sdp->sd_lock); 787789Sahrens ZFS_EXIT(zfsvfs); 788789Sahrens return (ENOENT); 789789Sahrens } 790789Sahrens 791789Sahrens sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP); 792789Sahrens sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP); 793789Sahrens (void) strcpy(sep->se_name, nm); 794789Sahrens *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap)); 795789Sahrens avl_insert(&sdp->sd_snaps, sep, where); 796789Sahrens 797789Sahrens dmu_objset_close(snap); 798789Sahrens domount: 799789Sahrens mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) + 800789Sahrens strlen("/.zfs/snapshot/") + strlen(nm) + 1; 801789Sahrens mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP); 802789Sahrens (void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s", 803789Sahrens refstr_value(dvp->v_vfsp->vfs_mntpt), nm); 804789Sahrens 805789Sahrens margs.spec = snapname; 806789Sahrens margs.dir = mountpoint; 807789Sahrens margs.flags = MS_SYSSPACE | MS_NOMNTTAB; 808789Sahrens margs.fstype = "zfs"; 809789Sahrens margs.dataptr = NULL; 810789Sahrens margs.datalen = 0; 811789Sahrens margs.optptr = NULL; 812789Sahrens margs.optlen = 0; 813789Sahrens 814789Sahrens err = domount("zfs", &margs, *vpp, kcred, &vfsp); 815789Sahrens kmem_free(mountpoint, mountpoint_len); 816789Sahrens 817816Smaybee if (err == 0) { 818816Smaybee /* 819816Smaybee * Return the mounted root rather than the covered mount point. 8205326Sek110237 * Takes the GFS vnode at .zfs/snapshot/<snapname> and returns 8215326Sek110237 * the ZFS vnode mounted on top of the GFS node. This ZFS 8225326Sek110237 * vnode is the root the newly created vfsp. 823816Smaybee */ 824816Smaybee VFS_RELE(vfsp); 825816Smaybee err = traverse(vpp); 826816Smaybee } 827789Sahrens 828816Smaybee if (err == 0) { 829816Smaybee /* 8305326Sek110237 * Fix up the root vnode mounted on .zfs/snapshot/<snapname>. 8314736Sek110237 * 8324736Sek110237 * This is where we lie about our v_vfsp in order to 8335326Sek110237 * make .zfs/snapshot/<snapname> accessible over NFS 8345326Sek110237 * without requiring manual mounts of <snapname>. 835816Smaybee */ 836816Smaybee ASSERT(VTOZ(*vpp)->z_zfsvfs != zfsvfs); 837816Smaybee VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs; 838816Smaybee (*vpp)->v_vfsp = zfsvfs->z_vfs; 839816Smaybee (*vpp)->v_flag &= ~VROOT; 840816Smaybee } 841789Sahrens mutex_exit(&sdp->sd_lock); 842789Sahrens ZFS_EXIT(zfsvfs); 843789Sahrens 8441566Smaybee /* 8451566Smaybee * If we had an error, drop our hold on the vnode and 8461566Smaybee * zfsctl_snapshot_inactive() will clean up. 8471566Smaybee */ 8481566Smaybee if (err) { 849816Smaybee VN_RELE(*vpp); 8501566Smaybee *vpp = NULL; 8511566Smaybee } 852816Smaybee return (err); 853789Sahrens } 854789Sahrens 855789Sahrens /* ARGSUSED */ 856789Sahrens static int 8575663Sck153898 zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp, 8585663Sck153898 offset_t *offp, offset_t *nextp, void *data, int flags) 859789Sahrens { 860789Sahrens zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; 861789Sahrens char snapname[MAXNAMELEN]; 862789Sahrens uint64_t id, cookie; 8635663Sck153898 boolean_t case_conflict; 8645663Sck153898 int error; 865789Sahrens 866789Sahrens ZFS_ENTER(zfsvfs); 867789Sahrens 868789Sahrens cookie = *offp; 8695663Sck153898 error = dmu_snapshot_list_next(zfsvfs->z_os, MAXNAMELEN, snapname, &id, 8705663Sck153898 &cookie, &case_conflict); 8715663Sck153898 if (error) { 872789Sahrens ZFS_EXIT(zfsvfs); 8735663Sck153898 if (error == ENOENT) { 8745663Sck153898 *eofp = 1; 8755663Sck153898 return (0); 8765663Sck153898 } 8775663Sck153898 return (error); 878789Sahrens } 879789Sahrens 8805663Sck153898 if (flags & V_RDDIR_ENTFLAGS) { 8815663Sck153898 edirent_t *eodp = dp; 8825663Sck153898 8835663Sck153898 (void) strcpy(eodp->ed_name, snapname); 8845663Sck153898 eodp->ed_ino = ZFSCTL_INO_SNAP(id); 8855663Sck153898 eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0; 8865663Sck153898 } else { 8875663Sck153898 struct dirent64 *odp = dp; 8885663Sck153898 8895663Sck153898 (void) strcpy(odp->d_name, snapname); 8905663Sck153898 odp->d_ino = ZFSCTL_INO_SNAP(id); 8915663Sck153898 } 892789Sahrens *nextp = cookie; 893789Sahrens 894789Sahrens ZFS_EXIT(zfsvfs); 895789Sahrens 896789Sahrens return (0); 897789Sahrens } 898789Sahrens 8995326Sek110237 /* 9005326Sek110237 * pvp is the '.zfs' directory (zfsctl_node_t). 9015326Sek110237 * Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t). 9025326Sek110237 * 9035326Sek110237 * This function is the callback to create a GFS vnode for '.zfs/snapshot' 9045326Sek110237 * when a lookup is performed on .zfs for "snapshot". 9055326Sek110237 */ 906789Sahrens vnode_t * 907789Sahrens zfsctl_mknode_snapdir(vnode_t *pvp) 908789Sahrens { 909789Sahrens vnode_t *vp; 910789Sahrens zfsctl_snapdir_t *sdp; 911789Sahrens 912789Sahrens vp = gfs_dir_create(sizeof (zfsctl_snapdir_t), pvp, 913789Sahrens zfsctl_ops_snapdir, NULL, NULL, MAXNAMELEN, 914789Sahrens zfsctl_snapdir_readdir_cb, NULL); 915789Sahrens sdp = vp->v_data; 916789Sahrens sdp->sd_node.zc_id = ZFSCTL_INO_SNAPDIR; 9171571Sek110237 sdp->sd_node.zc_cmtime = ((zfsctl_node_t *)pvp->v_data)->zc_cmtime; 918789Sahrens mutex_init(&sdp->sd_lock, NULL, MUTEX_DEFAULT, NULL); 919789Sahrens avl_create(&sdp->sd_snaps, snapentry_compare, 920789Sahrens sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node)); 921789Sahrens return (vp); 922789Sahrens } 923789Sahrens 924789Sahrens /* ARGSUSED */ 925789Sahrens static int 9265331Samw zfsctl_snapdir_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, 9275331Samw caller_context_t *ct) 928789Sahrens { 929789Sahrens zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; 930789Sahrens zfsctl_snapdir_t *sdp = vp->v_data; 931789Sahrens 932789Sahrens ZFS_ENTER(zfsvfs); 933789Sahrens zfsctl_common_getattr(vp, vap); 934789Sahrens vap->va_nodeid = gfs_file_inode(vp); 935789Sahrens vap->va_nlink = vap->va_size = avl_numnodes(&sdp->sd_snaps) + 2; 936789Sahrens ZFS_EXIT(zfsvfs); 937789Sahrens 938789Sahrens return (0); 939789Sahrens } 940789Sahrens 9411566Smaybee /* ARGSUSED */ 942789Sahrens static void 9435331Samw zfsctl_snapdir_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 944789Sahrens { 945789Sahrens zfsctl_snapdir_t *sdp = vp->v_data; 9461566Smaybee void *private; 947789Sahrens 9481566Smaybee private = gfs_dir_inactive(vp); 9491566Smaybee if (private != NULL) { 9501566Smaybee ASSERT(avl_numnodes(&sdp->sd_snaps) == 0); 9511566Smaybee mutex_destroy(&sdp->sd_lock); 9521566Smaybee avl_destroy(&sdp->sd_snaps); 9531566Smaybee kmem_free(private, sizeof (zfsctl_snapdir_t)); 9541566Smaybee } 955789Sahrens } 956789Sahrens 957789Sahrens static const fs_operation_def_t zfsctl_tops_snapdir[] = { 9583898Srsb { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } }, 9593898Srsb { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } }, 9603898Srsb { VOPNAME_IOCTL, { .error = fs_inval } }, 9613898Srsb { VOPNAME_GETATTR, { .vop_getattr = zfsctl_snapdir_getattr } }, 9623898Srsb { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } }, 9633898Srsb { VOPNAME_RENAME, { .vop_rename = zfsctl_snapdir_rename } }, 9643898Srsb { VOPNAME_RMDIR, { .vop_rmdir = zfsctl_snapdir_remove } }, 9654543Smarks { VOPNAME_MKDIR, { .vop_mkdir = zfsctl_snapdir_mkdir } }, 9663898Srsb { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } }, 9673898Srsb { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_snapdir_lookup } }, 9683898Srsb { VOPNAME_SEEK, { .vop_seek = fs_seek } }, 9693898Srsb { VOPNAME_INACTIVE, { .vop_inactive = zfsctl_snapdir_inactive } }, 9703898Srsb { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } }, 971789Sahrens { NULL } 972789Sahrens }; 973789Sahrens 9745326Sek110237 /* 9755326Sek110237 * pvp is the GFS vnode '.zfs/snapshot'. 9765326Sek110237 * 9775326Sek110237 * This creates a GFS node under '.zfs/snapshot' representing each 9785326Sek110237 * snapshot. This newly created GFS node is what we mount snapshot 9795326Sek110237 * vfs_t's ontop of. 9805326Sek110237 */ 981789Sahrens static vnode_t * 982789Sahrens zfsctl_snapshot_mknode(vnode_t *pvp, uint64_t objset) 983789Sahrens { 984789Sahrens vnode_t *vp; 985789Sahrens zfsctl_node_t *zcp; 986789Sahrens 987789Sahrens vp = gfs_dir_create(sizeof (zfsctl_node_t), pvp, 988789Sahrens zfsctl_ops_snapshot, NULL, NULL, MAXNAMELEN, NULL, NULL); 989789Sahrens zcp = vp->v_data; 990789Sahrens zcp->zc_id = objset; 9916068Sck153898 VFS_HOLD(vp->v_vfsp); 992789Sahrens 993789Sahrens return (vp); 994789Sahrens } 995789Sahrens 996789Sahrens static void 9975331Samw zfsctl_snapshot_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 998789Sahrens { 999789Sahrens zfsctl_snapdir_t *sdp; 1000789Sahrens zfs_snapentry_t *sep, *next; 1001789Sahrens vnode_t *dvp; 1002789Sahrens 10036492Stimh VERIFY(gfs_dir_lookup(vp, "..", &dvp, cr, 0, NULL, NULL) == 0); 1004789Sahrens sdp = dvp->v_data; 1005789Sahrens 1006789Sahrens mutex_enter(&sdp->sd_lock); 1007789Sahrens 1008789Sahrens if (vp->v_count > 1) { 1009789Sahrens mutex_exit(&sdp->sd_lock); 1010789Sahrens return; 1011789Sahrens } 1012789Sahrens ASSERT(!vn_ismntpt(vp)); 1013789Sahrens 1014789Sahrens sep = avl_first(&sdp->sd_snaps); 1015789Sahrens while (sep != NULL) { 1016789Sahrens next = AVL_NEXT(&sdp->sd_snaps, sep); 1017789Sahrens 1018789Sahrens if (sep->se_root == vp) { 1019789Sahrens avl_remove(&sdp->sd_snaps, sep); 1020789Sahrens kmem_free(sep->se_name, strlen(sep->se_name) + 1); 1021789Sahrens kmem_free(sep, sizeof (zfs_snapentry_t)); 1022789Sahrens break; 1023789Sahrens } 1024789Sahrens sep = next; 1025789Sahrens } 1026789Sahrens ASSERT(sep != NULL); 1027789Sahrens 1028789Sahrens mutex_exit(&sdp->sd_lock); 1029789Sahrens VN_RELE(dvp); 10306068Sck153898 VFS_RELE(vp->v_vfsp); 1031789Sahrens 10321566Smaybee /* 10331566Smaybee * Dispose of the vnode for the snapshot mount point. 10341566Smaybee * This is safe to do because once this entry has been removed 10351566Smaybee * from the AVL tree, it can't be found again, so cannot become 10361566Smaybee * "active". If we lookup the same name again we will end up 10371566Smaybee * creating a new vnode. 10381566Smaybee */ 10395331Samw gfs_vop_inactive(vp, cr, ct); 1040789Sahrens } 1041789Sahrens 1042789Sahrens 1043789Sahrens /* 1044789Sahrens * These VP's should never see the light of day. They should always 1045789Sahrens * be covered. 1046789Sahrens */ 1047789Sahrens static const fs_operation_def_t zfsctl_tops_snapshot[] = { 10483898Srsb VOPNAME_INACTIVE, { .vop_inactive = zfsctl_snapshot_inactive }, 1049789Sahrens NULL, NULL 1050789Sahrens }; 1051789Sahrens 1052789Sahrens int 1053789Sahrens zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp) 1054789Sahrens { 1055789Sahrens zfsvfs_t *zfsvfs = vfsp->vfs_data; 1056789Sahrens vnode_t *dvp, *vp; 1057789Sahrens zfsctl_snapdir_t *sdp; 1058789Sahrens zfsctl_node_t *zcp; 1059789Sahrens zfs_snapentry_t *sep; 1060789Sahrens int error; 1061789Sahrens 1062789Sahrens ASSERT(zfsvfs->z_ctldir != NULL); 1063789Sahrens error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, 10645331Samw NULL, 0, NULL, kcred, NULL, NULL, NULL); 1065789Sahrens if (error != 0) 1066789Sahrens return (error); 1067789Sahrens sdp = dvp->v_data; 1068789Sahrens 1069789Sahrens mutex_enter(&sdp->sd_lock); 1070789Sahrens sep = avl_first(&sdp->sd_snaps); 1071789Sahrens while (sep != NULL) { 1072789Sahrens vp = sep->se_root; 1073789Sahrens zcp = vp->v_data; 1074789Sahrens if (zcp->zc_id == objsetid) 1075789Sahrens break; 1076789Sahrens 1077789Sahrens sep = AVL_NEXT(&sdp->sd_snaps, sep); 1078789Sahrens } 1079789Sahrens 1080789Sahrens if (sep != NULL) { 1081789Sahrens VN_HOLD(vp); 10825326Sek110237 /* 10835326Sek110237 * Return the mounted root rather than the covered mount point. 10845326Sek110237 * Takes the GFS vnode at .zfs/snapshot/<snapshot objsetid> 10855326Sek110237 * and returns the ZFS vnode mounted on top of the GFS node. 10865326Sek110237 * This ZFS vnode is the root of the vfs for objset 'objsetid'. 10875326Sek110237 */ 1088789Sahrens error = traverse(&vp); 10891589Smaybee if (error == 0) { 10901589Smaybee if (vp == sep->se_root) 10911589Smaybee error = EINVAL; 10921589Smaybee else 10931589Smaybee *zfsvfsp = VTOZ(vp)->z_zfsvfs; 10941589Smaybee } 10951572Snd150628 mutex_exit(&sdp->sd_lock); 1096789Sahrens VN_RELE(vp); 1097789Sahrens } else { 1098789Sahrens error = EINVAL; 10991572Snd150628 mutex_exit(&sdp->sd_lock); 1100789Sahrens } 1101789Sahrens 1102789Sahrens VN_RELE(dvp); 1103789Sahrens 1104789Sahrens return (error); 1105789Sahrens } 1106789Sahrens 1107789Sahrens /* 1108789Sahrens * Unmount any snapshots for the given filesystem. This is called from 1109789Sahrens * zfs_umount() - if we have a ctldir, then go through and unmount all the 1110789Sahrens * snapshots. 1111789Sahrens */ 1112789Sahrens int 1113789Sahrens zfsctl_umount_snapshots(vfs_t *vfsp, int fflags, cred_t *cr) 1114789Sahrens { 1115789Sahrens zfsvfs_t *zfsvfs = vfsp->vfs_data; 11166068Sck153898 vnode_t *dvp; 1117789Sahrens zfsctl_snapdir_t *sdp; 1118789Sahrens zfs_snapentry_t *sep, *next; 1119789Sahrens int error; 1120789Sahrens 1121789Sahrens ASSERT(zfsvfs->z_ctldir != NULL); 1122789Sahrens error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp, 11235331Samw NULL, 0, NULL, cr, NULL, NULL, NULL); 1124789Sahrens if (error != 0) 1125789Sahrens return (error); 1126789Sahrens sdp = dvp->v_data; 1127789Sahrens 1128789Sahrens mutex_enter(&sdp->sd_lock); 1129789Sahrens 1130789Sahrens sep = avl_first(&sdp->sd_snaps); 1131789Sahrens while (sep != NULL) { 1132789Sahrens next = AVL_NEXT(&sdp->sd_snaps, sep); 1133789Sahrens 1134789Sahrens /* 1135789Sahrens * If this snapshot is not mounted, then it must 1136789Sahrens * have just been unmounted by somebody else, and 1137789Sahrens * will be cleaned up by zfsctl_snapdir_inactive(). 1138789Sahrens */ 11396068Sck153898 if (vn_ismntpt(sep->se_root)) { 11406068Sck153898 avl_remove(&sdp->sd_snaps, sep); 11416068Sck153898 error = zfsctl_unmount_snap(sep, fflags, cr); 1142789Sahrens if (error) { 11436068Sck153898 avl_add(&sdp->sd_snaps, sep); 11446068Sck153898 break; 1145789Sahrens } 1146789Sahrens } 1147789Sahrens sep = next; 1148789Sahrens } 11496068Sck153898 1150789Sahrens mutex_exit(&sdp->sd_lock); 1151789Sahrens VN_RELE(dvp); 1152789Sahrens 1153789Sahrens return (error); 1154789Sahrens } 1155