xref: /original-bsd/sys/ufs/ufs/ufs_ihash.c (revision 27393bdf)
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.5 (Berkeley) 03/20/95
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 LIST_HEAD(ihashhead, inode) *ihashtbl;
24 u_long	ihash;		/* size of hash table - 1 */
25 #define	INOHASH(device, inum)	(&ihashtbl[((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(dev, inum)
43 	dev_t dev;
44 	ino_t inum;
45 {
46 	register struct inode *ip;
47 
48 	for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
49 		if (inum == ip->i_number && dev == ip->i_dev)
50 			return (ITOV(ip));
51 	}
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(dev, inum)
61 	dev_t dev;
62 	ino_t inum;
63 {
64 	register struct inode *ip;
65 	struct vnode *vp;
66 
67 loop:
68 	for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
69 		if (inum == ip->i_number && dev == ip->i_dev) {
70 			if (ip->i_flag & IN_LOCKED) {
71 				ip->i_flag |= IN_WANTED;
72 				sleep(ip, PINOD);
73 				goto loop;
74 			}
75 			vp = ITOV(ip);
76 			if (vget(vp, 1))
77 				goto loop;
78 			return (vp);
79 		}
80 	}
81 	return (NULL);
82 }
83 
84 /*
85 * Insert the inode into the hash table, and return it locked.
86  */
87 void
88 ufs_ihashins(ip)
89 	struct inode *ip;
90 {
91 	struct ihashhead *ipp;
92 
93 	ipp = INOHASH(ip->i_dev, ip->i_number);
94 	LIST_INSERT_HEAD(ipp, ip, i_hash);
95 	if (ip->i_flag & IN_LOCKED)
96 		panic("ufs_ihashins: already locked");
97 	if (curproc)
98 		ip->i_lockholder = curproc->p_pid;
99 	else
100 		ip->i_lockholder = -1;
101 	ip->i_flag |= IN_LOCKED;
102 }
103 
104 /*
105  * Remove the inode from the hash table.
106  */
107 void
108 ufs_ihashrem(ip)
109 	register struct inode *ip;
110 {
111 	register struct inode *iq;
112 
113 	LIST_REMOVE(ip, i_hash);
114 #ifdef DIAGNOSTIC
115 	ip->i_hash.le_next = NULL;
116 	ip->i_hash.le_prev = NULL;
117 #endif
118 }
119