summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zfs_ctldir.c
diff options
context:
space:
mode:
authormarks <none@none>2007-06-26 07:44:24 -0700
committermarks <none@none>2007-06-26 07:44:24 -0700
commitecd6cf800b63704be73fb264c3f5b6e0dafc068d (patch)
treeec83d040bc56ee0a46e9533a645e832e58d8ba86 /usr/src/uts/common/fs/zfs/zfs_ctldir.c
parent8ac1b93fdff76ea81638299d410b2d474240ee2b (diff)
downloadillumos-gate-ecd6cf800b63704be73fb264c3f5b6e0dafc068d.tar.gz
PSARC/2006/465 ZFS Delegated Administration
PSARC/2006/577 zpool property to disable delegation PSARC/2006/625 Enhancements to zpool history PSARC/2007/228 ZFS delegation amendments PSARC/2007/295 ZFS Delegated Administration Addendum 6280676 restore "owner" property 6349470 investigate non-root restore/backup 6572465 'zpool set bootfs=...' records history as 'zfs set bootfs=...'
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zfs_ctldir.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ctldir.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_ctldir.c b/usr/src/uts/common/fs/zfs/zfs_ctldir.c
index f48dd98436..d842fafa2a 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ctldir.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ctldir.c
@@ -63,6 +63,7 @@
#include <sys/gfs.h>
#include <sys/stat.h>
#include <sys/dmu.h>
+#include <sys/dsl_deleg.h>
#include <sys/mount.h>
typedef struct {
@@ -411,7 +412,7 @@ zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname)
return (0);
}
-static int
+int
zfsctl_unmount_snap(vnode_t *dvp, const char *name, int force, cred_t *cr)
{
zfsctl_snapdir_t *sdp = dvp->v_data;
@@ -514,10 +515,13 @@ zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from);
if (err)
return (err);
- err = zfs_secpolicy_write(from, cr);
+
+ err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to);
if (err)
return (err);
+ if (err = zfs_secpolicy_rename_perms(from, to, cr))
+ return (err);
/*
* Cannot move snapshots out of the snapdir.
*/
@@ -527,10 +531,6 @@ zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
if (strcmp(snm, tnm) == 0)
return (0);
- err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to);
- if (err)
- return (err);
-
mutex_enter(&sdp->sd_lock);
search.se_name = (char *)snm;
@@ -559,13 +559,13 @@ zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr)
err = zfsctl_snapshot_zname(dvp, name, MAXNAMELEN, snapname);
if (err)
return (err);
- err = zfs_secpolicy_write(snapname, cr);
- if (err)
+
+ if (err = zfs_secpolicy_destroy_perms(snapname, cr))
return (err);
mutex_enter(&sdp->sd_lock);
- err = zfsctl_unmount_snap(dvp, name, 0, cr);
+ err = zfsctl_unmount_snap(dvp, name, MS_FORCE, cr);
if (err) {
mutex_exit(&sdp->sd_lock);
return (err);
@@ -578,6 +578,35 @@ zfsctl_snapdir_remove(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr)
return (err);
}
+/* ARGSUSED */
+static int
+zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp,
+ cred_t *cr)
+{
+ 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;
+
+ 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, B_FALSE);
+ if (err)
+ return (err);
+ err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
+ }
+
+ return (err);
+}
+
/*
* Lookup entry point for the 'snapshot' directory. Try to open the
* snapshot if it exist, creating the pseudo filesystem vnode as necessary.
@@ -796,6 +825,7 @@ static const fs_operation_def_t zfsctl_tops_snapdir[] = {
{ VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } },
{ VOPNAME_RENAME, { .vop_rename = zfsctl_snapdir_rename } },
{ VOPNAME_RMDIR, { .vop_rmdir = zfsctl_snapdir_remove } },
+ { VOPNAME_MKDIR, { .vop_mkdir = zfsctl_snapdir_mkdir } },
{ VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } },
{ VOPNAME_LOOKUP, { .vop_lookup = zfsctl_snapdir_lookup } },
{ VOPNAME_SEEK, { .vop_seek = fs_seek } },