diff options
author | pjd <pjd@FreeBSD.org> | 2011-02-27 19:41:40 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2011-02-27 19:41:40 +0000 |
commit | 1b03c5bf41222b723415638f03e00ed12cac076a (patch) | |
tree | ef515cadc08bf427e4d3f1360199ec9827b1596b /sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | |
parent | c67d387baf03726323703774b1b320235fb1f24b (diff) | |
download | FreeBSD-src-1b03c5bf41222b723415638f03e00ed12cac076a.zip FreeBSD-src-1b03c5bf41222b723415638f03e00ed12cac076a.tar.gz |
Finally... Import the latest open-source ZFS version - (SPA) 28.
Few new things available from now on:
- Data deduplication.
- Triple parity RAIDZ (RAIDZ3).
- zfs diff.
- zpool split.
- Snapshot holds.
- zpool import -F. Allows to rewind corrupted pool to earlier
transaction group.
- Possibility to import pool in read-only mode.
MFC after: 1 month
Diffstat (limited to 'sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c')
-rw-r--r-- | sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 72 |
1 files changed, 32 insertions, 40 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index 8538b54..be9f4ec 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -115,10 +115,10 @@ int mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, char *fspec, int fsflags) { - struct mount *mp; struct vfsconf *vfsp; + struct mount *mp; + vnode_t *vp, *mvp; struct ucred *cr; - vnode_t *vp; int error; /* @@ -153,8 +153,10 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, /* * Allocate and initialize the filesystem. + * We don't want regular user that triggered snapshot mount to be able + * to unmount it, so pass credentials of the parent mount. */ - mp = vfs_mount_alloc(vp, vfsp, fspath, td->td_ucred); + mp = vfs_mount_alloc(vp, vfsp, fspath, vp->v_mount->mnt_cred); mp->mnt_optnew = NULL; vfs_setmntopt(mp, "from", fspec, 0); @@ -164,8 +166,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, /* * Set the mount level flags. */ - mp->mnt_flag &= ~MNT_UPDATEMASK; - mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS); + mp->mnt_flag = fsflags & MNT_UPDATEMASK; /* * Snapshots are always read-only. */ @@ -176,13 +177,6 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, */ mp->mnt_flag |= MNT_IGNORE; /* - * Unprivileged user can trigger mounting a snapshot, but we don't want - * him to unmount it, so we switch to privileged of original mount. - */ - crfree(mp->mnt_cred); - mp->mnt_cred = crdup(vp->v_mount->mnt_cred); - mp->mnt_stat.f_owner = mp->mnt_cred->cr_uid; - /* * XXX: This is evil, but we can't mount a snapshot as a regular user. * XXX: Is is safe when snapshot is mounted from within a jail? */ @@ -191,17 +185,25 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, error = VFS_MOUNT(mp); td->td_ucred = cr; - if (error == 0) { - if (mp->mnt_opt != NULL) - vfs_freeopts(mp->mnt_opt); - mp->mnt_opt = mp->mnt_optnew; - (void)VFS_STATFS(mp, &mp->mnt_stat); + if (error != 0) { + vrele(vp); + vfs_unbusy(mp); + vfs_mount_destroy(mp); + *vpp = NULL; + return (error); } + + if (mp->mnt_opt != NULL) + vfs_freeopts(mp->mnt_opt); + mp->mnt_opt = mp->mnt_optnew; + (void)VFS_STATFS(mp, &mp->mnt_stat); + /* * Prevent external consumers of mount options from reading * mnt_optnew. */ mp->mnt_optnew = NULL; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); #ifdef FREEBSD_NAMECACHE cache_purge(vp); @@ -209,27 +211,17 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, VI_LOCK(vp); vp->v_iflag &= ~VI_MOUNT; VI_UNLOCK(vp); - if (error == 0) { - vnode_t *mvp; - - vp->v_mountedhere = mp; - /* - * Put the new filesystem on the mount list. - */ - mtx_lock(&mountlist_mtx); - TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); - mtx_unlock(&mountlist_mtx); - vfs_event_signal(NULL, VQ_MOUNT, 0); - if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp)) - panic("mount: lost mount"); - vput(vp); - vfs_unbusy(mp); - *vpp = mvp; - } else { - vput(vp); - vfs_unbusy(mp); - vfs_mount_destroy(mp); - *vpp = NULL; - } - return (error); + + vp->v_mountedhere = mp; + /* Put the new filesystem on the mount list. */ + mtx_lock(&mountlist_mtx); + TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); + mtx_unlock(&mountlist_mtx); + vfs_event_signal(NULL, VQ_MOUNT, 0); + if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp)) + panic("mount: lost mount"); + vput(vp); + vfs_unbusy(mp); + *vpp = mvp; + return (0); } |