xref: /original-bsd/sys/ufs/ufs/ufs_ihash.c (revision 514cbc2d)
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.2 (Berkeley) 09/05/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(device, inum)	(((device) + (inum)) & 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 device/inum pair to find the incore inode, and return a pointer
39  * to it. If it is in core, return it, even if it is locked.
40  */
41 struct vnode *
42 ufs_ihashlookup(device, inum)
43 	dev_t device;
44 	ino_t inum;
45 {
46 	register struct inode **ipp, *ip;
47 
48 	ipp = &ihashtbl[INOHASH(device, inum)];
49 	for (ip = *ipp; ip; ip = ip->i_next)
50 		if (inum == ip->i_number && device == ip->i_dev)
51 			return (ITOV(ip));
52 	return (NULL);
53 }
54 
55 /*
56  * Use the device/inum pair to find the incore inode, and return a pointer
57  * to it. If it is in core, but locked, wait for it.
58  */
59 struct vnode *
60 ufs_ihashget(device, inum)
61 	dev_t device;
62 	ino_t inum;
63 {
64 	register struct inode **ipp, *ip;
65 	struct vnode *vp;
66 
67 	ipp = &ihashtbl[INOHASH(device, inum)];
68 retry:	for (ip = *ipp; ip != NULL; ip = ip->i_next)
69 		if (inum == ip->i_number && device == ip->i_dev) {
70 			if (ip->i_flag & ILOCKED) {
71 				ip->i_flag |= IWANT;
72 				sleep(ip, PINOD);
73 				goto retry;
74 			}
75 			vp = ITOV(ip);
76 			if (vget(vp))
77 				goto retry;
78 			return (vp);
79 		}
80 	return (NULL);
81 }
82 
83 /*
84  * Insert the inode into the hash table, and return it locked.
85  */
86 void
87 ufs_ihashins(ip)
88 	struct inode *ip;
89 {
90 	struct inode **ipp, *iq;
91 
92 	ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
93 	if (iq = *ipp)
94 		iq->i_prev = &ip->i_next;
95 	ip->i_next = iq;
96 	ip->i_prev = ipp;
97 	*ipp = ip;
98 	if ((ip->i_flag & ILOCKED) != 0)
99 		panic("ufs_ihashins: already locked");
100 	if (curproc)
101 		ip->i_lockholder = curproc->p_pid;
102 	else
103 		ip->i_lockholder = -1;
104 	ip->i_flag |= ILOCKED;
105 }
106 
107 /*
108  * Remove the inode from the hash table.
109  */
110 void
111 ufs_ihashrem(ip)
112 	register struct inode *ip;
113 {
114 	register struct inode *iq;
115 
116 	if (iq = ip->i_next)
117 		iq->i_prev = ip->i_prev;
118 	*ip->i_prev = iq;
119 #ifdef DIAGNOSTIC
120 	ip->i_next = NULL;
121 	ip->i_prev = NULL;
122 #endif
123 }
124