Beispiel #1
0
/* 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);
}
Beispiel #2
0
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));
}