Annotation of sys/ufs/ufs/ufs_ihash.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ufs_ihash.c,v 1.13 2007/03/21 17:29:32 thib Exp $ */
2: /* $NetBSD: ufs_ihash.c,v 1.3 1996/02/09 22:36:04 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1982, 1986, 1989, 1991, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the University nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: * @(#)ufs_ihash.c 8.4 (Berkeley) 12/30/93
33: */
34:
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/vnode.h>
38: #include <sys/malloc.h>
39: #include <sys/proc.h>
40:
41: #include <ufs/ufs/quota.h>
42: #include <ufs/ufs/inode.h>
43: #include <ufs/ufs/ufs_extern.h>
44:
45: /*
46: * Structures associated with inode cacheing.
47: */
48: LIST_HEAD(ihashhead, inode) *ihashtbl;
49: u_long ihash; /* size of hash table - 1 */
50: #define INOHASH(device, inum) (&ihashtbl[((device) + (inum)) & ihash])
51: struct simplelock ufs_ihash_slock;
52:
53: /*
54: * Initialize inode hash table.
55: */
56: void
57: ufs_ihashinit(void)
58: {
59: ihashtbl = hashinit(desiredvnodes, M_UFSMNT, M_WAITOK, &ihash);
60: simple_lock_init(&ufs_ihash_slock);
61: }
62:
63: /*
64: * Use the device/inum pair to find the incore inode, and return a pointer
65: * to it. If it is in core, return it, even if it is locked.
66: */
67: struct vnode *
68: ufs_ihashlookup(dev_t dev, ino_t inum)
69: {
70: struct inode *ip;
71:
72: simple_lock(&ufs_ihash_slock);
73: LIST_FOREACH(ip, INOHASH(dev, inum), i_hash)
74: if (inum == ip->i_number && dev == ip->i_dev)
75: break;
76: simple_unlock(&ufs_ihash_slock);
77:
78: if (ip)
79: return (ITOV(ip));
80:
81: return (NULLVP);
82: }
83:
84: /*
85: * Use the device/inum pair to find the incore inode, and return a pointer
86: * to it. If it is in core, but locked, wait for it.
87: */
88: struct vnode *
89: ufs_ihashget(dev_t dev, ino_t inum)
90: {
91: struct proc *p = curproc;
92: struct inode *ip;
93: struct vnode *vp;
94: loop:
95: simple_lock(&ufs_ihash_slock);
96: LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) {
97: if (inum == ip->i_number && dev == ip->i_dev) {
98: vp = ITOV(ip);
99: simple_unlock(&ufs_ihash_slock);
100: if (vget(vp, LK_EXCLUSIVE, p))
101: goto loop;
102: return (vp);
103: }
104: }
105: simple_unlock(&ufs_ihash_slock);
106: return (NULL);
107: }
108:
109: /*
110: * Insert the inode into the hash table, and return it locked.
111: */
112: int
113: ufs_ihashins(struct inode *ip)
114: {
115: struct inode *curip;
116: struct ihashhead *ipp;
117: dev_t dev = ip->i_dev;
118: ino_t inum = ip->i_number;
119:
120: /* lock the inode, then put it on the appropriate hash list */
121: lockmgr(&ip->i_lock, LK_EXCLUSIVE, NULL);
122:
123: simple_lock(&ufs_ihash_slock);
124:
125: LIST_FOREACH(curip, INOHASH(dev, inum), i_hash) {
126: if (inum == curip->i_number && dev == curip->i_dev) {
127: simple_unlock(&ufs_ihash_slock);
128: lockmgr(&ip->i_lock, LK_RELEASE, NULL);
129: return (EEXIST);
130: }
131: }
132:
133: ipp = INOHASH(dev, inum);
134: LIST_INSERT_HEAD(ipp, ip, i_hash);
135: simple_unlock(&ufs_ihash_slock);
136:
137: return (0);
138: }
139:
140: /*
141: * Remove the inode from the hash table.
142: */
143: void
144: ufs_ihashrem(struct inode *ip)
145: {
146: simple_lock(&ufs_ihash_slock);
147:
148: if (ip->i_hash.le_prev == NULL)
149: return;
150:
151: LIST_REMOVE(ip, i_hash);
152: #ifdef DIAGNOSTIC
153: ip->i_hash.le_next = NULL;
154: ip->i_hash.le_prev = NULL;
155: #endif
156: simple_unlock(&ufs_ihash_slock);
157:
158: }
CVSweb