Page MenuHomeFreeBSD

D17233.id54425.diff
No OneTemporary

D17233.id54425.diff

Index: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
===================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
@@ -46,6 +46,8 @@
zfsvfs_t *z_parent; /* parent fs */
objset_t *z_os; /* objset reference */
uint64_t z_root; /* id of root znode */
+ struct vnode *z_rootvnode; /* root vnode */
+ struct rmlock z_rootvnodelock;/* protection for root vnode */
uint64_t z_unlinkedobj; /* id of unlinked zapobj */
uint64_t z_max_blksz; /* maximum block size for files */
uint64_t z_fuid_obj; /* fuid table object number */
Index: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
===================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -65,6 +65,7 @@
#include <sys/spa_boot.h>
#include <sys/jail.h>
#include <ufs/ufs/quota.h>
+#include <sys/rmlock.h>
#include "zfs_comutil.h"
@@ -92,6 +93,9 @@
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0,
"ZPL_VERSION");
+static int zfs_root_setvnode(zfsvfs_t *zfsvfs);
+static void zfs_root_dropvnode(zfsvfs_t *zfsvfs);
+
static int zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg);
static int zfs_mount(vfs_t *vfsp);
static int zfs_umount(vfs_t *vfsp, int fflag);
@@ -1209,6 +1213,8 @@
for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++)
mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
+ rm_init(&zfsvfs->z_rootvnodelock, "zfs root vnode lock");
+
error = zfsvfs_init(zfsvfs, os);
if (error != 0) {
*zfvp = NULL;
@@ -1315,6 +1321,8 @@
rw_enter(&zfsvfs_lock, RW_READER);
rw_exit(&zfsvfs_lock);
+ rm_destroy(&zfsvfs->z_rootvnodelock);
+
zfs_fuid_destroy(zfsvfs);
mutex_destroy(&zfsvfs->z_znodes_lock);
@@ -1921,6 +1929,8 @@
error = zfs_domount(vfsp, osname);
PICKUP_GIANT();
+ zfs_root_setvnode((zfsvfs_t *)vfsp->vfs_data);
+
#ifdef illumos
/*
* Add an extra VFS_HOLD on our parent vfs so that it can't
@@ -1993,14 +2003,65 @@
}
static int
+zfs_root_setvnode(zfsvfs_t *zfsvfs)
+{
+ znode_t *rootzp;
+ int error;
+
+ ZFS_ENTER(zfsvfs);
+ error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
+ if (error != 0)
+ panic("could not zfs_zget for root vnode");
+ ZFS_EXIT(zfsvfs);
+
+ rm_wlock(&zfsvfs->z_rootvnodelock);
+ if (zfsvfs->z_rootvnode != NULL)
+ panic("zfs mount point already has a root vnode: %p\n",
+ zfsvfs->z_rootvnode);
+ zfsvfs->z_rootvnode = ZTOV(rootzp);
+ rm_wunlock(&zfsvfs->z_rootvnodelock);
+ return (0);
+}
+
+static void
+zfs_root_putvnode(zfsvfs_t *zfsvfs)
+{
+ struct vnode *vp;
+
+ rm_wlock(&zfsvfs->z_rootvnodelock);
+ vp = zfsvfs->z_rootvnode;
+ zfsvfs->z_rootvnode = NULL;
+ rm_wunlock(&zfsvfs->z_rootvnodelock);
+ if (vp != NULL)
+ vrele(vp);
+}
+
+static int
zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
{
+ struct rm_priotracker tracker;
zfsvfs_t *zfsvfs = vfsp->vfs_data;
znode_t *rootzp;
int error;
- ZFS_ENTER(zfsvfs);
+ rm_rlock(&zfsvfs->z_rootvnodelock, &tracker);
+ *vpp = zfsvfs->z_rootvnode;
+ if (*vpp != NULL && (((*vpp)->v_iflag & VI_DOOMED) == 0)) {
+ vrefact(*vpp);
+ rm_runlock(&zfsvfs->z_rootvnodelock, &tracker);
+ goto lock;
+ }
+ rm_runlock(&zfsvfs->z_rootvnodelock, &tracker);
+ /*
+ * We found the vnode but did not like it.
+ */
+ if (*vpp != NULL) {
+ *vpp = NULL;
+ zfs_root_putvnode(zfsvfs);
+ }
+
+ ZFS_ENTER(zfsvfs);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
if (error == 0)
*vpp = ZTOV(rootzp);
@@ -2008,6 +2069,7 @@
ZFS_EXIT(zfsvfs);
if (error == 0) {
+lock:
error = vn_lock(*vpp, flags);
if (error != 0) {
VN_RELE(*vpp);
@@ -2125,6 +2187,8 @@
objset_t *os;
cred_t *cr = td->td_ucred;
int ret;
+
+ zfs_root_putvnode(zfsvfs);
ret = secpolicy_fs_unmount(cr, vfsp);
if (ret) {

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 27, 11:50 AM (13 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27304342
Default Alt Text
D17233.id54425.diff (3 KB)

Event Timeline