[BACK]Return to procfs_subr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / miscfs / procfs

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

Diff for /src/sys/miscfs/procfs/procfs_subr.c between version 1.28 and 1.28.2.1

version 1.28, 1999/09/02 23:33:45 version 1.28.2.1, 2000/11/20 18:09:49
Line 51 
Line 51 
   
 #include <miscfs/procfs/procfs.h>  #include <miscfs/procfs/procfs.h>
   
 static struct pfsnode *pfshead;  void procfs_hashins __P((struct pfsnode *));
 static int pfsvplock;  void procfs_hashrem __P((struct pfsnode *));
   struct vnode *procfs_hashget __P((pid_t, pfstype, struct mount *));
   
   LIST_HEAD(pfs_hashhead, pfsnode) *pfs_hashtbl;
   u_long  pfs_ihash;      /* size of hash table - 1 */
   #define PFSPIDHASH(pid) (&pfs_hashtbl[(pid) & pfs_ihash])
   
   struct lock pfs_hashlock;
   struct simplelock pfs_hash_slock;
   
 #define ISSET(t, f)     ((t) & (f))  #define ISSET(t, f)     ((t) & (f))
   
Line 91  procfs_allocvp(mp, vpp, pid, pfs_type)
Line 99  procfs_allocvp(mp, vpp, pid, pfs_type)
 {  {
         struct pfsnode *pfs;          struct pfsnode *pfs;
         struct vnode *vp;          struct vnode *vp;
         struct pfsnode **pp;  
         int error;          int error;
   
 loop:          do {
         for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {                  if ((*vpp = procfs_hashget(pid, pfs_type, mp)) != NULL)
                 vp = PFSTOV(pfs);  
                 if (pfs->pfs_pid == pid &&  
                     pfs->pfs_type == pfs_type &&  
                     vp->v_mount == mp) {  
                         if (vget(vp, LK_EXCLUSIVE))  
                                 goto loop;  
                         *vpp = vp;  
                         return (0);                          return (0);
                 }          } while (lockmgr(&pfs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
         }  
   
         /*          if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) != 0) {
          * otherwise lock the vp list while we call getnewvnode                  *vpp = NULL;
          * since that can block.                  lockmgr(&pfs_hashlock, LK_RELEASE, 0);
          */                  return (error);
         if (pfsvplock & PROCFS_LOCKED) {  
                 pfsvplock |= PROCFS_WANT;  
                 sleep((caddr_t) &pfsvplock, PINOD);  
                 goto loop;  
         }          }
         pfsvplock |= PROCFS_LOCKED;  
   
         if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) != 0)  
                 goto out;  
         vp = *vpp;          vp = *vpp;
   
         MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);          MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
         vp->v_data = pfs;          vp->v_data = pfs;
   
         pfs->pfs_next = 0;  
         pfs->pfs_pid = (pid_t) pid;          pfs->pfs_pid = (pid_t) pid;
         pfs->pfs_type = pfs_type;          pfs->pfs_type = pfs_type;
         pfs->pfs_vnode = vp;          pfs->pfs_vnode = vp;
Line 176  loop:
Line 166  loop:
                 panic("procfs_allocvp");                  panic("procfs_allocvp");
         }          }
   
         VOP_LOCK(vp, LK_EXCLUSIVE);          procfs_hashins(pfs);
           lockmgr(&pfs_hashlock, LK_RELEASE, 0);
         /* add to procfs vnode list */  
         for (pp = &pfshead; *pp; pp = &(*pp)->pfs_next)  
                 continue;  
         *pp = pfs;  
   
 out:  
         pfsvplock &= ~PROCFS_LOCKED;  
   
         if (pfsvplock & PROCFS_WANT) {  
                 pfsvplock &= ~PROCFS_WANT;  
                 wakeup((caddr_t) &pfsvplock);  
         }  
   
         return (error);          return (error);
 }  }
Line 198  int
Line 176  int
 procfs_freevp(vp)  procfs_freevp(vp)
         struct vnode *vp;          struct vnode *vp;
 {  {
         struct pfsnode **pfspp;  
         struct pfsnode *pfs = VTOPFS(vp);          struct pfsnode *pfs = VTOPFS(vp);
   
         for (pfspp = &pfshead; *pfspp != 0; pfspp = &(*pfspp)->pfs_next) {          procfs_hashrem(pfs);
                 if (*pfspp == pfs) {  
                         *pfspp = pfs->pfs_next;  
                         break;  
                 }  
         }  
   
         FREE(vp->v_data, M_TEMP);          FREE(vp->v_data, M_TEMP);
         vp->v_data = 0;          vp->v_data = 0;
Line 336  vfs_findname(nm, buf, buflen)
Line 308  vfs_findname(nm, buf, buflen)
   
         return (0);          return (0);
 }  }
   
   /*
    * Initialize pfsnode hash table.
    */
   void
   procfs_hashinit()
   {
           lockinit(&pfs_hashlock, PINOD, "pfs_hashlock", 0, 0);
           pfs_hashtbl = hashinit(desiredvnodes / 4, M_UFSMNT, M_WAITOK,
               &pfs_ihash);
           simple_lock_init(&pfs_hash_slock);
   }
   
   /*
    * Free pfsnode hash table.
    */
   void
   procfs_hashdone()
   {
           hashdone(pfs_hashtbl, M_UFSMNT);
   }
   
   struct vnode *
   procfs_hashget(pid, type, mp)
           pid_t pid;
           pfstype type;
           struct mount *mp;
   {
           struct pfsnode *pp;
           struct vnode *vp;
   
   loop:
           simple_lock(&pfs_hash_slock);
           for (pp = PFSPIDHASH(pid)->lh_first; pp; pp = pp->pfs_hash.le_next) {
                   vp = PFSTOV(pp);
                   if (pid == pp->pfs_pid && pp->pfs_type == type &&
                       vp->v_mount == mp) {
                           simple_lock(&vp->v_interlock);
                           simple_unlock(&pfs_hash_slock);
                           if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
                                   goto loop;
                           return (vp);
                   }
           }
           simple_unlock(&pfs_hash_slock);
           return (NULL);
   }
   
   /*
    * Insert the pfsnode into the hash table and lock it.
    */
   void
   procfs_hashins(pp)
           struct pfsnode *pp;
   {
           struct pfs_hashhead *ppp;
   
           /* lock the pfsnode, then put it on the appropriate hash list */
           lockmgr(&pp->pfs_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
   
           simple_lock(&pfs_hash_slock);
           ppp = PFSPIDHASH(pp->pfs_pid);
           LIST_INSERT_HEAD(ppp, pp, pfs_hash);
           simple_unlock(&pfs_hash_slock);
   }
   
   /*
    * Remove the pfsnode from the hash table.
    */
   void
   procfs_hashrem(pp)
           struct pfsnode *pp;
   {
           simple_lock(&pfs_hash_slock);
           LIST_REMOVE(pp, pfs_hash);
           simple_unlock(&pfs_hash_slock);
   }
   
   void
   procfs_revoke_vnodes(p, arg)
           struct proc *p;
           void *arg;
   {
           struct pfsnode *pfs, *pnext;
           struct vnode *vp;
           struct mount *mp = (struct mount *)arg;
   
           if (!(p->p_flag & P_SUGID))
                   return;
   
           for (pfs = PFSPIDHASH(p->p_pid)->lh_first; pfs; pfs = pnext) {
                   vp = PFSTOV(pfs);
                   pnext = pfs->pfs_hash.le_next;
                   if (vp->v_usecount > 0 && pfs->pfs_pid == p->p_pid &&
                       vp->v_mount == mp)
                           VOP_REVOKE(vp, REVOKEALL);
           }
   }

Legend:
Removed from v.1.28  
changed lines
  Added in v.1.28.2.1

CVSweb <webmaster@jp.NetBSD.org>