xref: /dflybsd-src/sys/vfs/ext2fs/ext2_ihash.c (revision cfe603905713d4e92a7956678970d5dff8e913f2)
1*cfe60390STomohiro Kusumi /*
2*cfe60390STomohiro Kusumi  * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
3*cfe60390STomohiro Kusumi  *	The Regents of the University of California.  All rights reserved.
4*cfe60390STomohiro Kusumi  *
5*cfe60390STomohiro Kusumi  * Redistribution and use in source and binary forms, with or without
6*cfe60390STomohiro Kusumi  * modification, are permitted provided that the following conditions
7*cfe60390STomohiro Kusumi  * are met:
8*cfe60390STomohiro Kusumi  * 1. Redistributions of source code must retain the above copyright
9*cfe60390STomohiro Kusumi  *    notice, this list of conditions and the following disclaimer.
10*cfe60390STomohiro Kusumi  * 2. Redistributions in binary form must reproduce the above copyright
11*cfe60390STomohiro Kusumi  *    notice, this list of conditions and the following disclaimer in the
12*cfe60390STomohiro Kusumi  *    documentation and/or other materials provided with the distribution.
13*cfe60390STomohiro Kusumi  * 3. Neither the name of the University nor the names of its contributors
14*cfe60390STomohiro Kusumi  *    may be used to endorse or promote products derived from this software
15*cfe60390STomohiro Kusumi  *    without specific prior written permission.
16*cfe60390STomohiro Kusumi  *
17*cfe60390STomohiro Kusumi  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18*cfe60390STomohiro Kusumi  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*cfe60390STomohiro Kusumi  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*cfe60390STomohiro Kusumi  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21*cfe60390STomohiro Kusumi  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*cfe60390STomohiro Kusumi  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*cfe60390STomohiro Kusumi  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*cfe60390STomohiro Kusumi  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*cfe60390STomohiro Kusumi  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*cfe60390STomohiro Kusumi  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*cfe60390STomohiro Kusumi  * SUCH DAMAGE.
28*cfe60390STomohiro Kusumi  *
29*cfe60390STomohiro Kusumi  * @(#)ufs_ihash.c	8.7 (Berkeley) 5/17/95
30*cfe60390STomohiro Kusumi  * $FreeBSD: src/sys/ufs/ufs/ufs_ihash.c,v 1.20 1999/08/28 00:52:29 peter Exp $
31*cfe60390STomohiro Kusumi  */
32*cfe60390STomohiro Kusumi 
33*cfe60390STomohiro Kusumi #include <sys/param.h>
34*cfe60390STomohiro Kusumi #include <sys/systm.h>
35*cfe60390STomohiro Kusumi #include <sys/kernel.h>
36*cfe60390STomohiro Kusumi #include <sys/lock.h>
37*cfe60390STomohiro Kusumi #include <sys/vnode.h>
38*cfe60390STomohiro Kusumi #include <sys/malloc.h>
39*cfe60390STomohiro Kusumi #include <sys/proc.h>
40*cfe60390STomohiro Kusumi 
41*cfe60390STomohiro Kusumi #include <vfs/ext2fs/fs.h>
42*cfe60390STomohiro Kusumi #include <vfs/ext2fs/ext2fs.h>
43*cfe60390STomohiro Kusumi #include <vfs/ext2fs/inode.h>
44*cfe60390STomohiro Kusumi #include <vfs/ext2fs/ext2_dinode.h>
45*cfe60390STomohiro Kusumi #include <vfs/ext2fs/ext2_extern.h>
46*cfe60390STomohiro Kusumi 
47*cfe60390STomohiro Kusumi static MALLOC_DEFINE(M_EXT2IHASH, "EXT2 ihash", "EXT2 Inode hash tables");
48*cfe60390STomohiro Kusumi /*
49*cfe60390STomohiro Kusumi  * Structures associated with inode cacheing.
50*cfe60390STomohiro Kusumi  */
51*cfe60390STomohiro Kusumi static struct inode **ext2_ihashtbl;
52*cfe60390STomohiro Kusumi static u_long	ext2_ihash;		/* size of hash table - 1 */
53*cfe60390STomohiro Kusumi static struct lwkt_token ext2_ihash_token;
54*cfe60390STomohiro Kusumi 
55*cfe60390STomohiro Kusumi #define	INOHASH(device, inum)	(&ext2_ihashtbl[(minor(device) + (inum)) & ext2_ihash])
56*cfe60390STomohiro Kusumi 
57*cfe60390STomohiro Kusumi /*
58*cfe60390STomohiro Kusumi  * Initialize inode hash table.
59*cfe60390STomohiro Kusumi  */
60*cfe60390STomohiro Kusumi void
ext2_ihashinit(void)61*cfe60390STomohiro Kusumi ext2_ihashinit(void)
62*cfe60390STomohiro Kusumi {
63*cfe60390STomohiro Kusumi 	ext2_ihash = vfs_inodehashsize();
64*cfe60390STomohiro Kusumi 	ext2_ihashtbl = malloc(sizeof(void *) * ext2_ihash, M_EXT2IHASH,
65*cfe60390STomohiro Kusumi 	    M_WAITOK | M_ZERO);
66*cfe60390STomohiro Kusumi 	--ext2_ihash;
67*cfe60390STomohiro Kusumi 	lwkt_token_init(&ext2_ihash_token, "ext2ihash");
68*cfe60390STomohiro Kusumi }
69*cfe60390STomohiro Kusumi 
70*cfe60390STomohiro Kusumi void
ext2_ihashuninit(void)71*cfe60390STomohiro Kusumi ext2_ihashuninit(void)
72*cfe60390STomohiro Kusumi {
73*cfe60390STomohiro Kusumi 	lwkt_gettoken(&ext2_ihash_token);
74*cfe60390STomohiro Kusumi 	if (ext2_ihashtbl)
75*cfe60390STomohiro Kusumi 		free(ext2_ihashtbl, M_EXT2IHASH);
76*cfe60390STomohiro Kusumi 	lwkt_reltoken(&ext2_ihash_token);
77*cfe60390STomohiro Kusumi }
78*cfe60390STomohiro Kusumi 
79*cfe60390STomohiro Kusumi /*
80*cfe60390STomohiro Kusumi  * Use the device/inum pair to find the incore inode, and return a pointer
81*cfe60390STomohiro Kusumi  * to it. If it is in core, but locked, wait for it.
82*cfe60390STomohiro Kusumi  *
83*cfe60390STomohiro Kusumi  * Note that the serializing tokens do not prevent other processes from
84*cfe60390STomohiro Kusumi  * playing with the data structure being protected while we are blocked.
85*cfe60390STomohiro Kusumi  * They do protect us from preemptive interrupts which might try to
86*cfe60390STomohiro Kusumi  * play with the protected data structure.
87*cfe60390STomohiro Kusumi  */
88*cfe60390STomohiro Kusumi struct vnode *
ext2_ihashget(cdev_t dev,ino_t inum)89*cfe60390STomohiro Kusumi ext2_ihashget(cdev_t dev, ino_t inum)
90*cfe60390STomohiro Kusumi {
91*cfe60390STomohiro Kusumi 	struct inode *ip;
92*cfe60390STomohiro Kusumi 	struct vnode *vp;
93*cfe60390STomohiro Kusumi 
94*cfe60390STomohiro Kusumi 	lwkt_gettoken(&ext2_ihash_token);
95*cfe60390STomohiro Kusumi loop:
96*cfe60390STomohiro Kusumi 	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
97*cfe60390STomohiro Kusumi 		if (inum != ip->i_number || dev != ip->i_dev)
98*cfe60390STomohiro Kusumi 			continue;
99*cfe60390STomohiro Kusumi 		vp = ITOV(ip);
100*cfe60390STomohiro Kusumi 		if (vget(vp, LK_EXCLUSIVE))
101*cfe60390STomohiro Kusumi 			goto loop;
102*cfe60390STomohiro Kusumi 		/*
103*cfe60390STomohiro Kusumi 		 * We must check to see if the inode has been ripped
104*cfe60390STomohiro Kusumi 		 * out from under us after blocking.
105*cfe60390STomohiro Kusumi 		 */
106*cfe60390STomohiro Kusumi 		for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
107*cfe60390STomohiro Kusumi 			if (inum == ip->i_number && dev == ip->i_dev)
108*cfe60390STomohiro Kusumi 				break;
109*cfe60390STomohiro Kusumi 		}
110*cfe60390STomohiro Kusumi 		if (ip == NULL || ITOV(ip) != vp) {
111*cfe60390STomohiro Kusumi 			vput(vp);
112*cfe60390STomohiro Kusumi 			goto loop;
113*cfe60390STomohiro Kusumi 		}
114*cfe60390STomohiro Kusumi 		lwkt_reltoken(&ext2_ihash_token);
115*cfe60390STomohiro Kusumi 		return (vp);
116*cfe60390STomohiro Kusumi 	}
117*cfe60390STomohiro Kusumi 	lwkt_reltoken(&ext2_ihash_token);
118*cfe60390STomohiro Kusumi 	return (NULL);
119*cfe60390STomohiro Kusumi }
120*cfe60390STomohiro Kusumi 
121*cfe60390STomohiro Kusumi /*
122*cfe60390STomohiro Kusumi  * Insert the inode into the hash table, and return it locked.
123*cfe60390STomohiro Kusumi  */
124*cfe60390STomohiro Kusumi int
ext2_ihashins(struct inode * ip)125*cfe60390STomohiro Kusumi ext2_ihashins(struct inode *ip)
126*cfe60390STomohiro Kusumi {
127*cfe60390STomohiro Kusumi 	struct inode **ipp;
128*cfe60390STomohiro Kusumi 	struct inode *iq;
129*cfe60390STomohiro Kusumi 
130*cfe60390STomohiro Kusumi 	KKASSERT((ip->i_flag & IN_HASHED) == 0);
131*cfe60390STomohiro Kusumi 	lwkt_gettoken(&ext2_ihash_token);
132*cfe60390STomohiro Kusumi 	ipp = INOHASH(ip->i_dev, ip->i_number);
133*cfe60390STomohiro Kusumi 	while ((iq = *ipp) != NULL) {
134*cfe60390STomohiro Kusumi 		if (ip->i_dev == iq->i_dev && ip->i_number == iq->i_number) {
135*cfe60390STomohiro Kusumi 			lwkt_reltoken(&ext2_ihash_token);
136*cfe60390STomohiro Kusumi 			return (EBUSY);
137*cfe60390STomohiro Kusumi 		}
138*cfe60390STomohiro Kusumi 		ipp = &iq->i_next;
139*cfe60390STomohiro Kusumi 	}
140*cfe60390STomohiro Kusumi 	ip->i_next = NULL;
141*cfe60390STomohiro Kusumi 	*ipp = ip;
142*cfe60390STomohiro Kusumi 	ip->i_flag |= IN_HASHED;
143*cfe60390STomohiro Kusumi 	lwkt_reltoken(&ext2_ihash_token);
144*cfe60390STomohiro Kusumi 	return (0);
145*cfe60390STomohiro Kusumi }
146*cfe60390STomohiro Kusumi 
147*cfe60390STomohiro Kusumi /*
148*cfe60390STomohiro Kusumi  * Remove the inode from the hash table.
149*cfe60390STomohiro Kusumi  */
150*cfe60390STomohiro Kusumi void
ext2_ihashrem(struct inode * ip)151*cfe60390STomohiro Kusumi ext2_ihashrem(struct inode *ip)
152*cfe60390STomohiro Kusumi {
153*cfe60390STomohiro Kusumi 	struct inode **ipp;
154*cfe60390STomohiro Kusumi 	struct inode *iq;
155*cfe60390STomohiro Kusumi 
156*cfe60390STomohiro Kusumi 	lwkt_gettoken(&ext2_ihash_token);
157*cfe60390STomohiro Kusumi 	if (ip->i_flag & IN_HASHED) {
158*cfe60390STomohiro Kusumi 		ipp = INOHASH(ip->i_dev, ip->i_number);
159*cfe60390STomohiro Kusumi 		while ((iq = *ipp) != NULL) {
160*cfe60390STomohiro Kusumi 			if (ip == iq)
161*cfe60390STomohiro Kusumi 				break;
162*cfe60390STomohiro Kusumi 			ipp = &iq->i_next;
163*cfe60390STomohiro Kusumi 		}
164*cfe60390STomohiro Kusumi 		KKASSERT(ip == iq);
165*cfe60390STomohiro Kusumi 		*ipp = ip->i_next;
166*cfe60390STomohiro Kusumi 		ip->i_next = NULL;
167*cfe60390STomohiro Kusumi 		ip->i_flag &= ~IN_HASHED;
168*cfe60390STomohiro Kusumi 	}
169*cfe60390STomohiro Kusumi 	lwkt_reltoken(&ext2_ihash_token);
170*cfe60390STomohiro Kusumi }
171