 d65f6f7009
			
		
	
	
		d65f6f7009
		
	
	
	
	
		
			
			. common/include/arch/i386 is not actually an imported sys/arch/i386/include but leftover Minix files; remove and move to include/ . move include/ufs to sys/ufs, where it came from, now that we have a sys/ hierarchy . move mdocml/ to external/bsd/, now we have that . single sys/arch/i386/stand/ import for boot stuff
		
			
				
	
	
		
			221 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*	$NetBSD: chfs_ihash.c,v 1.1 2011/11/24 15:51:31 ahoka Exp $	*/
 | |
| 
 | |
| /*-
 | |
|  * Copyright (c) 2010 Department of Software Engineering,
 | |
|  *		      University of Szeged, Hungary
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * This code is derived from software contributed to The NetBSD Foundation
 | |
|  * by the Department of Software Engineering, University of Szeged, Hungary
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  * 1. Redistributions of source code must retain the above copyright
 | |
|  *    notice, this list of conditions and the following disclaimer.
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright
 | |
|  *    notice, this list of conditions and the following disclaimer in the
 | |
|  *    documentation and/or other materials provided with the distribution.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | |
|  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | |
|  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | |
|  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | |
|  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | |
|  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | |
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | |
|  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | |
|  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | |
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | |
|  * SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #include "chfs.h"
 | |
| /*
 | |
|  * Structures associated with inode cacheing.
 | |
|  */
 | |
| static LIST_HEAD(ihashhead, chfs_inode) *chfs_ihashtbl;
 | |
| static u_long	chfs_ihash;		/* size of hash table - 1 */
 | |
| #define INOHASH(device, inum)	(((device) + (inum)) & chfs_ihash)
 | |
| 
 | |
| kmutex_t	chfs_ihash_lock;
 | |
| kmutex_t	chfs_hashlock;
 | |
| 
 | |
| /*
 | |
|  * Initialize inode hash table.
 | |
|  */
 | |
| void
 | |
| chfs_ihashinit(void)
 | |
| {
 | |
| 	dbg("initing\n");
 | |
| 
 | |
| 	mutex_init(&chfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
 | |
| 	mutex_init(&chfs_ihash_lock, MUTEX_DEFAULT, IPL_NONE);
 | |
| 	chfs_ihashtbl = hashinit(desiredvnodes,
 | |
| 	    HASH_LIST, true, &chfs_ihash);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Reinitialize inode hash table.
 | |
|  */
 | |
| 
 | |
| void
 | |
| chfs_ihashreinit(void)
 | |
| {
 | |
| 	struct chfs_inode *ip;
 | |
| 	struct ihashhead *oldhash, *hash;
 | |
| 	u_long oldmask, mask, val;
 | |
| 	int i;
 | |
| 
 | |
| 	dbg("reiniting\n");
 | |
| 
 | |
| 	hash = hashinit(desiredvnodes, HASH_LIST, true, &mask);
 | |
| 	mutex_enter(&chfs_ihash_lock);
 | |
| 	oldhash = chfs_ihashtbl;
 | |
| 	oldmask = chfs_ihash;
 | |
| 	chfs_ihashtbl = hash;
 | |
| 	chfs_ihash = mask;
 | |
| 	for (i = 0; i <= oldmask; i++) {
 | |
| 		while ((ip = LIST_FIRST(&oldhash[i])) != NULL) {
 | |
| 			LIST_REMOVE(ip, hash_entry);
 | |
| 			val = INOHASH(ip->dev, ip->ino);
 | |
| 			LIST_INSERT_HEAD(&hash[val], ip, hash_entry);
 | |
| 		}
 | |
| 	}
 | |
| 	mutex_exit(&chfs_ihash_lock);
 | |
| 	hashdone(oldhash, HASH_LIST, oldmask);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Free inode hash table.
 | |
|  */
 | |
| void
 | |
| chfs_ihashdone(void)
 | |
| {
 | |
| 	dbg("destroying\n");
 | |
| 
 | |
| 	hashdone(chfs_ihashtbl, HASH_LIST, chfs_ihash);
 | |
| 	mutex_destroy(&chfs_hashlock);
 | |
| 	mutex_destroy(&chfs_ihash_lock);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Use the device/inum pair to find the incore inode, and return a pointer
 | |
|  * to it. If it is in core, return it, even if it is locked.
 | |
|  */
 | |
| struct vnode *
 | |
| chfs_ihashlookup(dev_t dev, ino_t inum)
 | |
| {
 | |
| 	struct chfs_inode *ip;
 | |
| 	struct ihashhead *ipp;
 | |
| 
 | |
| 	dbg("dev: %ju, inum: %ju\n", (uintmax_t )dev, (uintmax_t )inum);
 | |
| 
 | |
| 	KASSERT(mutex_owned(&chfs_ihash_lock));
 | |
| 
 | |
| 	ipp = &chfs_ihashtbl[INOHASH(dev, inum)];
 | |
| 	LIST_FOREACH(ip, ipp, hash_entry) {
 | |
| 		if (inum == ip->ino && dev == ip->dev) {
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (ip) {
 | |
| 		return (ITOV(ip));
 | |
| 	}
 | |
| 
 | |
| 	return (NULLVP);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Use the device/inum pair to find the incore inode, and return a pointer
 | |
|  * to it. If it is in core, but locked, wait for it.
 | |
|  */
 | |
| struct vnode *
 | |
| chfs_ihashget(dev_t dev, ino_t inum, int flags)
 | |
| {
 | |
| 	struct ihashhead *ipp;
 | |
| 	struct chfs_inode *ip;
 | |
| 	struct vnode *vp;
 | |
| 
 | |
| 	dbg("search for ino\n");
 | |
| 
 | |
| loop:
 | |
| 	mutex_enter(&chfs_ihash_lock);
 | |
| 	ipp = &chfs_ihashtbl[INOHASH(dev, inum)];
 | |
| 	dbg("ipp: %p, chfs_ihashtbl: %p, ihash: %lu\n",
 | |
| 	    ipp, chfs_ihashtbl, chfs_ihash);
 | |
| 	LIST_FOREACH(ip, ipp, hash_entry) {
 | |
| 		dbg("ip: %p\n", ip);
 | |
| 		if (inum == ip->ino && dev == ip->dev) {
 | |
| //			printf("chfs_ihashget: found inode: %p\n", ip);
 | |
| 			vp = ITOV(ip);
 | |
| 			KASSERT(vp != NULL);
 | |
| 			//dbg("found\n");
 | |
| 			if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) {
 | |
| 				//dbg("wait for #%llu\n", ip->ino);
 | |
| 				mutex_exit(&chfs_ihash_lock);
 | |
| 				goto loop;
 | |
| 			}
 | |
| 			/*
 | |
| 			if (VOP_ISLOCKED(vp))
 | |
| 				dbg("locked\n");
 | |
| 			else
 | |
| 				dbg("isn't locked\n");
 | |
| 			*/
 | |
| 			if (flags == 0) {
 | |
| 				//dbg("no flags\n");
 | |
| 				mutex_exit(&chfs_ihash_lock);
 | |
| 			} else {
 | |
| 				//dbg("vget\n");
 | |
| 				mutex_enter(vp->v_interlock);
 | |
| 				mutex_exit(&chfs_ihash_lock);
 | |
| 				if (vget(vp, flags)) {
 | |
| 					goto loop;
 | |
| 				}
 | |
| 				//dbg("got it\n");
 | |
| 			}
 | |
| 			//dbg("return\n");
 | |
| 			return (vp);
 | |
| 		}
 | |
| 	}
 | |
| 	//dbg("not found\n");
 | |
| 	mutex_exit(&chfs_ihash_lock);
 | |
| 	return (NULL);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Insert the inode into the hash table, and return it locked.
 | |
|  */
 | |
| void
 | |
| chfs_ihashins(struct chfs_inode *ip)
 | |
| {
 | |
| 	struct ihashhead *ipp;
 | |
| 
 | |
| 	dbg("ip: %p\n", ip);
 | |
| 
 | |
| 	KASSERT(mutex_owned(&chfs_hashlock));
 | |
| 
 | |
| 	/* lock the inode, then put it on the appropriate hash list */
 | |
| 	VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
 | |
| 
 | |
| 	mutex_enter(&chfs_ihash_lock);
 | |
| 	ipp = &chfs_ihashtbl[INOHASH(ip->dev, ip->ino)];
 | |
| 	LIST_INSERT_HEAD(ipp, ip, hash_entry);
 | |
| 	mutex_exit(&chfs_ihash_lock);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Remove the inode from the hash table.
 | |
|  */
 | |
| void
 | |
| chfs_ihashrem(struct chfs_inode *ip)
 | |
| {
 | |
| 	dbg("ip: %p\n", ip);
 | |
| 
 | |
| 	mutex_enter(&chfs_ihash_lock);
 | |
| 	LIST_REMOVE(ip, hash_entry);
 | |
| 	mutex_exit(&chfs_ihash_lock);
 | |
| }
 | |
| 
 |