/* ARGSUSED */ int zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap, struct inode **ipp, cred_t *cr, int flags) { zfs_sb_t *zsb = ITOZSB(dip); char *dsname; int error; dsname = kmem_alloc(MAXNAMELEN, KM_SLEEP); if (snapshot_namecheck(dirname, NULL, NULL) != 0) { error = EILSEQ; goto out; } dmu_objset_name(zsb->z_os, dsname); error = zfs_secpolicy_snapshot_perms(dsname, cr); if (error) goto out; if (error == 0) { error = dmu_objset_snapshot(dsname, dirname, NULL, NULL, B_FALSE, B_FALSE, -1); if (error) goto out; error = zfsctl_snapdir_lookup(dip, dirname, ipp, 0, cr, NULL, NULL); } out: kmem_free(dsname, MAXNAMELEN); return (error); }
/* 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[MAXNAMELEN]; int err; static enum symfollow follow = NO_FOLLOW; static enum uio_seg seg = UIO_SYSSPACE; if (snapshot_namecheck(dirname, NULL, NULL) != 0) return (EILSEQ); dmu_objset_name(zfsvfs->z_os, name); *vpp = NULL; err = zfs_secpolicy_snapshot_perms(name, cr); if (err) return (err); if (err == 0) { err = dmu_objset_snapshot(name, dirname, NULL, B_FALSE); if (err) return (err); err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp); } return (err); }