xref: /original-bsd/sys/ufs/ffs/ufs_ihash.c (revision c98fd05d)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ufs_ihash.c	7.5 (Berkeley) 07/20/92
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/vnode.h>
13 #include <sys/malloc.h>
14 
15 #include <ufs/ufs/quota.h>
16 #include <ufs/ufs/inode.h>
17 #include <ufs/ufs/ufs_extern.h>
18 
19 /*
20  * Structures associated with inode cacheing.
21  */
22 struct inode **ihashtbl;
23 u_long	ihash;		/* size of hash table - 1 */
24 #define	INOHASH(dev, ino)	(((dev) + (ino)) & ihash)
25 
26 /*
27  * Initialize inode hash table.
28  */
29 void
30 ufs_ihashinit()
31 {
32 
33 	ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash);
34 }
35 
36 /*
37  * Use the dev/ino pair to find the incore inode, and return a pointer to it.
38  * If it is in core, but locked, wait for it.
39  */
40 struct vnode *
41 ufs_ihashget(dev, ino)
42 	dev_t dev;
43 	ino_t ino;
44 {
45 	register struct inode **ipp, *ip;
46 	struct vnode *vp;
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 		if ((ip->i_flag & ILOCKED) != 0) {
54 			ip->i_flag |= IWANT;
55 			sleep((caddr_t)ip, PINOD);
56 			goto loop;
57 		}
58 		vp = ITOV(ip);
59 		if (vget(vp))
60 			goto loop;
61 		return (vp);
62 	}
63 	return (NULL);
64 }
65 
66 /*
67  * Insert the inode into the hash table, and return it locked.
68  */
69 void
70 ufs_ihashins(ip)
71 	struct inode *ip;
72 {
73 	struct inode **ipp, *iq;
74 
75 	ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
76 	if (iq = *ipp)
77 		iq->i_prev = &ip->i_next;
78 	ip->i_next = iq;
79 	ip->i_prev = ipp;
80 	*ipp = ip;
81 	ILOCK(ip);
82 }
83 
84 /*
85  * Remove the inode from the hash table.
86  */
87 void
88 ufs_ihashrem(ip)
89 	register struct inode *ip;
90 {
91 	register struct inode *iq;
92 
93 	if (iq = ip->i_next)
94 		iq->i_prev = ip->i_prev;
95 	*ip->i_prev = iq;
96 #ifdef DIAGNOSTIC
97 	ip->i_next = NULL;
98 	ip->i_prev = NULL;
99 #endif
100 }
101