xref: /original-bsd/sys/ufs/ufs/ufs_ihash.c (revision 0ac4996f)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ufs_ihash.c	8.6 (Berkeley) 05/14/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 struct simplelock ufs_ihash_slock;
27 
28 /*
29  * Initialize inode hash table.
30  */
31 void
32 ufs_ihashinit()
33 {
34 
35 	ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash);
36 	simple_lock_init(&ufs_ihash_slock);
37 }
38 
39 /*
40  * Use the device/inum pair to find the incore inode, and return a pointer
41  * to it. If it is in core, return it, even if it is locked.
42  */
43 struct vnode *
44 ufs_ihashlookup(dev, inum)
45 	dev_t dev;
46 	ino_t inum;
47 {
48 	struct inode *ip;
49 
50 	simple_lock(&ufs_ihash_slock);
51 	for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next)
52 		if (inum == ip->i_number && dev == ip->i_dev)
53 			break;
54 	simple_unlock(&ufs_ihash_slock);
55 
56 	if (ip)
57 		return (ITOV(ip));
58 	return (NULLVP);
59 }
60 
61 /*
62  * Use the device/inum pair to find the incore inode, and return a pointer
63  * to it. If it is in core, but locked, wait for it.
64  */
65 struct vnode *
66 ufs_ihashget(dev, inum)
67 	dev_t dev;
68 	ino_t inum;
69 {
70 	struct proc *p = curproc;	/* XXX */
71 	struct inode *ip;
72 	struct vnode *vp;
73 
74 loop:
75 	simple_lock(&ufs_ihash_slock);
76 	for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
77 		if (inum == ip->i_number && dev == ip->i_dev) {
78 			vp = ITOV(ip);
79 			simple_lock(&vp->v_interlock);
80 			simple_unlock(&ufs_ihash_slock);
81 			if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
82 				goto loop;
83 			return (vp);
84 		}
85 	}
86 	simple_unlock(&ufs_ihash_slock);
87 	return (NULL);
88 }
89 
90 /*
91 * Insert the inode into the hash table, and return it locked.
92  */
93 void
94 ufs_ihashins(ip)
95 	struct inode *ip;
96 {
97 	struct proc *p = curproc;		/* XXX */
98 	struct ihashhead *ipp;
99 
100 	simple_lock(&ufs_ihash_slock);
101 	ipp = INOHASH(ip->i_dev, ip->i_number);
102 	LIST_INSERT_HEAD(ipp, ip, i_hash);
103 	simple_unlock(&ufs_ihash_slock);
104 
105 	lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
106 }
107 
108 /*
109  * Remove the inode from the hash table.
110  */
111 void
112 ufs_ihashrem(ip)
113 	struct inode *ip;
114 {
115 	struct inode *iq;
116 
117 	simple_lock(&ufs_ihash_slock);
118 	LIST_REMOVE(ip, i_hash);
119 #ifdef DIAGNOSTIC
120 	ip->i_hash.le_next = NULL;
121 	ip->i_hash.le_prev = NULL;
122 #endif
123 	simple_unlock(&ufs_ihash_slock);
124 }
125