Annotation of sys/ufs/ufs/ufs_ihash.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ufs_ihash.c,v 1.13 2007/03/21 17:29:32 thib Exp $ */
! 2: /* $NetBSD: ufs_ihash.c,v 1.3 1996/02/09 22:36:04 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1982, 1986, 1989, 1991, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. Neither the name of the University nor the names of its contributors
! 17: * may be used to endorse or promote products derived from this software
! 18: * without specific prior written permission.
! 19: *
! 20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 30: * SUCH DAMAGE.
! 31: *
! 32: * @(#)ufs_ihash.c 8.4 (Berkeley) 12/30/93
! 33: */
! 34:
! 35: #include <sys/param.h>
! 36: #include <sys/systm.h>
! 37: #include <sys/vnode.h>
! 38: #include <sys/malloc.h>
! 39: #include <sys/proc.h>
! 40:
! 41: #include <ufs/ufs/quota.h>
! 42: #include <ufs/ufs/inode.h>
! 43: #include <ufs/ufs/ufs_extern.h>
! 44:
! 45: /*
! 46: * Structures associated with inode cacheing.
! 47: */
! 48: LIST_HEAD(ihashhead, inode) *ihashtbl;
! 49: u_long ihash; /* size of hash table - 1 */
! 50: #define INOHASH(device, inum) (&ihashtbl[((device) + (inum)) & ihash])
! 51: struct simplelock ufs_ihash_slock;
! 52:
! 53: /*
! 54: * Initialize inode hash table.
! 55: */
! 56: void
! 57: ufs_ihashinit(void)
! 58: {
! 59: ihashtbl = hashinit(desiredvnodes, M_UFSMNT, M_WAITOK, &ihash);
! 60: simple_lock_init(&ufs_ihash_slock);
! 61: }
! 62:
! 63: /*
! 64: * Use the device/inum pair to find the incore inode, and return a pointer
! 65: * to it. If it is in core, return it, even if it is locked.
! 66: */
! 67: struct vnode *
! 68: ufs_ihashlookup(dev_t dev, ino_t inum)
! 69: {
! 70: struct inode *ip;
! 71:
! 72: simple_lock(&ufs_ihash_slock);
! 73: LIST_FOREACH(ip, INOHASH(dev, inum), i_hash)
! 74: if (inum == ip->i_number && dev == ip->i_dev)
! 75: break;
! 76: simple_unlock(&ufs_ihash_slock);
! 77:
! 78: if (ip)
! 79: return (ITOV(ip));
! 80:
! 81: return (NULLVP);
! 82: }
! 83:
! 84: /*
! 85: * Use the device/inum pair to find the incore inode, and return a pointer
! 86: * to it. If it is in core, but locked, wait for it.
! 87: */
! 88: struct vnode *
! 89: ufs_ihashget(dev_t dev, ino_t inum)
! 90: {
! 91: struct proc *p = curproc;
! 92: struct inode *ip;
! 93: struct vnode *vp;
! 94: loop:
! 95: simple_lock(&ufs_ihash_slock);
! 96: LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) {
! 97: if (inum == ip->i_number && dev == ip->i_dev) {
! 98: vp = ITOV(ip);
! 99: simple_unlock(&ufs_ihash_slock);
! 100: if (vget(vp, LK_EXCLUSIVE, p))
! 101: goto loop;
! 102: return (vp);
! 103: }
! 104: }
! 105: simple_unlock(&ufs_ihash_slock);
! 106: return (NULL);
! 107: }
! 108:
! 109: /*
! 110: * Insert the inode into the hash table, and return it locked.
! 111: */
! 112: int
! 113: ufs_ihashins(struct inode *ip)
! 114: {
! 115: struct inode *curip;
! 116: struct ihashhead *ipp;
! 117: dev_t dev = ip->i_dev;
! 118: ino_t inum = ip->i_number;
! 119:
! 120: /* lock the inode, then put it on the appropriate hash list */
! 121: lockmgr(&ip->i_lock, LK_EXCLUSIVE, NULL);
! 122:
! 123: simple_lock(&ufs_ihash_slock);
! 124:
! 125: LIST_FOREACH(curip, INOHASH(dev, inum), i_hash) {
! 126: if (inum == curip->i_number && dev == curip->i_dev) {
! 127: simple_unlock(&ufs_ihash_slock);
! 128: lockmgr(&ip->i_lock, LK_RELEASE, NULL);
! 129: return (EEXIST);
! 130: }
! 131: }
! 132:
! 133: ipp = INOHASH(dev, inum);
! 134: LIST_INSERT_HEAD(ipp, ip, i_hash);
! 135: simple_unlock(&ufs_ihash_slock);
! 136:
! 137: return (0);
! 138: }
! 139:
! 140: /*
! 141: * Remove the inode from the hash table.
! 142: */
! 143: void
! 144: ufs_ihashrem(struct inode *ip)
! 145: {
! 146: simple_lock(&ufs_ihash_slock);
! 147:
! 148: if (ip->i_hash.le_prev == NULL)
! 149: return;
! 150:
! 151: LIST_REMOVE(ip, i_hash);
! 152: #ifdef DIAGNOSTIC
! 153: ip->i_hash.le_next = NULL;
! 154: ip->i_hash.le_prev = NULL;
! 155: #endif
! 156: simple_unlock(&ufs_ihash_slock);
! 157:
! 158: }
CVSweb