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/356372bb8bef
branches:  trunk
changeset: 801734:356372bb8bef
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 3be668cc69fd -r 356372bb8bef 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 3be668cc69fd -r 356372bb8bef 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