/* 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); }
zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags) #endif { fstrans_cookie_t cookie; cred_t *cr = CRED(); struct inode *ip = NULL; int error; crhold(cr); cookie = spl_fstrans_mark(); error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip, 0, cr, NULL, NULL); ASSERT3S(error, <=, 0); spl_fstrans_unmark(cookie); crfree(cr); if (error && error != -ENOENT) return (ERR_PTR(error)); ASSERT(error == 0 || ip == NULL); d_clear_d_op(dentry); d_set_d_op(dentry, &zpl_dops_snapdirs); #ifdef HAVE_AUTOMOUNT dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; #endif return (d_splice_alias(ip, dentry)); }