kernel - lwkt_token revamp
[dragonfly.git] / sys / vfs / hpfs / hpfs_hash.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ufs_ihash.c 8.7 (Berkeley) 5/17/95
34 * $FreeBSD: src/sys/fs/hpfs/hpfs_hash.c,v 1.1 1999/12/09 19:09:58 semenu Exp $
b13267a5 35 * $DragonFly: src/sys/vfs/hpfs/hpfs_hash.c,v 1.16 2006/09/10 01:26:40 dillon Exp $
984263bc
MD
36 */
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/kernel.h>
41#include <sys/lock.h>
42#include <sys/vnode.h>
43#include <sys/mount.h>
44#include <sys/malloc.h>
45#include <sys/proc.h>
46
1f2de5d4 47#include "hpfs.h"
984263bc
MD
48
49MALLOC_DEFINE(M_HPFSHASH, "HPFS hash", "HPFS node hash tables");
50
51/*
52 * Structures associated with hpfsnode cacheing.
53 */
54static LIST_HEAD(hphashhead, hpfsnode) *hpfs_hphashtbl;
55static u_long hpfs_hphash; /* size of hash table - 1 */
56#define HPNOHASH(dev, lsn) (&hpfs_hphashtbl[(minor(dev) + (lsn)) & hpfs_hphash])
57#ifndef NULL_SIMPLELOCKS
8a8d5d85 58static struct lwkt_token hpfs_hphash_token;
984263bc
MD
59#endif
60struct lock hpfs_hphash_lock;
61
62/*
63 * Initialize inode hash table.
64 */
65void
dd3af26c 66hpfs_hphashinit(void)
984263bc
MD
67{
68
f2770c70 69 lockinit (&hpfs_hphash_lock, "hpfs_hphashlock", 0, 0);
984263bc
MD
70 hpfs_hphashtbl = HASHINIT(desiredvnodes, M_HPFSHASH, M_WAITOK,
71 &hpfs_hphash);
3b998fa9 72 lwkt_token_init(&hpfs_hphash_token, 1);
984263bc
MD
73}
74
75/*
ae61ec9d
HP
76 * Free the inode hash.
77 */
78int
79hpfs_hphash_uninit(struct vfsconf *vfc)
80{
3b998fa9 81 lwkt_gettoken(&hpfs_hphash_token);
ae61ec9d 82 if (hpfs_hphashtbl)
efda3bd0 83 kfree(hpfs_hphashtbl, M_HPFSHASH);
3b998fa9 84 lwkt_reltoken(&hpfs_hphash_token);
ae61ec9d
HP
85
86 return 0;
87}
88
89/*
984263bc
MD
90 * Use the device/inum pair to find the incore inode, and return a pointer
91 * to it. If it is in core, return it, even if it is locked.
92 */
93struct hpfsnode *
b13267a5 94hpfs_hphashlookup(cdev_t dev, lsn_t ino)
984263bc
MD
95{
96 struct hpfsnode *hp;
97
3b998fa9 98 lwkt_gettoken(&hpfs_hphash_token);
41a01a4d 99 for (hp = HPNOHASH(dev, ino)->lh_first; hp; hp = hp->h_hash.le_next) {
984263bc
MD
100 if (ino == hp->h_no && dev == hp->h_dev)
101 break;
41a01a4d 102 }
3b998fa9 103 lwkt_reltoken(&hpfs_hphash_token);
984263bc
MD
104
105 return (hp);
106}
107
984263bc 108struct vnode *
b13267a5 109hpfs_hphashvget(cdev_t dev, lsn_t ino)
984263bc
MD
110{
111 struct hpfsnode *hp;
112 struct vnode *vp;
113
3b998fa9 114 lwkt_gettoken(&hpfs_hphash_token);
984263bc 115loop:
984263bc 116 for (hp = HPNOHASH(dev, ino)->lh_first; hp; hp = hp->h_hash.le_next) {
41a01a4d
MD
117 if (ino != hp->h_no || dev != hp->h_dev)
118 continue;
119 vp = HPTOV(hp);
41a01a4d 120
87de5057 121 if (vget(vp, LK_EXCLUSIVE))
5fd012e0 122 goto loop;
41a01a4d
MD
123 /*
124 * We must check to see if the inode has been ripped
125 * out from under us after blocking.
126 */
127 for (hp = HPNOHASH(dev, ino)->lh_first; hp; hp = hp->h_hash.le_next) {
128 if (ino == hp->h_no && dev == hp->h_dev)
129 break;
130 }
131 if (hp == NULL || vp != HPTOV(hp)) {
5fd012e0 132 vput(vp);
41a01a4d 133 goto loop;
984263bc 134 }
41a01a4d
MD
135
136 /*
137 * Or if the vget fails (due to a race)
138 */
3b998fa9 139 lwkt_reltoken(&hpfs_hphash_token);
41a01a4d 140 return (vp);
984263bc 141 }
3b998fa9 142 lwkt_reltoken(&hpfs_hphash_token);
984263bc
MD
143 return (NULLVP);
144}
145
146/*
147 * Insert the hpfsnode into the hash table.
148 */
149void
dd3af26c 150hpfs_hphashins(struct hpfsnode *hp)
984263bc
MD
151{
152 struct hphashhead *hpp;
153
3b998fa9 154 lwkt_gettoken(&hpfs_hphash_token);
984263bc
MD
155 hpp = HPNOHASH(hp->h_dev, hp->h_no);
156 hp->h_flag |= H_HASHED;
157 LIST_INSERT_HEAD(hpp, hp, h_hash);
3b998fa9 158 lwkt_reltoken(&hpfs_hphash_token);
984263bc
MD
159}
160
161/*
162 * Remove the inode from the hash table.
163 */
164void
dd3af26c 165hpfs_hphashrem(struct hpfsnode *hp)
984263bc 166{
3b998fa9 167 lwkt_gettoken(&hpfs_hphash_token);
984263bc
MD
168 if (hp->h_flag & H_HASHED) {
169 hp->h_flag &= ~H_HASHED;
170 LIST_REMOVE(hp, h_hash);
171#ifdef DIAGNOSTIC
172 hp->h_hash.le_next = NULL;
173 hp->h_hash.le_prev = NULL;
174#endif
175 }
3b998fa9 176 lwkt_reltoken(&hpfs_hphash_token);
984263bc 177}