xref: /original-bsd/sys/ufs/ffs/ufs_ihash.c (revision 13ec26c3)
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.4 (Berkeley) 03/11/92
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/namei.h>
13 #include <sys/vnode.h>
14 #include <sys/malloc.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 union ihash {
24 	union	ihash *ih_head[2];
25 	struct	inode *ih_chain[2];
26 } *ihashtbl;
27 #define	ih_forw	ih_chain[0]
28 #define	ih_back	ih_chain[1]
29 
30 u_long	ihash;			/* size of hash table - 1 */
31 #define	INOHASH(dev, ino)	(((dev) + (ino)) & ihash)
32 
33 /*
34  * Initialize inode hash table.
35  */
36 void
37 ufs_ihashinit()
38 {
39 	register union ihash *ihp;
40 	long ihashsize;
41 
42 	ihashsize = roundup((desiredvnodes + 1) * sizeof *ihp / 2,
43 		NBPG * CLSIZE);
44 	ihashtbl = (union ihash *)malloc((u_long)ihashsize,
45 	    M_UFSMNT, M_WAITOK);
46 	for (ihash = 1; ihash <= ihashsize / sizeof *ihp; ihash <<= 1)
47 		continue;
48 	ihash = (ihash >> 1) - 1;
49 	for (ihp = &ihashtbl[ihash]; ihp >= ihashtbl; ihp--) {
50 		ihp->ih_head[0] = ihp;
51 		ihp->ih_head[1] = ihp;
52 	}
53 }
54 
55 /*
56  * Use the dev/ino pair to find the incore inode, and return a pointer to it.
57  * If it is in core, but locked, wait for it.
58  */
59 struct vnode *
60 ufs_ihashget(dev, ino)
61 	/* dev_t */ int dev;
62 	ino_t ino;
63 {
64 	register union ihash *ihp;
65 	register struct inode *ip;
66 	struct vnode *vp;
67 
68 	ihp = &ihashtbl[INOHASH(dev, ino)];
69 loop:
70 	for (ip = ihp->ih_forw; ip != (struct inode *)ihp; ip = ip->i_forw) {
71 		if (ino != ip->i_number || dev != ip->i_dev)
72 			continue;
73 		if ((ip->i_flag & ILOCKED) != 0) {
74 			ip->i_flag |= IWANT;
75 			sleep((caddr_t)ip, PINOD);
76 			goto loop;
77 		}
78 		vp = ITOV(ip);
79 		if (vget(vp))
80 			goto loop;
81 		return (vp);
82 	}
83 	return (NULL);
84 }
85 
86 /*
87  * Insert the inode into the hash table, and return it locked.
88  */
89 void
90 ufs_ihashins(ip)
91 	struct inode *ip;
92 {
93 	insque(ip, &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]);
94 	ILOCK(ip);
95 }
96