xref: /original-bsd/sys/ufs/ffs/ufs_ihash.c (revision 7513c514)
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.2 (Berkeley) 11/05/91
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/namei.h>
13 #include <sys/vnode.h>
14 
15 #include <ufs/ufs/quota.h>
16 #include <ufs/ufs/inode.h>
17 #include <ufs/ufs/ufs_extern.h>
18 
19 #define	INOHSZ	512
20 #if	((INOHSZ & (INOHSZ - 1)) == 0)
21 #define	INOHASH(dev, ino)	(((dev) + (ino)) & (INOHSZ - 1))
22 #else
23 #define	INOHASH(dev, ino)	(((unsigned int)((dev) + (ino))) % INOHSZ)
24 #endif
25 
26 static union ihead {
27 	union  ihead *ih_head[2];
28 	struct inode *ih_chain[2];
29 } ihead[INOHSZ];
30 
31 
32 /*
33  * Initialize inode hash table.
34  */
35 void
36 ufs_ihashinit()
37 {
38 	register union ihead *ih;
39 	register int i;
40 
41 	for (ih = ihead, i = INOHSZ; --i >= 0; ++ih)
42 		ih->ih_head[0] = ih->ih_head[1] = ih;
43 }
44 
45 /*
46  * Use the dev/ino pair to find the incore inode, and return a pointer to it.
47  * If it is in core, but locked, wait for it.
48  */
49 struct vnode *
50 ufs_ihashget(dev, ino)
51 	/* dev_t */ int dev;
52 	ino_t ino;
53 {
54 	register union ihead *ih;
55 	register struct inode *ip;
56 	struct vnode *vp;
57 
58 	ih = &ihead[INOHASH(dev, ino)];
59 loop:
60 	for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw) {
61 		if (ino != ip->i_number || dev != ip->i_dev)
62 			continue;
63 		if ((ip->i_flag & ILOCKED) != 0) {
64 			ip->i_flag |= IWANT;
65 			sleep((caddr_t)ip, PINOD);
66 			goto loop;
67 		}
68 		vp = ITOV(ip);
69 		if (vget(vp))
70 			goto loop;
71 		return (vp);
72 	}
73 	return (NULL);
74 }
75 
76 /*
77  * Insert the inode into the hash table, and return it locked.
78  */
79 void
80 ufs_ihashins(ip)
81 	struct inode *ip;
82 {
83 	insque(ip, &ihead[INOHASH(ip->i_dev, ip->i_number)]);
84 	ILOCK(ip);
85 }
86