xref: /original-bsd/sys/ufs/ufs/ufs_ihash.c (revision 3705696b)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ufs_ihash.c	8.1 (Berkeley) 06/11/93
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/vnode.h>
13 #include <sys/malloc.h>
14 #include <sys/proc.h>
15 
16 #include <ufs/ufs/quota.h>
17 #include <ufs/ufs/inode.h>
18 #include <ufs/ufs/ufs_extern.h>
19 
20 /*
21  * Structures associated with inode cacheing.
22  */
23 struct inode **ihashtbl;
24 u_long	ihash;		/* size of hash table - 1 */
25 #define	INOHASH(dev, ino)	(((dev) + (ino)) & ihash)
26 
27 /*
28  * Initialize inode hash table.
29  */
30 void
31 ufs_ihashinit()
32 {
33 
34 	ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash);
35 }
36 
37 /*
38  * Use the dev/ino pair to find the incore inode, and return a pointer to it.
39  * If it is in core, return it, even if it is locked.
40  */
41 struct vnode *
42 ufs_ihashlookup(dev, ino)
43 	dev_t dev;
44 	ino_t ino;
45 {
46 	register struct inode **ipp, *ip;
47 
48 	ipp = &ihashtbl[INOHASH(dev, ino)];
49 loop:
50 	for (ip = *ipp; ip; ip = ip->i_next) {
51 		if (ino != ip->i_number || dev != ip->i_dev)
52 			continue;
53 		return (ITOV(ip));
54 	}
55 	return (NULL);
56 }
57 
58 /*
59  * Use the dev/ino pair to find the incore inode, and return a pointer to it.
60  * If it is in core, but locked, wait for it.
61  */
62 struct vnode *
63 ufs_ihashget(dev, ino)
64 	dev_t dev;
65 	ino_t ino;
66 {
67 	register struct inode **ipp, *ip;
68 	struct vnode *vp;
69 
70 	ipp = &ihashtbl[INOHASH(dev, ino)];
71 loop:
72 	for (ip = *ipp; ip; ip = ip->i_next) {
73 		if (ino != ip->i_number || dev != ip->i_dev)
74 			continue;
75 		if ((ip->i_flag & ILOCKED) != 0) {
76 			ip->i_flag |= IWANT;
77 			sleep((caddr_t)ip, PINOD);
78 			goto loop;
79 		}
80 		vp = ITOV(ip);
81 		if (vget(vp))
82 			goto loop;
83 		return (vp);
84 	}
85 	return (NULL);
86 }
87 
88 /*
89  * Insert the inode into the hash table, and return it locked.
90  */
91 void
92 ufs_ihashins(ip)
93 	struct inode *ip;
94 {
95 	struct inode **ipp, *iq;
96 
97 	ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
98 	if (iq = *ipp)
99 		iq->i_prev = &ip->i_next;
100 	ip->i_next = iq;
101 	ip->i_prev = ipp;
102 	*ipp = ip;
103 	if ((ip->i_flag & ILOCKED) != 0)
104 		panic("ufs_ihashins: already locked");
105 	if (curproc)
106 		ip->i_lockholder = curproc->p_pid;
107 	else
108 		ip->i_lockholder = -1;
109 	ip->i_flag |= ILOCKED;
110 }
111 
112 /*
113  * Remove the inode from the hash table.
114  */
115 void
116 ufs_ihashrem(ip)
117 	register struct inode *ip;
118 {
119 	register struct inode *iq;
120 
121 	if (iq = ip->i_next)
122 		iq->i_prev = ip->i_prev;
123 	*ip->i_prev = iq;
124 #ifdef DIAGNOSTIC
125 	ip->i_next = NULL;
126 	ip->i_prev = NULL;
127 #endif
128 }
129