- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop
Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
		
	
			
		
			
				
	
	
		
			213 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*	$NetBSD: chfs_ihash.c,v 1.2 2012/10/19 12:44:39 ttoth 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) {
 | 
						|
			vp = ITOV(ip);
 | 
						|
			KASSERT(vp != NULL);
 | 
						|
			if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) {
 | 
						|
				mutex_exit(&chfs_ihash_lock);
 | 
						|
				goto loop;
 | 
						|
			}
 | 
						|
			/*
 | 
						|
			if (VOP_ISLOCKED(vp))
 | 
						|
				dbg("locked\n");
 | 
						|
			else
 | 
						|
				dbg("isn't locked\n");
 | 
						|
			*/
 | 
						|
			if (flags == 0) {
 | 
						|
				mutex_exit(&chfs_ihash_lock);
 | 
						|
			} else {
 | 
						|
				mutex_enter(vp->v_interlock);
 | 
						|
				mutex_exit(&chfs_ihash_lock);
 | 
						|
				if (vget(vp, flags)) {
 | 
						|
					goto loop;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return (vp);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	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);
 | 
						|
}
 | 
						|
 |