Module Name:    src
Committed By:   hannken
Date:           Thu Aug 28 08:29:50 UTC 2014

Modified Files:
        src/sys/fs/puffs: puffs_msgif.c puffs_node.c puffs_sys.h puffs_vfsops.c
            puffs_vnops.c

Log Message:
Change puffs from hashlist to vcache.
- field "pa_nhashbuckets" of struct "puffs_kargs" becomes a no-op.
  and should be removed on the next protocol version bump.


To generate a diff of this commit:
cvs rdiff -u -r1.94 -r1.95 src/sys/fs/puffs/puffs_msgif.c
cvs rdiff -u -r1.31 -r1.32 src/sys/fs/puffs/puffs_node.c
cvs rdiff -u -r1.85 -r1.86 src/sys/fs/puffs/puffs_sys.h
cvs rdiff -u -r1.113 -r1.114 src/sys/fs/puffs/puffs_vfsops.c
cvs rdiff -u -r1.183 -r1.184 src/sys/fs/puffs/puffs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/puffs/puffs_msgif.c
diff -u src/sys/fs/puffs/puffs_msgif.c:1.94 src/sys/fs/puffs/puffs_msgif.c:1.95
--- src/sys/fs/puffs/puffs_msgif.c:1.94	Thu Oct 17 21:03:27 2013
+++ src/sys/fs/puffs/puffs_msgif.c	Thu Aug 28 08:29:50 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_msgif.c,v 1.94 2013/10/17 21:03:27 christos Exp $	*/
+/*	$NetBSD: puffs_msgif.c,v 1.95 2014/08/28 08:29:50 hannken Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.94 2013/10/17 21:03:27 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.95 2014/08/28 08:29:50 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -856,7 +856,7 @@ puffsop_expire(struct puffs_mount *pmp, 
 	 * vrele should cause it to be reclaimed.
 	 * Otherwise, we have nothing to do.
 	 */
-	if (puffs_cookie2vnode(pmp, cookie, 0, 0, &vp) == 0) {
+	if (puffs_cookie2vnode(pmp, cookie, &vp) == 0) {
 		VPTOPP(vp)->pn_stat &= ~PNODE_SOPEXP;
 		vrele(vp); 
 	}
@@ -889,7 +889,7 @@ puffsop_flush(struct puffs_mount *pmp, s
 	 * reason we need to eventually bump locking to userspace, as we
 	 * will need to lock the node if we wish to do flushes.
 	 */
-	rv = puffs_cookie2vnode(pmp, pf->pf_cookie, 0, 0, &vp);
+	rv = puffs_cookie2vnode(pmp, pf->pf_cookie, &vp);
 	if (rv) {
 		if (rv == PUFFS_NOSUCHCOOKIE)
 			rv = ENOENT;

Index: src/sys/fs/puffs/puffs_node.c
diff -u src/sys/fs/puffs/puffs_node.c:1.31 src/sys/fs/puffs/puffs_node.c:1.32
--- src/sys/fs/puffs/puffs_node.c:1.31	Thu Jan 23 10:13:56 2014
+++ src/sys/fs/puffs/puffs_node.c	Thu Aug 28 08:29:50 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_node.c,v 1.31 2014/01/23 10:13:56 hannken Exp $	*/
+/*	$NetBSD: puffs_node.c,v 1.32 2014/08/28 08:29:50 hannken Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_node.c,v 1.31 2014/01/23 10:13:56 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_node.c,v 1.32 2014/08/28 08:29:50 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/hash.h>
@@ -48,148 +48,96 @@ __KERNEL_RCSID(0, "$NetBSD: puffs_node.c
 #include <miscfs/genfs/genfs_node.h>
 #include <miscfs/specfs/specdev.h>
 
-static const struct genfs_ops puffs_genfsops = {
-	.gop_size = puffs_gop_size,
-	.gop_write = genfs_gop_write,
-	.gop_markupdate = puffs_gop_markupdate,
-#if 0
-	.gop_alloc, should ask userspace
-#endif
-};
-
-static __inline struct puffs_node_hashlist
-	*puffs_cookie2hashlist(struct puffs_mount *, puffs_cookie_t);
-static struct puffs_node *puffs_cookie2pnode(struct puffs_mount *,
-					     puffs_cookie_t);
-
 struct pool puffs_pnpool;
 struct pool puffs_vapool;
 
 /*
  * Grab a vnode, intialize all the puffs-dependent stuff.
  */
-int
-puffs_getvnode(struct mount *mp, puffs_cookie_t ck, enum vtype type,
-	voff_t vsize, dev_t rdev, struct vnode **vpp)
+static int
+puffs_getvnode1(struct mount *mp, puffs_cookie_t ck, enum vtype type,
+	voff_t vsize, dev_t rdev, bool may_exist, struct vnode **vpp)
 {
 	struct puffs_mount *pmp;
-	struct puffs_newcookie *pnc;
 	struct vnode *vp;
 	struct puffs_node *pnode;
-	struct puffs_node_hashlist *plist;
 	int error;
 
 	pmp = MPTOPUFFSMP(mp);
 
-	error = EPROTO;
 	if (type <= VNON || type >= VBAD) {
 		puffs_senderr(pmp, PUFFS_ERR_MAKENODE, EINVAL,
 		    "bad node type", ck);
-		goto bad;
+		return EPROTO;
 	}
 	if (vsize == VSIZENOTSET) {
 		puffs_senderr(pmp, PUFFS_ERR_MAKENODE, EINVAL,
 		    "VSIZENOTSET is not a valid size", ck);
-		goto bad;
+		return EPROTO;
 	}
 
-	error = getnewvnode(VT_PUFFS, mp, puffs_vnodeop_p, NULL, &vp);
-	if (error) {
-		goto bad;
+	for (;;) {
+		error = vcache_get(mp, &ck, sizeof(ck), &vp);
+		if (error)
+			return error;
+		mutex_enter(vp->v_interlock);
+		pnode = VPTOPP(vp);
+		if (pnode != NULL)
+			break;
+		mutex_exit(vp->v_interlock);
+		vrele(vp);
 	}
-	vp->v_type = type;
+	mutex_enter(&pnode->pn_mtx);
+	mutex_exit(vp->v_interlock);
 
 	/*
-	 * Creation should not fail after this point.  Or if it does,
-	 * care must be taken so that VOP_INACTIVE() isn't called.
+	 * Release and error out if caller wants a fresh vnode.
 	 */
+	if (vp->v_type != VNON && ! may_exist) {
+		mutex_exit(&pnode->pn_mtx);
+		vrele(vp);
+		return EEXIST;
+	}
 
-	/* default size */
-	uvm_vnp_setsize(vp, 0);
+	*vpp = vp;
 
-	/* dances based on vnode type. almost ufs_vinit(), but not quite */
-	switch (type) {
-	case VCHR:
-	case VBLK:
-		/*
-		 * replace vnode operation vector with the specops vector.
-		 * our user server has very little control over the node
-		 * if it decides its a character or block special file
-		 */
+	/*
+	 * If fully initialized were done.
+	 */
+	if (vp->v_type != VNON) {
+		mutex_exit(&pnode->pn_mtx);
+		return 0;
+	}
+
+	/*
+	 * Set type and finalize the initialisation.
+	 */
+	vp->v_type = type;
+	if (type == VCHR || type == VBLK) {
 		vp->v_op = puffs_specop_p;
 		spec_node_init(vp, rdev);
-		break;
-
-	case VFIFO:
+	} else if (type == VFIFO) {
 		vp->v_op = puffs_fifoop_p;
-		break;
-
-	case VREG:
+	} else if (vp->v_type == VREG) {
 		uvm_vnp_setsize(vp, vsize);
-		break;
-
-	case VDIR:
-	case VLNK:
-	case VSOCK:
-		break;
-	default:
-		panic("puffs_getvnode: invalid vtype %d", type);
-	}
-
-	pnode = pool_get(&puffs_pnpool, PR_WAITOK);
-	memset(pnode, 0, sizeof(struct puffs_node));
-
-	pnode->pn_cookie = ck;
-	pnode->pn_refcount = 1;
-
-	/* insert cookie on list, take off of interlock list */
-	mutex_init(&pnode->pn_mtx, MUTEX_DEFAULT, IPL_NONE);
-	selinit(&pnode->pn_sel);
-	plist = puffs_cookie2hashlist(pmp, ck);
-	mutex_enter(&pmp->pmp_lock);
-	LIST_INSERT_HEAD(plist, pnode, pn_hashent);
-	if (ck != pmp->pmp_root_cookie) {
-		LIST_FOREACH(pnc, &pmp->pmp_newcookie, pnc_entries) {
-			if (pnc->pnc_cookie == ck) {
-				LIST_REMOVE(pnc, pnc_entries);
-				kmem_free(pnc, sizeof(struct puffs_newcookie));
-				break;
-			}
-		}
-		KASSERT(pnc != NULL);
 	}
-	mutex_init(&pnode->pn_sizemtx, MUTEX_DEFAULT, IPL_NONE);
-	mutex_exit(&pmp->pmp_lock);
 
-	vp->v_data = pnode;
-	vp->v_type = type;
-	pnode->pn_vp = vp;
 	pnode->pn_serversize = vsize;
 
-	genfs_node_init(vp, &puffs_genfsops);
-	*vpp = vp;
-
 	DPRINTF(("new vnode at %p, pnode %p, cookie %p\n", vp,
 	    pnode, pnode->pn_cookie));
 
+	mutex_exit(&pnode->pn_mtx);
+
 	return 0;
+}
 
- bad:
-	/* remove staging cookie from list */
-	if (ck != pmp->pmp_root_cookie) {
-		mutex_enter(&pmp->pmp_lock);
-		LIST_FOREACH(pnc, &pmp->pmp_newcookie, pnc_entries) {
-			if (pnc->pnc_cookie == ck) {
-				LIST_REMOVE(pnc, pnc_entries);
-				kmem_free(pnc, sizeof(struct puffs_newcookie));
-				break;
-			}
-		}
-		KASSERT(pnc != NULL);
-		mutex_exit(&pmp->pmp_lock);
-	}
+int
+puffs_getvnode(struct mount *mp, puffs_cookie_t ck, enum vtype type,
+	voff_t vsize, dev_t rdev, struct vnode **vpp)
+{
 
-	return error;
+	return puffs_getvnode1(mp, ck, type, vsize, rdev, true, vpp);
 }
 
 /* new node creating for creative vop ops (create, symlink, mkdir, mknod) */
@@ -199,54 +147,37 @@ puffs_newnode(struct mount *mp, struct v
 	enum vtype type, dev_t rdev)
 {
 	struct puffs_mount *pmp = MPTOPUFFSMP(mp);
-	struct puffs_newcookie *pnc;
-	struct vnode *vp;
 	int error;
 
 	/* userspace probably has this as a NULL op */
-	if (ck == NULL) {
-		error = EOPNOTSUPP;
-		return error;
-	}
+	if (ck == NULL)
+		return EOPNOTSUPP;
 
 	/*
 	 * Check for previous node with the same designation.
 	 * Explicitly check the root node cookie, since it might be
 	 * reclaimed from the kernel when this check is made.
 	 */
-	mutex_enter(&pmp->pmp_lock);
-	if (ck == pmp->pmp_root_cookie
-	    || puffs_cookie2pnode(pmp, ck) != NULL) {
-		mutex_exit(&pmp->pmp_lock);
+	if (ck == pmp->pmp_root_cookie) {
 		puffs_senderr(pmp, PUFFS_ERR_MAKENODE, EEXIST,
 		    "cookie exists", ck);
 		return EPROTO;
 	}
 
-	LIST_FOREACH(pnc, &pmp->pmp_newcookie, pnc_entries) {
-		if (pnc->pnc_cookie == ck) {
-			mutex_exit(&pmp->pmp_lock);
-			puffs_senderr(pmp, PUFFS_ERR_MAKENODE, EEXIST,
-			    "newcookie exists", ck);
-			return EPROTO;
-		}
-	}
-
 	KASSERT(curlwp != uvm.pagedaemon_lwp);
-	pnc = kmem_alloc(sizeof(struct puffs_newcookie), KM_SLEEP);
-	pnc->pnc_cookie = ck;
-	LIST_INSERT_HEAD(&pmp->pmp_newcookie, pnc, pnc_entries);
-	mutex_exit(&pmp->pmp_lock);
 
-	error = puffs_getvnode(dvp->v_mount, ck, type, 0, rdev, &vp);
-	if (error)
+	error = puffs_getvnode1(dvp->v_mount, ck, type, 0, rdev, false, vpp);
+	if (error) {
+		if (error == EEXIST) {
+			puffs_senderr(pmp, PUFFS_ERR_MAKENODE, EEXIST,
+			    "cookie exists", ck);
+			error = EPROTO;
+		}
 		return error;
-
-	vp->v_type = type;
-	*vpp = vp;
+	}
 
 	if (PUFFS_USE_NAMECACHE(pmp))
-		cache_enter(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
+		cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
 			    cnp->cn_flags);
 
 	return 0;
@@ -259,44 +190,18 @@ puffs_putvnode(struct vnode *vp)
 
 	pnode = VPTOPP(vp);
 
-#ifdef DIAGNOSTIC
-	if (vp->v_tag != VT_PUFFS)
-		panic("puffs_putvnode: %p not a puffs vnode", vp);
-#endif
+	KASSERT(vp->v_tag == VT_PUFFS);
 
+	vcache_remove(vp->v_mount, &pnode->pn_cookie, sizeof(pnode->pn_cookie));
 	genfs_node_destroy(vp);
-	puffs_releasenode(pnode);
+	
+	/*
+	 * To interlock with puffs_getvnode1().
+	 */
+	mutex_enter(vp->v_interlock);
 	vp->v_data = NULL;
-
-	return;
-}
-
-static __inline struct puffs_node_hashlist *
-puffs_cookie2hashlist(struct puffs_mount *pmp, puffs_cookie_t ck)
-{
-	uint32_t hash;
-
-	hash = hash32_buf(&ck, sizeof(ck), HASH32_BUF_INIT);
-	return &pmp->pmp_pnodehash[hash % pmp->pmp_npnodehash];
-}
-
-/*
- * Translate cookie to puffs_node.  Caller must hold pmp_lock
- * and it will be held upon return.
- */
-static struct puffs_node *
-puffs_cookie2pnode(struct puffs_mount *pmp, puffs_cookie_t ck)
-{
-	struct puffs_node_hashlist *plist;
-	struct puffs_node *pnode;
-
-	plist = puffs_cookie2hashlist(pmp, ck);
-	LIST_FOREACH(pnode, plist, pn_hashent) {
-		if (pnode->pn_cookie == ck)
-			break;
-	}
-
-	return pnode;
+	mutex_exit(vp->v_interlock);
+	puffs_releasenode(pnode);
 }
 
 /*
@@ -314,48 +219,15 @@ puffs_makeroot(struct puffs_mount *pmp)
 	 *
 	 * pmp_root is set here and cleared in puffs_reclaim().
 	 */
- retry:
-	mutex_enter(&pmp->pmp_lock);
-	vp = pmp->pmp_root;
-	if (vp) {
-		mutex_enter(vp->v_interlock);
-		mutex_exit(&pmp->pmp_lock);
-		switch (vget(vp, 0)) {
-		case ENOENT:
-			goto retry;
-		case 0:
-			return 0;
-		default:
-			break;
-		}
-	} else
-		mutex_exit(&pmp->pmp_lock);
 
-	/*
-	 * So, didn't have the magic root vnode available.
-	 * No matter, grab another and stuff it with the cookie.
-	 */
-	if ((rv = puffs_getvnode(pmp->pmp_mp, pmp->pmp_root_cookie,
-	    pmp->pmp_root_vtype, pmp->pmp_root_vsize, pmp->pmp_root_rdev, &vp)))
+	rv = puffs_getvnode(pmp->pmp_mp, pmp->pmp_root_cookie,
+	    pmp->pmp_root_vtype, pmp->pmp_root_vsize, pmp->pmp_root_rdev, &vp);
+	if (rv != 0)
 		return rv;
 
-	/*
-	 * Someone magically managed to race us into puffs_getvnode?
-	 * Put our previous new vnode back and retry.
-	 */
 	mutex_enter(&pmp->pmp_lock);
-	if (pmp->pmp_root) {
-		struct puffs_node *pnode = vp->v_data;
-
-		LIST_REMOVE(pnode, pn_hashent);
-		mutex_exit(&pmp->pmp_lock);
-		puffs_putvnode(vp);
-		goto retry;
-	} 
-
-	/* store cache */
-	vp->v_vflag |= VV_ROOT;
-	pmp->pmp_root = vp;
+	if (pmp->pmp_root == NULL)
+		pmp->pmp_root = vp;
 	mutex_exit(&pmp->pmp_lock);
 
 	return 0;
@@ -364,26 +236,16 @@ puffs_makeroot(struct puffs_mount *pmp)
 /*
  * Locate the in-kernel vnode based on the cookie received given
  * from userspace.
- * The parameter "lock" control whether to lock the possible or
- * not.  Locking always might cause us to lock against ourselves
- * in situations where we want the vnode but don't care for the
- * vnode lock, e.g. file server issued putpages.
  *
  * returns 0 on success.  otherwise returns an errno or PUFFS_NOSUCHCOOKIE.
  *
  * returns PUFFS_NOSUCHCOOKIE if no vnode for the cookie is found.
- * in that case, if willcreate=true, the pmp_newcookie list is populated with
- * the given cookie.  it's the caller's responsibility to consume the entry
- * with calling puffs_getvnode.
  */
 int
-puffs_cookie2vnode(struct puffs_mount *pmp, puffs_cookie_t ck, int lock,
-	int willcreate, struct vnode **vpp)
+puffs_cookie2vnode(struct puffs_mount *pmp, puffs_cookie_t ck,
+    struct vnode **vpp)
 {
-	struct puffs_node *pnode;
-	struct puffs_newcookie *pnc;
-	struct vnode *vp;
-	int vgetflags, rv;
+	int rv;
 
 	/*
 	 * Handle root in a special manner, since we want to make sure
@@ -392,43 +254,21 @@ puffs_cookie2vnode(struct puffs_mount *p
 	if (ck == pmp->pmp_root_cookie) {
 		if ((rv = puffs_makeroot(pmp)))
 			return rv;
-		if (lock)
-			vn_lock(pmp->pmp_root, LK_EXCLUSIVE | LK_RETRY);
-
 		*vpp = pmp->pmp_root;
 		return 0;
 	}
 
- retry:
-	mutex_enter(&pmp->pmp_lock);
-	pnode = puffs_cookie2pnode(pmp, ck);
-	if (pnode == NULL) {
-		if (willcreate) {
-			pnc = kmem_alloc(sizeof(struct puffs_newcookie),
-			    KM_SLEEP);
-			pnc->pnc_cookie = ck;
-			LIST_INSERT_HEAD(&pmp->pmp_newcookie, pnc, pnc_entries);
-		}
-		mutex_exit(&pmp->pmp_lock);
-		return PUFFS_NOSUCHCOOKIE;
-	}
-	vp = pnode->pn_vp;
-	mutex_enter(vp->v_interlock);
-	mutex_exit(&pmp->pmp_lock);
-
-	vgetflags = 0;
-	if (lock)
-		vgetflags |= LK_EXCLUSIVE;
-	switch (rv = vget(vp, vgetflags)) {
-	case ENOENT:
-		goto retry;
-	case 0:
-		break;
-	default:
+	rv = vcache_get(PMPTOMP(pmp), ck, sizeof(ck), vpp);
+	if (rv != 0)
 		return rv;
+	mutex_enter((*vpp)->v_interlock);
+	if ((*vpp)->v_type == VNON) {
+		mutex_exit((*vpp)->v_interlock);
+		vrele(*vpp);
+		*vpp = NULL;
+		return PUFFS_NOSUCHCOOKIE;
 	}
 
-	*vpp = vp;
 	return 0;
 }
 

Index: src/sys/fs/puffs/puffs_sys.h
diff -u src/sys/fs/puffs/puffs_sys.h:1.85 src/sys/fs/puffs/puffs_sys.h:1.86
--- src/sys/fs/puffs/puffs_sys.h:1.85	Sat Aug 16 16:19:41 2014
+++ src/sys/fs/puffs/puffs_sys.h	Thu Aug 28 08:29:50 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_sys.h,v 1.85 2014/08/16 16:19:41 manu Exp $	*/
+/*	$NetBSD: puffs_sys.h,v 1.86 2014/08/28 08:29:50 hannken Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
@@ -144,15 +144,6 @@ struct puffs_mount {
 
 	struct puffs_wq			pmp_msg_replywait;
 
-	struct puffs_node_hashlist	*pmp_pnodehash;
-	int				pmp_npnodehash;
-
-	/*
-	 * a list of cookies which is going to be puffs_getvnode'd.
-	 * this is merely a loose attempt to prevent races.
-	 */
-	LIST_HEAD(, puffs_newcookie)	pmp_newcookie;
-
 	struct mount			*pmp_mp;
 
 	struct vnode			*pmp_root;
@@ -237,8 +228,6 @@ struct puffs_node {
 	int		pn_va_timeout;	/* attribute cache */
 	struct vattr *	pn_va_cache;	/* attribute cache */
 	struct vnode *  pn_parent;	/* parent cache */
-
-	LIST_ENTRY(puffs_node) pn_hashent;
 };
 
 typedef void (*parkdone_fn)(struct puffs_mount *, struct puffs_req *, void *);
@@ -274,7 +263,7 @@ void	puffs_releasenode(struct puffs_node
 void	puffs_referencenode(struct puffs_node *);
 
 #define PUFFS_NOSUCHCOOKIE (-1)
-int	puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t, int, int,
+int	puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t,
 			   struct vnode **);
 void	puffs_makecn(struct puffs_kcn *, struct puffs_kcred *,
 		     const struct componentname *, int);

Index: src/sys/fs/puffs/puffs_vfsops.c
diff -u src/sys/fs/puffs/puffs_vfsops.c:1.113 src/sys/fs/puffs/puffs_vfsops.c:1.114
--- src/sys/fs/puffs/puffs_vfsops.c:1.113	Sun May 25 19:32:36 2014
+++ src/sys/fs/puffs/puffs_vfsops.c	Thu Aug 28 08:29:50 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vfsops.c,v 1.113 2014/05/25 19:32:36 christos Exp $	*/
+/*	$NetBSD: puffs_vfsops.c,v 1.114 2014/08/28 08:29:50 hannken Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.113 2014/05/25 19:32:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.114 2014/08/28 08:29:50 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -62,17 +62,6 @@ MODULE(MODULE_CLASS_VFS, puffs, "putter"
 
 VFS_PROTOS(puffs_vfsop);
 
-#ifndef PUFFS_PNODEBUCKETS
-#define PUFFS_PNODEBUCKETS 256
-#endif
-#ifndef PUFFS_MAXPNODEBUCKETS
-#define PUFFS_MAXPNODEBUCKETS 8192
-#endif
-int puffs_pnodebuckets_default = PUFFS_PNODEBUCKETS;
-int puffs_maxpnodebuckets = PUFFS_MAXPNODEBUCKETS;
-
-#define BUCKETALLOC(a) (sizeof(struct puffs_pnode_hashlist *) * (a))
-
 static struct putter_ops puffs_putter = {
 	.pop_getout	= puffs_msgif_getout,
 	.pop_releaseout	= puffs_msgif_releaseout,
@@ -81,6 +70,15 @@ static struct putter_ops puffs_putter = 
 	.pop_close	= puffs_msgif_close,
 };
 
+static const struct genfs_ops puffs_genfsops = {
+        .gop_size = puffs_gop_size,
+	.gop_write = genfs_gop_write,
+	.gop_markupdate = puffs_gop_markupdate,
+#if 0
+	.gop_alloc, should ask userspace
+#endif
+};
+
 /*
  * Try to ensure data structures used by the puffs protocol
  * do not unexpectedly change.
@@ -206,17 +204,6 @@ puffs_vfsop_mount(struct mount *mp, cons
 
 	(void)strlcpy(args->pa_typename, fstype, sizeof(args->pa_typename));
 
-	if (args->pa_nhashbuckets == 0)
-		args->pa_nhashbuckets = puffs_pnodebuckets_default;
-	if (args->pa_nhashbuckets < 1)
-		args->pa_nhashbuckets = 1;
-	if (args->pa_nhashbuckets > PUFFS_MAXPNODEBUCKETS) {
-		args->pa_nhashbuckets = puffs_maxpnodebuckets;
-		printf("puffs_mount: using %d hash buckets. "
-		    "adjust puffs_maxpnodebuckets for more\n",
-		    puffs_maxpnodebuckets);
-	}
-
 	error = set_statvfs_info(path, UIO_USERSPACE, args->pa_mntfromname,
 	    UIO_SYSSPACE, fstype, mp, curlwp);
 	if (error)
@@ -270,13 +257,6 @@ puffs_vfsop_mount(struct mount *mp, cons
 	pmp->pmp_msg_maxsize = args->pa_maxmsglen;
 	pmp->pmp_args = *args;
 
-	pmp->pmp_npnodehash = args->pa_nhashbuckets;
-	pmp->pmp_pnodehash = kmem_alloc(BUCKETALLOC(pmp->pmp_npnodehash),
-	    KM_SLEEP);
-	for (i = 0; i < pmp->pmp_npnodehash; i++)
-		LIST_INIT(&pmp->pmp_pnodehash[i]);
-	LIST_INIT(&pmp->pmp_newcookie);
-
 	/*
 	 * Inform the fileops processing code that we have a mountpoint.
 	 * If it doesn't know about anyone with our pid/fd having the
@@ -319,8 +299,6 @@ puffs_vfsop_mount(struct mount *mp, cons
  out:
 	if (error && pmp && pmp->pmp_pi)
 		putter_detach(pmp->pmp_pi);
-	if (error && pmp && pmp->pmp_pnodehash)
-		kmem_free(pmp->pmp_pnodehash, BUCKETALLOC(pmp->pmp_npnodehash));
 	if (error && pmp)
 		kmem_free(pmp, sizeof(struct puffs_mount));
 	return error;
@@ -441,7 +419,6 @@ puffs_vfsop_unmount(struct mount *mp, in
 		mutex_destroy(&pmp->pmp_lock);
 		mutex_destroy(&pmp->pmp_sopmtx);
 
-		kmem_free(pmp->pmp_pnodehash, BUCKETALLOC(pmp->pmp_npnodehash));
 		kmem_free(pmp, sizeof(struct puffs_mount));
 		error = 0;
 	} else {
@@ -462,9 +439,17 @@ puffs_vfsop_root(struct mount *mp, struc
 	struct puffs_mount *pmp = MPTOPUFFSMP(mp);
 	int rv;
 
-	rv = puffs_cookie2vnode(pmp, pmp->pmp_root_cookie, 1, 1, vpp);
+	rv = puffs_cookie2vnode(pmp, pmp->pmp_root_cookie, vpp);
 	KASSERT(rv != PUFFS_NOSUCHCOOKIE);
-	return rv;
+	if (rv != 0)
+		return rv;
+	rv = vn_lock(*vpp, LK_EXCLUSIVE);
+	if (rv != 0) {
+		vrele(*vpp);
+		*vpp = NULL;
+		return rv;
+	}
+	return 0;
 }
 
 int
@@ -644,19 +629,12 @@ puffs_vfsop_fhtovp(struct mount *mp, str
 	if (error)
 		goto out;
 
-	error = puffs_cookie2vnode(pmp, fhtonode_msg->pvfsr_fhcookie, 1,1,&vp);
-	DPRINTF(("puffs_fhtovp: got cookie %p, existing vnode %p\n",
-	    fhtonode_msg->pvfsr_fhcookie, vp));
-	if (error == PUFFS_NOSUCHCOOKIE) {
-		error = puffs_getvnode(mp, fhtonode_msg->pvfsr_fhcookie,
-		    fhtonode_msg->pvfsr_vtype, fhtonode_msg->pvfsr_size,
-		    fhtonode_msg->pvfsr_rdev, &vp);
-		if (error)
-			goto out;
-		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-	} else if (error) {
+	error = puffs_getvnode(mp, fhtonode_msg->pvfsr_fhcookie,
+	    fhtonode_msg->pvfsr_vtype, fhtonode_msg->pvfsr_size,
+	    fhtonode_msg->pvfsr_rdev, &vp);
+	if (error)
 		goto out;
-	}
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 
 	*vpp = vp;
  out:
@@ -739,6 +717,41 @@ puffs_vfsop_vptofh(struct vnode *vp, str
 	return error;
 }
 
+int
+puffs_vfsop_loadvnode(struct mount *mp, struct vnode *vp,
+    const void *key, size_t key_len, const void **new_key)
+{
+	struct puffs_mount *pmp;
+	struct puffs_node *pnode;
+
+	KASSERT(key_len == sizeof(puffs_cookie_t));
+
+	pmp = MPTOPUFFSMP(mp);
+
+	/* Allocate and initialize the pnode. */
+	pnode = pool_get(&puffs_pnpool, PR_WAITOK);
+	memset(pnode, 0, sizeof(struct puffs_node));
+
+	pnode->pn_vp = vp;
+	memcpy(&pnode->pn_cookie, key, key_len);
+	pnode->pn_refcount = 1;
+	mutex_init(&pnode->pn_mtx, MUTEX_DEFAULT, IPL_NONE);
+	mutex_init(&pnode->pn_sizemtx, MUTEX_DEFAULT, IPL_NONE);
+	selinit(&pnode->pn_sel);
+	vp->v_tag = VT_PUFFS;
+	vp->v_type = VNON;
+	vp->v_op = puffs_vnodeop_p;
+	if (pnode->pn_cookie == pmp->pmp_root_cookie)
+		vp->v_vflag |= VV_ROOT;
+	vp->v_data = pnode;
+
+	genfs_node_init(vp, &puffs_genfsops);
+	uvm_vnp_setsize(vp, 0);
+
+	*new_key = &pnode->pn_cookie;
+	return 0;
+}
+
 void
 puffs_vfsop_init(void)
 {
@@ -838,6 +851,7 @@ struct vfsops puffs_vfsops = {
 	.vfs_statvfs = puffs_vfsop_statvfs,
 	.vfs_sync = puffs_vfsop_sync,
 	.vfs_vget = (void *)eopnotsupp,
+	.vfs_loadvnode = puffs_vfsop_loadvnode,
 	.vfs_fhtovp = puffs_vfsop_fhtovp,
 	.vfs_vptofh = puffs_vfsop_vptofh,
 	.vfs_init = puffs_vfsop_init,

Index: src/sys/fs/puffs/puffs_vnops.c
diff -u src/sys/fs/puffs/puffs_vnops.c:1.183 src/sys/fs/puffs/puffs_vnops.c:1.184
--- src/sys/fs/puffs/puffs_vnops.c:1.183	Sat Aug 16 16:19:41 2014
+++ src/sys/fs/puffs/puffs_vnops.c	Thu Aug 28 08:29:50 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vnops.c,v 1.183 2014/08/16 16:19:41 manu Exp $	*/
+/*	$NetBSD: puffs_vnops.c,v 1.184 2014/08/28 08:29:50 hannken Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.183 2014/08/16 16:19:41 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.184 2014/08/28 08:29:50 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -668,11 +668,6 @@ puffs_vnop_lookup(void *v)
 	 * match the userland cookie anymore: is the node known?
 	 */
 	if (vp == NULL) {
-		error = puffs_cookie2vnode(pmp, lookup_msg->pvnr_newnode,
-					   1, 1, &vp);
-	}
-
-	if (error == PUFFS_NOSUCHCOOKIE) {
 		error = puffs_getvnode(dvp->v_mount,
 		    lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
 		    lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp);
@@ -684,10 +679,6 @@ puffs_vnop_lookup(void *v)
 		}
 
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-	} else if (error) {
-		puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, VPTOPNC(dvp),
-		    lookup_msg->pvnr_newnode, ap->a_cnp);
-		goto out;
 	}
 
 	/*
@@ -1401,7 +1392,6 @@ puffs_vnop_reclaim(void *v)
 	} */ *ap = v;
 	struct vnode *vp = ap->a_vp;
 	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
-	struct puffs_node *pnode = vp->v_data;
 	bool notifyserver = true;
 
 	/*
@@ -1424,7 +1414,6 @@ puffs_vnop_reclaim(void *v)
 	 * that and someone might race us into node creation
 	 */
 	mutex_enter(&pmp->pmp_lock);
-	LIST_REMOVE(pnode, pn_hashent);
 	if (PUFFS_USE_NAMECACHE(pmp))
 		cache_purge(vp);
 	mutex_exit(&pmp->pmp_lock);
@@ -1443,7 +1432,6 @@ puffs_vnop_reclaim(void *v)
 	}
 
 	puffs_putvnode(vp);
-	vp->v_data = NULL;
 
 	return 0;
 }

Reply via email to