/* ARGSUSED */ static int zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp) { zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data; char name[ZFS_MAX_DATASET_NAME_LEN]; int err; static enum symfollow follow = NO_FOLLOW; static enum uio_seg seg = UIO_SYSSPACE; if (zfs_component_namecheck(dirname, NULL, NULL) != 0) return (SET_ERROR(EILSEQ)); dmu_objset_name(zfsvfs->z_os, name); *vpp = NULL; err = zfs_secpolicy_snapshot_perms(name, cr); if (err != 0) return (err); if (err == 0) { err = dmu_objset_snapshot_one(name, dirname); if (err != 0) return (err); err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp); } return (err); }
/* * Gets the full dataset name that corresponds to the given snapshot name * Example: * zfsctl_snapshot_zname("snap1") -> "mypool/myfs@snap1" */ static int zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname) { objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os; if (zfs_component_namecheck(name, NULL, NULL) != 0) return (SET_ERROR(EILSEQ)); dmu_objset_name(os, zname); if (strlen(zname) + 1 + strlen(name) >= len) return (SET_ERROR(ENAMETOOLONG)); (void) strcat(zname, "@"); (void) strcat(zname, name); return (0); }
static int dsl_bookmark_hold_ds(dsl_pool_t *dp, const char *fullname, dsl_dataset_t **dsp, void *tag, char **shortnamep) { char buf[MAXNAMELEN]; char *hashp; if (strlen(fullname) >= MAXNAMELEN) return (SET_ERROR(ENAMETOOLONG)); hashp = strchr(fullname, '#'); if (hashp == NULL) return (SET_ERROR(EINVAL)); *shortnamep = hashp + 1; if (zfs_component_namecheck(*shortnamep, NULL, NULL)) return (SET_ERROR(EINVAL)); (void) strlcpy(buf, fullname, hashp - fullname + 1); return (dsl_dataset_hold(dp, buf, tag, dsp)); }
/* * Permissions set name must start with the letter '@' followed by the * same character restrictions as snapshot names, except that the name * cannot exceed 64 characters. */ int permset_namecheck(const char *path, namecheck_err_t *why, char *what) { if (strlen(path) >= ZFS_PERMSET_MAXLEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } if (path[0] != '@') { if (why) { *why = NAME_ERR_NO_AT; *what = path[0]; } return (-1); } return (zfs_component_namecheck(&path[1], why, what)); }