xref: /csrg-svn/sys/ufs/ffs/ufs_ihash.c (revision 65234)
151517Sbostic /*
263376Sbostic  * Copyright (c) 1982, 1986, 1989, 1991, 1993
363376Sbostic  *	The Regents of the University of California.  All rights reserved.
451517Sbostic  *
551517Sbostic  * %sccs.include.redist.c%
651517Sbostic  *
7*65234Smckusick  *	@(#)ufs_ihash.c	8.4 (Berkeley) 12/30/93
851517Sbostic  */
951517Sbostic 
1051517Sbostic #include <sys/param.h>
1151517Sbostic #include <sys/systm.h>
1251517Sbostic #include <sys/vnode.h>
1351975Smckusick #include <sys/malloc.h>
1457037Smckusick #include <sys/proc.h>
1551517Sbostic 
1651517Sbostic #include <ufs/ufs/quota.h>
1751517Sbostic #include <ufs/ufs/inode.h>
1851517Sbostic #include <ufs/ufs/ufs_extern.h>
1951517Sbostic 
2051975Smckusick /*
2151975Smckusick  * Structures associated with inode cacheing.
2251975Smckusick  */
2355411Smckusick struct inode **ihashtbl;
2455411Smckusick u_long	ihash;		/* size of hash table - 1 */
2564427Sbostic #define	INOHASH(device, inum)	(((device) + (inum)) & ihash)
2651517Sbostic 
2751517Sbostic /*
2851517Sbostic  * Initialize inode hash table.
2951517Sbostic  */
3051517Sbostic void
ufs_ihashinit()3151517Sbostic ufs_ihashinit()
3251517Sbostic {
3351517Sbostic 
3455411Smckusick 	ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash);
3551517Sbostic }
3651517Sbostic 
3751517Sbostic /*
3864427Sbostic  * Use the device/inum pair to find the incore inode, and return a pointer
3964427Sbostic  * to it. If it is in core, return it, even if it is locked.
4057038Smargo  */
4157038Smargo struct vnode *
ufs_ihashlookup(device,inum)4264427Sbostic ufs_ihashlookup(device, inum)
4364427Sbostic 	dev_t device;
4464427Sbostic 	ino_t inum;
4557038Smargo {
4664601Sbostic 	register struct inode *ip;
4757038Smargo 
4864601Sbostic 	for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
4964601Sbostic 		if (ip == NULL)
5064601Sbostic 			return (NULL);
5164427Sbostic 		if (inum == ip->i_number && device == ip->i_dev)
5264427Sbostic 			return (ITOV(ip));
5364601Sbostic 	}
5464601Sbostic 	/* NOTREACHED */
5557038Smargo }
5657038Smargo 
5757038Smargo /*
5864427Sbostic  * Use the device/inum pair to find the incore inode, and return a pointer
5964427Sbostic  * to it. If it is in core, but locked, wait for it.
6051517Sbostic  */
6151553Smckusick struct vnode *
ufs_ihashget(device,inum)6264427Sbostic ufs_ihashget(device, inum)
6364427Sbostic 	dev_t device;
6464427Sbostic 	ino_t inum;
6551517Sbostic {
6664601Sbostic 	register struct inode *ip;
6751553Smckusick 	struct vnode *vp;
6851517Sbostic 
6964601Sbostic 	for (;;)
7064601Sbostic 		for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
7164601Sbostic 			if (ip == NULL)
7264601Sbostic 				return (NULL);
7364601Sbostic 			if (inum == ip->i_number && device == ip->i_dev) {
7464601Sbostic 				if (ip->i_flag & IN_LOCKED) {
7564601Sbostic 					ip->i_flag |= IN_WANTED;
7664601Sbostic 					sleep(ip, PINOD);
7764601Sbostic 					break;
7864601Sbostic 				}
7964601Sbostic 				vp = ITOV(ip);
80*65234Smckusick 				if (!vget(vp, 1))
8164601Sbostic 					return (vp);
8264601Sbostic 				break;
8364427Sbostic 			}
8451517Sbostic 		}
8564601Sbostic 	/* NOTREACHED */
8651517Sbostic }
8751517Sbostic 
8851517Sbostic /*
8951517Sbostic  * Insert the inode into the hash table, and return it locked.
9051517Sbostic  */
9151517Sbostic void
ufs_ihashins(ip)9251517Sbostic ufs_ihashins(ip)
9351517Sbostic 	struct inode *ip;
9451517Sbostic {
9555411Smckusick 	struct inode **ipp, *iq;
9655411Smckusick 
9755411Smckusick 	ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
9855411Smckusick 	if (iq = *ipp)
9955411Smckusick 		iq->i_prev = &ip->i_next;
10055411Smckusick 	ip->i_next = iq;
10155411Smckusick 	ip->i_prev = ipp;
10255411Smckusick 	*ipp = ip;
10364601Sbostic 	if (ip->i_flag & IN_LOCKED)
10456801Smckusick 		panic("ufs_ihashins: already locked");
10557037Smckusick 	if (curproc)
10657037Smckusick 		ip->i_lockholder = curproc->p_pid;
10757037Smckusick 	else
10857037Smckusick 		ip->i_lockholder = -1;
10964601Sbostic 	ip->i_flag |= IN_LOCKED;
11051517Sbostic }
11155411Smckusick 
11255411Smckusick /*
11355411Smckusick  * Remove the inode from the hash table.
11455411Smckusick  */
11555411Smckusick void
ufs_ihashrem(ip)11655411Smckusick ufs_ihashrem(ip)
11755411Smckusick 	register struct inode *ip;
11855411Smckusick {
11955411Smckusick 	register struct inode *iq;
12055411Smckusick 
12155411Smckusick 	if (iq = ip->i_next)
12255411Smckusick 		iq->i_prev = ip->i_prev;
12355411Smckusick 	*ip->i_prev = iq;
12455411Smckusick #ifdef DIAGNOSTIC
12555411Smckusick 	ip->i_next = NULL;
12655411Smckusick 	ip->i_prev = NULL;
12755411Smckusick #endif
12855411Smckusick }
129