Module Name: src
Committed By: martin
Date: Fri Aug 29 11:55:34 UTC 2014
Modified Files:
src/sys/fs/puffs [netbsd-7]: puffs_msgif.c puffs_node.c puffs_sys.h
puffs_vfsops.c puffs_vnops.c
Log Message:
Pull up following revision(s) (requested by hannken in ticket #67):
sys/fs/puffs/puffs_sys.h: revision 1.86
sys/fs/puffs/puffs_vfsops.c: revision 1.114
sys/fs/puffs/puffs_msgif.c: revision 1.95
sys/fs/puffs/puffs_node.c: revision 1.32
sys/fs/puffs/puffs_vnops.c: revision 1.184
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.94.4.1 src/sys/fs/puffs/puffs_msgif.c
cvs rdiff -u -r1.31 -r1.31.4.1 src/sys/fs/puffs/puffs_node.c
cvs rdiff -u -r1.84.4.1 -r1.84.4.2 src/sys/fs/puffs/puffs_sys.h
cvs rdiff -u -r1.113 -r1.113.2.1 src/sys/fs/puffs/puffs_vfsops.c
cvs rdiff -u -r1.182.2.1 -r1.182.2.2 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.94.4.1
--- src/sys/fs/puffs/puffs_msgif.c:1.94 Thu Oct 17 21:03:27 2013
+++ src/sys/fs/puffs/puffs_msgif.c Fri Aug 29 11:55:34 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.94.4.1 2014/08/29 11:55:34 martin 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.94.4.1 2014/08/29 11:55:34 martin 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.31.4.1
--- src/sys/fs/puffs/puffs_node.c:1.31 Thu Jan 23 10:13:56 2014
+++ src/sys/fs/puffs/puffs_node.c Fri Aug 29 11:55:34 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.31.4.1 2014/08/29 11:55:34 martin 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.31.4.1 2014/08/29 11:55:34 martin 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.84.4.1 src/sys/fs/puffs/puffs_sys.h:1.84.4.2
--- src/sys/fs/puffs/puffs_sys.h:1.84.4.1 Tue Aug 26 23:15:12 2014
+++ src/sys/fs/puffs/puffs_sys.h Fri Aug 29 11:55:34 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: puffs_sys.h,v 1.84.4.1 2014/08/26 23:15:12 riz Exp $ */
+/* $NetBSD: puffs_sys.h,v 1.84.4.2 2014/08/29 11:55:34 martin 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.113.2.1
--- src/sys/fs/puffs/puffs_vfsops.c:1.113 Sun May 25 19:32:36 2014
+++ src/sys/fs/puffs/puffs_vfsops.c Fri Aug 29 11:55:34 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.113.2.1 2014/08/29 11:55:34 martin 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.113.2.1 2014/08/29 11:55:34 martin 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.182.2.1 src/sys/fs/puffs/puffs_vnops.c:1.182.2.2
--- src/sys/fs/puffs/puffs_vnops.c:1.182.2.1 Tue Aug 26 23:15:12 2014
+++ src/sys/fs/puffs/puffs_vnops.c Fri Aug 29 11:55:34 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: puffs_vnops.c,v 1.182.2.1 2014/08/26 23:15:12 riz Exp $ */
+/* $NetBSD: puffs_vnops.c,v 1.182.2.2 2014/08/29 11:55:34 martin 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.182.2.1 2014/08/26 23:15:12 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.182.2.2 2014/08/29 11:55:34 martin 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;
}