Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/miscfs/procfs Change procfs from hashlist to vcache.



details:   https://anonhg.NetBSD.org/src/rev/8b7626794da4
branches:  trunk
changeset: 331032:8b7626794da4
user:      hannken <hannken%NetBSD.org@localhost>
date:      Sun Jul 27 16:47:26 2014 +0000

description:
Change procfs from hashlist to vcache.
- Key is (type, pid, fd)
- Remove argument "p" from procfs_allocvp().  It is only used
  when "type == PFSfd".  Lookup the proc with proc_find() when
  procfs_loadvnode() needs it.
- Use a vfs_vnode_iterator for procfs_revoke_vnodes().

diffstat:

 sys/miscfs/procfs/procfs.h        |   22 +-
 sys/miscfs/procfs/procfs_subr.c   |  346 ++-----------------------------------
 sys/miscfs/procfs/procfs_vfsops.c |  180 +++++++++++++++++++-
 sys/miscfs/procfs/procfs_vnops.c  |   32 ++-
 4 files changed, 229 insertions(+), 351 deletions(-)

diffs (truncated from 793 to 300 lines):

diff -r 34101d61af3c -r 8b7626794da4 sys/miscfs/procfs/procfs.h
--- a/sys/miscfs/procfs/procfs.h        Sun Jul 27 16:37:47 2014 +0000
+++ b/sys/miscfs/procfs/procfs.h        Sun Jul 27 16:47:26 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: procfs.h,v 1.69 2014/04/05 18:42:32 christos Exp $     */
+/*     $NetBSD: procfs.h,v 1.70 2014/07/27 16:47:26 hannken Exp $      */
 
 /*
  * Copyright (c) 1993
@@ -118,12 +118,17 @@
 /*
  * control data for the proc file system.
  */
+struct pfskey {
+       pfstype         pk_type;        /* type of procfs node */
+       pid_t           pk_pid;         /* associated process */
+       int             pk_fd;          /* associated fd if not -1 */
+};
 struct pfsnode {
-       LIST_ENTRY(pfsnode) pfs_hash;   /* hash chain */
        struct vnode    *pfs_vnode;     /* vnode associated with this pfsnode */
-       pfstype         pfs_type;       /* type of procfs node */
-       pid_t           pfs_pid;        /* associated process */
-       int             pfs_fd;         /* associated fd if not -1 */
+       struct pfskey   pfs_key;
+#define pfs_type pfs_key.pk_type
+#define pfs_pid pfs_key.pk_pid
+#define pfs_fd pfs_key.pk_fd
        mode_t          pfs_mode;       /* mode bits for stat() */
        u_long          pfs_flags;      /* open flags */
        u_long          pfs_fileno;     /* unique file id */
@@ -187,9 +192,7 @@
 
 int procfs_proc_lock(int, struct proc **, int);
 void procfs_proc_unlock(struct proc *);
-int procfs_freevp(struct vnode *);
-int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int,
-    struct proc *);
+int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int);
 int procfs_donote(struct lwp *, struct proc *, struct pfsnode *,
     struct uio *);
 int procfs_doregs(struct lwp *, struct lwp *, struct pfsnode *,
@@ -232,9 +235,6 @@
     struct uio *);
 
 void procfs_revoke_vnodes(struct proc *, void *);
-void procfs_hashinit(void);
-void procfs_hashreinit(void);
-void procfs_hashdone(void);
 int procfs_getfp(struct pfsnode *, struct proc *, struct file **);
 
 /* functions to check whether or not files should be displayed */
diff -r 34101d61af3c -r 8b7626794da4 sys/miscfs/procfs/procfs_subr.c
--- a/sys/miscfs/procfs/procfs_subr.c   Sun Jul 27 16:37:47 2014 +0000
+++ b/sys/miscfs/procfs/procfs_subr.c   Sun Jul 27 16:47:26 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: procfs_subr.c,v 1.104 2014/02/07 15:29:22 hannken Exp $        */
+/*     $NetBSD: procfs_subr.c,v 1.105 2014/07/27 16:47:26 hannken Exp $        */
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.104 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.105 2014/07/27 16:47:26 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -118,224 +118,22 @@
 
 #include <miscfs/procfs/procfs.h>
 
-void procfs_hashins(struct pfsnode *);
-void procfs_hashrem(struct pfsnode *);
-struct vnode *procfs_hashget(pid_t, pfstype, int, struct mount *);
-
-LIST_HEAD(pfs_hashhead, pfsnode) *pfs_hashtbl;
-u_long pfs_ihash;      /* size of hash table - 1 */
-#define PFSPIDHASH(pid)        ((pid) & pfs_ihash)
-
-kmutex_t pfs_hashlock;
-kmutex_t pfs_ihash_lock;
-
-#define        ISSET(t, f)     ((t) & (f))
-
 /*
- * allocate a pfsnode/vnode pair.  the vnode is
- * referenced, and locked.
- *
- * the pid, pfs_type, and mount point uniquely
- * identify a pfsnode.  the mount point is needed
- * because someone might mount this filesystem
- * twice.
- *
- * all pfsnodes 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 process 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.
+ * Allocate a pfsnode/vnode pair.  The vnode is referenced.
+ * The pid, type, and file descriptor uniquely identify a pfsnode.
  */
 int
 procfs_allocvp(struct mount *mp, struct vnode **vpp, pid_t pid,
-    pfstype pfs_type, int fd, struct proc *p)
+    pfstype type, int fd)
 {
-       struct pfsnode *pfs;
-       struct vnode *vp;
-       int error;
-
-       *vpp = procfs_hashget(pid, pfs_type, fd, mp);
-       if (*vpp != NULL)
-               return (0);
-
-       error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, NULL, &vp);
-       if (error) {
-               *vpp = NULL;
-               return (error);
-       }
-       pfs = malloc(sizeof(struct pfsnode), M_TEMP, M_WAITOK);
-
-       mutex_enter(&pfs_hashlock);
-       if ((*vpp = procfs_hashget(pid, pfs_type, fd, mp)) != NULL) {
-               mutex_exit(&pfs_hashlock);
-               ungetnewvnode(vp);
-               free(pfs, M_TEMP);
-               return 0;
-       }
-
-       vp->v_data = pfs;
-       pfs->pfs_pid = pid;
-       pfs->pfs_type = pfs_type;
-       pfs->pfs_vnode = vp;
-       pfs->pfs_flags = 0;
-       pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type, fd);
-       pfs->pfs_fd = fd;
-
-       switch (pfs_type) {
-       case PFSroot:   /* /proc = dr-xr-xr-x */
-               vp->v_vflag |= VV_ROOT;
-               /*FALLTHROUGH*/
-       case PFSproc:   /* /proc/N = dr-xr-xr-x */
-               pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
-               vp->v_type = VDIR;
-               break;
-
-       case PFStask:   /* /proc/N/task = dr-xr-xr-x */
-               if (fd == -1) {
-                       pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|
-                           S_IROTH|S_IXOTH;
-                       vp->v_type = VDIR;
-                       break;
-               }
-               /*FALLTHROUGH*/
-       case PFScurproc:        /* /proc/curproc = lr-xr-xr-x */
-       case PFSself:   /* /proc/self    = lr-xr-xr-x */
-       case PFScwd:    /* /proc/N/cwd = lr-xr-xr-x */
-       case PFSchroot: /* /proc/N/chroot = lr-xr-xr-x */
-       case PFSexe:    /* /proc/N/exe = lr-xr-xr-x */
-               pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
-               vp->v_type = VLNK;
-               break;
-
-       case PFSfd:
-               if (fd == -1) { /* /proc/N/fd = dr-x------ */
-                       pfs->pfs_mode = S_IRUSR|S_IXUSR;
-                       vp->v_type = VDIR;
-               } else {        /* /proc/N/fd/M = [ps-]rw------- */
-                       file_t *fp;
-                       vnode_t *vxp;
-
-                       if ((fp = fd_getfile2(p, pfs->pfs_fd)) == NULL) {
-                               error = EBADF;
-                               goto bad;
-                       }
-
-                       pfs->pfs_mode = S_IRUSR|S_IWUSR;
-                       switch (fp->f_type) {
-                       case DTYPE_VNODE:
-                               vxp = fp->f_data;
+       struct pfskey key;
 
-                               /*
-                                * We make symlinks for directories
-                                * to avoid cycles.
-                                */
-                               if (vxp->v_type == VDIR)
-                                       goto symlink;
-                               vp->v_type = vxp->v_type;
-                               break;
-                       case DTYPE_PIPE:
-                               vp->v_type = VFIFO;
-                               break;
-                       case DTYPE_SOCKET:
-                               vp->v_type = VSOCK;
-                               break;
-                       case DTYPE_KQUEUE:
-                       case DTYPE_MISC:
-                       case DTYPE_SEM:
-                       symlink:
-                               pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|
-                                   S_IXGRP|S_IROTH|S_IXOTH;
-                               vp->v_type = VLNK;
-                               break;
-                       default:
-                               error = EOPNOTSUPP;
-                               closef(fp);
-                               goto bad;
-                       }
-                       closef(fp);
-               }
-               break;
-
-       case PFSfile:   /* /proc/N/file = -rw------- */
-       case PFSmem:    /* /proc/N/mem = -rw------- */
-       case PFSregs:   /* /proc/N/regs = -rw------- */
-       case PFSfpregs: /* /proc/N/fpregs = -rw------- */
-               pfs->pfs_mode = S_IRUSR|S_IWUSR;
-               vp->v_type = VREG;
-               break;
-
-       case PFSctl:    /* /proc/N/ctl = --w------ */
-       case PFSnote:   /* /proc/N/note = --w------ */
-       case PFSnotepg: /* /proc/N/notepg = --w------ */
-               pfs->pfs_mode = S_IWUSR;
-               vp->v_type = VREG;
-               break;
+       memset(&key, 0, sizeof(key));
+       key.pk_type = type;
+       key.pk_pid = pid;
+       key.pk_fd = fd;
 
-       case PFSmap:    /* /proc/N/map = -r--r--r-- */
-       case PFSmaps:   /* /proc/N/maps = -r--r--r-- */
-       case PFSstatus: /* /proc/N/status = -r--r--r-- */
-       case PFSstat:   /* /proc/N/stat = -r--r--r-- */
-       case PFScmdline:        /* /proc/N/cmdline = -r--r--r-- */
-       case PFSemul:   /* /proc/N/emul = -r--r--r-- */
-       case PFSmeminfo:        /* /proc/meminfo = -r--r--r-- */
-       case PFScpustat:        /* /proc/stat = -r--r--r-- */
-       case PFSdevices:        /* /proc/devices = -r--r--r-- */
-       case PFScpuinfo:        /* /proc/cpuinfo = -r--r--r-- */
-       case PFSuptime: /* /proc/uptime = -r--r--r-- */
-       case PFSmounts: /* /proc/mounts = -r--r--r-- */
-       case PFSloadavg:        /* /proc/loadavg = -r--r--r-- */
-       case PFSstatm:  /* /proc/N/statm = -r--r--r-- */
-       case PFSversion:        /* /proc/version = -r--r--r-- */
-               pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
-               vp->v_type = VREG;
-               break;
-
-#ifdef __HAVE_PROCFS_MACHDEP
-       PROCFS_MACHDEP_NODETYPE_CASES
-               procfs_machdep_allocvp(vp);
-               break;
-#endif
-
-       default:
-               panic("procfs_allocvp");
-       }
-
-       procfs_hashins(pfs);
-       uvm_vnp_setsize(vp, 0);
-       mutex_exit(&pfs_hashlock);
-
-       *vpp = vp;
-       return (0);
-
- bad:
-       mutex_exit(&pfs_hashlock);
-       free(pfs, M_TEMP);
-       vp->v_data = NULL;
-       ungetnewvnode(vp);
-       return (error);
-}
-
-int
-procfs_freevp(struct vnode *vp)
-{
-       struct pfsnode *pfs = VTOPFS(vp);
-
-       procfs_hashrem(pfs);
-
-       free(vp->v_data, M_TEMP);
-       vp->v_data = NULL;
-       return (0);



Home | Main Index | Thread Index | Old Index