Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/ptyfs Change ptyfs to vcache.
details: https://anonhg.NetBSD.org/src/rev/8534508b38fe
branches: trunk
changeset: 331592:8534508b38fe
user: hannken <hannken%NetBSD.org@localhost>
date: Fri Aug 15 13:40:39 2014 +0000
description:
Change ptyfs to vcache.
- Use (type, minor) as key.
- Change ptyfs_allocvp to return a referenced vnode and lock where needed.
- Remove unneeded vnode backpointer ptyfs_vnode.
- Keep a single hashlist for pty nodes to make their attributes persistent.
OK: Christos Zoulas
diffstat:
sys/fs/ptyfs/ptyfs.h | 18 +-
sys/fs/ptyfs/ptyfs_subr.c | 236 ++++---------------------------------------
sys/fs/ptyfs/ptyfs_vfsops.c | 72 ++++++++++++-
sys/fs/ptyfs/ptyfs_vnops.c | 19 +-
4 files changed, 110 insertions(+), 235 deletions(-)
diffs (truncated from 537 to 300 lines):
diff -r b507d5face71 -r 8534508b38fe sys/fs/ptyfs/ptyfs.h
--- a/sys/fs/ptyfs/ptyfs.h Fri Aug 15 13:32:53 2014 +0000
+++ b/sys/fs/ptyfs/ptyfs.h Fri Aug 15 13:40:39 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ptyfs.h,v 1.13 2014/08/13 14:10:00 hannken Exp $ */
+/* $NetBSD: ptyfs.h,v 1.14 2014/08/15 13:40:39 hannken Exp $ */
/*
* Copyright (c) 1993
@@ -87,11 +87,15 @@
/*
* control data for the proc file system.
*/
+struct ptyfskey {
+ ptyfstype ptk_type; /* type of ptyfs node */
+ int ptk_pty; /* the pty index */
+};
struct ptyfsnode {
- LIST_ENTRY(ptyfsnode) ptyfs_hash; /* hash chain */
- struct vnode *ptyfs_vnode; /* vnode associated with this ptyfsnode */
- ptyfstype ptyfs_type; /* type of ptyfs node */
- int ptyfs_pty; /* the pty index */
+ SLIST_ENTRY(ptyfsnode) ptyfs_hash; /* hash chain */
+ struct ptyfskey ptyfs_key;
+#define ptyfs_type ptyfs_key.ptk_type
+#define ptyfs_pty ptyfs_key.ptk_pty
u_long ptyfs_fileno; /* unique file id */
int ptyfs_status; /* status flag for times */
#define PTYFS_ACCESS 1
@@ -150,16 +154,14 @@
* Convert between ptyfsnode vnode
*/
#define VTOPTYFS(vp) ((struct ptyfsnode *)(vp)->v_data)
-#define PTYFSTOV(ptyfs) ((ptyfs)->ptyfs_vnode)
-int ptyfs_freevp(struct vnode *);
void ptyfs_set_active(struct mount *, int);
void ptyfs_clr_active(struct mount *, int);
int ptyfs_next_active(struct mount *, int);
int ptyfs_allocvp(struct mount *, struct vnode **, ptyfstype, int);
void ptyfs_hashinit(void);
-void ptyfs_hashreinit(void);
void ptyfs_hashdone(void);
+struct ptyfsnode *ptyfs_get_node(ptyfstype, int);
void ptyfs_itimes(struct ptyfsnode *, const struct timespec *,
const struct timespec *, const struct timespec *);
diff -r b507d5face71 -r 8534508b38fe sys/fs/ptyfs/ptyfs_subr.c
--- a/sys/fs/ptyfs/ptyfs_subr.c Fri Aug 15 13:32:53 2014 +0000
+++ b/sys/fs/ptyfs/ptyfs_subr.c Fri Aug 15 13:40:39 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ptyfs_subr.c,v 1.30 2014/08/13 14:10:00 hannken Exp $ */
+/* $NetBSD: ptyfs_subr.c,v 1.31 2014/08/15 13:40:39 hannken Exp $ */
/*
* Copyright (c) 1993
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ptyfs_subr.c,v 1.30 2014/08/13 14:10:00 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ptyfs_subr.c,v 1.31 2014/08/15 13:40:39 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -92,110 +92,29 @@
#include <sys/lwp.h>
#include <fs/ptyfs/ptyfs.h>
-#include <miscfs/specfs/specdev.h>
static kmutex_t ptyfs_hashlock;
-static LIST_HEAD(ptyfs_hashhead, ptyfsnode) *ptyfs_used_tbl, *ptyfs_free_tbl;
-static u_long ptyfs_used_mask, ptyfs_free_mask; /* size of hash table - 1 */
-static kmutex_t ptyfs_used_slock, ptyfs_free_slock;
-
-static void ptyfs_hashins(struct ptyfsnode *);
-static void ptyfs_hashrem(struct ptyfsnode *);
-
-static struct vnode *ptyfs_used_get(ptyfstype, int, struct mount *, int);
-static struct ptyfsnode *ptyfs_free_get(ptyfstype, int);
-
-static void ptyfs_rehash(kmutex_t *, struct ptyfs_hashhead **,
- u_long *);
-
-#define PTYHASH(type, pty, mask) (PTYFS_FILENO(type, pty) % (mask + 1))
-
+static SLIST_HEAD(ptyfs_hashhead, ptyfsnode) *ptyfs_node_tbl;
+static u_long ptyfs_node_mask; /* size of hash table - 1 */
/*
- * allocate a ptyfsnode/vnode pair. the vnode is
- * referenced, and locked.
+ * allocate a ptyfsnode/vnode pair. the vnode is referenced.
*
* the pty, ptyfs_type, and mount point uniquely
* identify a ptyfsnode. the mount point is needed
* because someone might mount this filesystem
* twice.
- *
- * all ptyfsnodes are maintained on a singly-linked
- * list. new nodes are only allocated when they cannot
- * be found on this list. entries on the list are
- * removed when the vfs reclaim entry is called.
- *
- * a single lock is kept for the entire list. this is
- * needed because the getnewvnode() function can block
- * waiting for a vnode to become free, in which case there
- * may be more than one ptyess trying to get the same
- * vnode. this lock is only taken if we are going to
- * call getnewvnode, since the kernel itself is single-threaded.
- *
- * if an entry is found on the list, then call vget() to
- * take a reference. this is done because there may be
- * zero references to it and so it needs to removed from
- * the vnode free list.
*/
int
ptyfs_allocvp(struct mount *mp, struct vnode **vpp, ptyfstype type, int pty)
{
- struct ptyfsnode *ptyfs;
- struct vnode *vp;
- int error;
-
- retry:
- if ((*vpp = ptyfs_used_get(type, pty, mp, LK_EXCLUSIVE)) != NULL)
- return 0;
-
- error = getnewvnode(VT_PTYFS, mp, ptyfs_vnodeop_p, NULL, &vp);
- if (error) {
- *vpp = NULL;
- return error;
- }
-
- mutex_enter(&ptyfs_hashlock);
- if (ptyfs_used_get(type, pty, mp, 0) != NULL) {
- mutex_exit(&ptyfs_hashlock);
- ungetnewvnode(vp);
- goto retry;
- }
-
- vp->v_data = ptyfs = ptyfs_free_get(type, pty);
- ptyfs->ptyfs_vnode = vp;
+ struct ptyfskey key;
- switch (type) {
- case PTYFSroot: /* /pts = dr-xr-xr-x */
- vp->v_type = VDIR;
- vp->v_vflag = VV_ROOT;
- break;
-
- case PTYFSpts: /* /pts/N = cxxxxxxxxx */
- case PTYFSptc: /* controlling side = cxxxxxxxxx */
- vp->v_type = VCHR;
- spec_node_init(vp, PTYFS_MAKEDEV(ptyfs));
- break;
- default:
- panic("ptyfs_allocvp");
- }
-
- ptyfs_hashins(ptyfs);
- uvm_vnp_setsize(vp, 0);
- mutex_exit(&ptyfs_hashlock);
-
- *vpp = vp;
- return 0;
-}
-
-int
-ptyfs_freevp(struct vnode *vp)
-{
- struct ptyfsnode *ptyfs = VTOPTYFS(vp);
-
- ptyfs_hashrem(ptyfs);
- vp->v_data = NULL;
- return 0;
+ memset(&key, 0, sizeof(key));
+ key.ptk_pty = pty;
+ key.ptk_type = type;
+ return vcache_get(mp, &key, sizeof(key), vpp);
}
/*
@@ -204,47 +123,9 @@
void
ptyfs_hashinit(void)
{
- ptyfs_used_tbl = hashinit(desiredvnodes / 4, HASH_LIST, true,
- &ptyfs_used_mask);
- ptyfs_free_tbl = hashinit(desiredvnodes / 4, HASH_LIST, true,
- &ptyfs_free_mask);
+
+ ptyfs_node_tbl = hashinit(16, HASH_LIST, true, &ptyfs_node_mask);
mutex_init(&ptyfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
- mutex_init(&ptyfs_used_slock, MUTEX_DEFAULT, IPL_NONE);
- mutex_init(&ptyfs_free_slock, MUTEX_DEFAULT, IPL_NONE);
-}
-
-void
-ptyfs_hashreinit(void)
-{
- ptyfs_rehash(&ptyfs_used_slock, &ptyfs_used_tbl, &ptyfs_used_mask);
- ptyfs_rehash(&ptyfs_free_slock, &ptyfs_free_tbl, &ptyfs_free_mask);
-}
-
-static void
-ptyfs_rehash(kmutex_t *hlock, struct ptyfs_hashhead **hhead,
- u_long *hmask)
-{
- struct ptyfsnode *pp;
- struct ptyfs_hashhead *oldhash, *hash;
- u_long i, oldmask, mask, val;
-
- hash = hashinit(desiredvnodes / 4, HASH_LIST, true, &mask);
-
- mutex_enter(hlock);
- oldhash = *hhead;
- oldmask = *hmask;
- *hhead = hash;
- *hmask = mask;
- for (i = 0; i <= oldmask; i++) {
- while ((pp = LIST_FIRST(&oldhash[i])) != NULL) {
- LIST_REMOVE(pp, ptyfs_hash);
- val = PTYHASH(pp->ptyfs_type, pp->ptyfs_pty,
- ptyfs_used_mask);
- LIST_INSERT_HEAD(&hash[val], pp, ptyfs_hash);
- }
- }
- mutex_exit(hlock);
- hashdone(oldhash, HASH_LIST, oldmask);
}
/*
@@ -255,32 +136,28 @@
{
mutex_destroy(&ptyfs_hashlock);
- mutex_destroy(&ptyfs_used_slock);
- mutex_destroy(&ptyfs_free_slock);
- hashdone(ptyfs_used_tbl, HASH_LIST, ptyfs_used_mask);
- hashdone(ptyfs_free_tbl, HASH_LIST, ptyfs_free_mask);
+ hashdone(ptyfs_node_tbl, HASH_LIST, ptyfs_node_mask);
}
/*
- * Get a ptyfsnode from the free table, or allocate one.
- * Removes the node from the free table.
+ * Get a ptyfsnode from the hash table, or allocate one.
*/
struct ptyfsnode *
-ptyfs_free_get(ptyfstype type, int pty)
+ptyfs_get_node(ptyfstype type, int pty)
{
struct ptyfs_hashhead *ppp;
struct ptyfsnode *pp;
- mutex_enter(&ptyfs_free_slock);
- ppp = &ptyfs_free_tbl[PTYHASH(type, pty, ptyfs_free_mask)];
- LIST_FOREACH(pp, ppp, ptyfs_hash) {
+ ppp = &ptyfs_node_tbl[PTYFS_FILENO(type, pty) & ptyfs_node_mask];
+
+ mutex_enter(&ptyfs_hashlock);
+ SLIST_FOREACH(pp, ppp, ptyfs_hash) {
if (pty == pp->ptyfs_pty && pp->ptyfs_type == type) {
- LIST_REMOVE(pp, ptyfs_hash);
- mutex_exit(&ptyfs_free_slock);
+ mutex_exit(&ptyfs_hashlock);
return pp;
}
}
- mutex_exit(&ptyfs_free_slock);
+ mutex_exit(&ptyfs_hashlock);
pp = malloc(sizeof(struct ptyfsnode), M_TEMP, M_WAITOK);
pp->ptyfs_pty = pty;
@@ -299,77 +176,12 @@
pp->ptyfs_birthtime = pp->ptyfs_mtime =
pp->ptyfs_atime = pp->ptyfs_ctime;
pp->ptyfs_flags = 0;
+ mutex_enter(&ptyfs_hashlock);
+ SLIST_INSERT_HEAD(ppp, pp, ptyfs_hash);
+ mutex_exit(&ptyfs_hashlock);
return pp;
}
-struct vnode *
-ptyfs_used_get(ptyfstype type, int pty, struct mount *mp, int flags)
-{
- struct ptyfs_hashhead *ppp;
- struct ptyfsnode *pp;
- struct vnode *vp;
-
-loop:
- mutex_enter(&ptyfs_used_slock);
- ppp = &ptyfs_used_tbl[PTYHASH(type, pty, ptyfs_used_mask)];
- LIST_FOREACH(pp, ppp, ptyfs_hash) {
- vp = PTYFSTOV(pp);
- if (pty == pp->ptyfs_pty && pp->ptyfs_type == type &&
- vp->v_mount == mp) {
Home |
Main Index |
Thread Index |
Old Index