xref: /original-bsd/sys/ufs/ufs/ufs_ihash.c (revision 95ecee29)
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.3 (Berkeley) 09/23/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 *ip;
47 
48 	for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
49 		if (ip == NULL)
50 			return (NULL);
51 		if (inum == ip->i_number && device == ip->i_dev)
52 			return (ITOV(ip));
53 	}
54 	/* NOTREACHED */
55 }
56 
57 /*
58  * Use the device/inum pair to find the incore inode, and return a pointer
59  * to it. If it is in core, but locked, wait for it.
60  */
61 struct vnode *
62 ufs_ihashget(device, inum)
63 	dev_t device;
64 	ino_t inum;
65 {
66 	register struct inode *ip;
67 	struct vnode *vp;
68 
69 	for (;;)
70 		for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
71 			if (ip == NULL)
72 				return (NULL);
73 			if (inum == ip->i_number && device == ip->i_dev) {
74 				if (ip->i_flag & IN_LOCKED) {
75 					ip->i_flag |= IN_WANTED;
76 					sleep(ip, PINOD);
77 					break;
78 				}
79 				vp = ITOV(ip);
80 				if (!vget(vp))
81 					return (vp);
82 				break;
83 			}
84 		}
85 	/* NOTREACHED */
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 & IN_LOCKED)
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 |= IN_LOCKED;
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