1 /* $NetBSD: chfs_ihash.c,v 1.2 2012/10/19 12:44:39 ttoth Exp $ */
4 * Copyright (c) 2010 Department of Software Engineering,
5 * University of Szeged, Hungary
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by the Department of Software Engineering, University of Szeged, Hungary
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * 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
35 * Structures associated with inode cacheing.
37 static LIST_HEAD(ihashhead
, chfs_inode
) *chfs_ihashtbl
;
38 static u_long chfs_ihash
; /* size of hash table - 1 */
39 #define INOHASH(device, inum) (((device) + (inum)) & chfs_ihash)
41 kmutex_t chfs_ihash_lock
;
42 kmutex_t chfs_hashlock
;
45 * Initialize inode hash table.
52 mutex_init(&chfs_hashlock
, MUTEX_DEFAULT
, IPL_NONE
);
53 mutex_init(&chfs_ihash_lock
, MUTEX_DEFAULT
, IPL_NONE
);
54 chfs_ihashtbl
= hashinit(desiredvnodes
,
55 HASH_LIST
, true, &chfs_ihash
);
59 * Reinitialize inode hash table.
63 chfs_ihashreinit(void)
65 struct chfs_inode
*ip
;
66 struct ihashhead
*oldhash
, *hash
;
67 u_long oldmask
, mask
, val
;
72 hash
= hashinit(desiredvnodes
, HASH_LIST
, true, &mask
);
73 mutex_enter(&chfs_ihash_lock
);
74 oldhash
= chfs_ihashtbl
;
78 for (i
= 0; i
<= oldmask
; i
++) {
79 while ((ip
= LIST_FIRST(&oldhash
[i
])) != NULL
) {
80 LIST_REMOVE(ip
, hash_entry
);
81 val
= INOHASH(ip
->dev
, ip
->ino
);
82 LIST_INSERT_HEAD(&hash
[val
], ip
, hash_entry
);
85 mutex_exit(&chfs_ihash_lock
);
86 hashdone(oldhash
, HASH_LIST
, oldmask
);
90 * Free inode hash table.
97 hashdone(chfs_ihashtbl
, HASH_LIST
, chfs_ihash
);
98 mutex_destroy(&chfs_hashlock
);
99 mutex_destroy(&chfs_ihash_lock
);
103 * Use the device/inum pair to find the incore inode, and return a pointer
104 * to it. If it is in core, return it, even if it is locked.
107 chfs_ihashlookup(dev_t dev
, ino_t inum
)
109 struct chfs_inode
*ip
;
110 struct ihashhead
*ipp
;
112 dbg("dev: %ju, inum: %ju\n", (uintmax_t )dev
, (uintmax_t )inum
);
114 KASSERT(mutex_owned(&chfs_ihash_lock
));
116 ipp
= &chfs_ihashtbl
[INOHASH(dev
, inum
)];
117 LIST_FOREACH(ip
, ipp
, hash_entry
) {
118 if (inum
== ip
->ino
&& dev
== ip
->dev
) {
131 * Use the device/inum pair to find the incore inode, and return a pointer
132 * to it. If it is in core, but locked, wait for it.
135 chfs_ihashget(dev_t dev
, ino_t inum
, int flags
)
137 struct ihashhead
*ipp
;
138 struct chfs_inode
*ip
;
141 dbg("search for ino\n");
144 mutex_enter(&chfs_ihash_lock
);
145 ipp
= &chfs_ihashtbl
[INOHASH(dev
, inum
)];
146 dbg("ipp: %p, chfs_ihashtbl: %p, ihash: %lu\n",
147 ipp
, chfs_ihashtbl
, chfs_ihash
);
148 LIST_FOREACH(ip
, ipp
, hash_entry
) {
150 if (inum
== ip
->ino
&& dev
== ip
->dev
) {
153 if (VOP_ISLOCKED(vp
) == LK_EXCLUSIVE
) {
154 mutex_exit(&chfs_ihash_lock
);
158 if (VOP_ISLOCKED(vp))
161 dbg("isn't locked\n");
164 mutex_exit(&chfs_ihash_lock
);
166 mutex_enter(vp
->v_interlock
);
167 mutex_exit(&chfs_ihash_lock
);
168 if (vget(vp
, flags
)) {
175 mutex_exit(&chfs_ihash_lock
);
180 * Insert the inode into the hash table, and return it locked.
183 chfs_ihashins(struct chfs_inode
*ip
)
185 struct ihashhead
*ipp
;
189 KASSERT(mutex_owned(&chfs_hashlock
));
191 /* lock the inode, then put it on the appropriate hash list */
192 VOP_LOCK(ITOV(ip
), LK_EXCLUSIVE
);
194 mutex_enter(&chfs_ihash_lock
);
195 ipp
= &chfs_ihashtbl
[INOHASH(ip
->dev
, ip
->ino
)];
196 LIST_INSERT_HEAD(ipp
, ip
, hash_entry
);
197 mutex_exit(&chfs_ihash_lock
);
201 * Remove the inode from the hash table.
204 chfs_ihashrem(struct chfs_inode
*ip
)
208 mutex_enter(&chfs_ihash_lock
);
209 LIST_REMOVE(ip
, hash_entry
);
210 mutex_exit(&chfs_ihash_lock
);