1/* $NetBSD$ */ 2 3/*- 4 * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Yevgeny Binder. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1982, 1986, 1989, 1991, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61#include <sys/cdefs.h> 62__KERNEL_RCSID(0, "$NetBSD$"); 63 64#include <sys/param.h> 65#include <sys/systm.h> 66#include <sys/kernel.h> 67#include <sys/vmmeter.h> 68#include <sys/time.h> 69#include <sys/proc.h> 70#include <sys/vnode.h> 71#include <sys/file.h> 72#include <sys/stat.h> 73#include <sys/mount.h> 74#include <sys/namei.h> 75#include <sys/buf.h> 76#include <sys/dirent.h> 77#include <sys/msgbuf.h> 78 79#include <fs/hfs/hfs.h> 80 81LIST_HEAD(nhashhead, hfsnode) *nhashtbl; 82u_long nhash; /* size of hash table - 1 */ 83#define HNOHASH(device, cnid, fork) (((device) + (cnid) + (fork)) & nhash) 84 85kmutex_t hfs_hashlock; 86kmutex_t hfs_nhash_lock; 87 88/* 89 * Initialize hfsnode hash table. 90 */ 91void 92hfs_nhashinit(void) 93{ 94 95 nhashtbl = hashinit(desiredvnodes, HASH_LIST, true, &nhash); 96 mutex_init(&hfs_nhash_lock, MUTEX_DEFAULT, IPL_NONE); 97 mutex_init(&hfs_hashlock, MUTEX_DEFAULT, IPL_NONE); 98} 99 100/* 101 * Free hfsnode hash table. 102 */ 103void 104hfs_nhashdone(void) 105{ 106 107 hashdone(nhashtbl, HASH_LIST, nhash); 108 mutex_destroy(&hfs_nhash_lock); 109 mutex_destroy(&hfs_hashlock); 110} 111 112/* 113 * Use the device/inum pair to find the incore inode, and return a pointer 114 * to it. If it is in core, but locked, wait for it. 115 */ 116struct vnode * 117hfs_nhashget(dev_t dev, hfs_cnid_t cnid, uint8_t fork, int flags) 118{ 119 struct hfsnode *hp; 120 struct nhashhead *hpp; 121 struct vnode *vp; 122 123loop: 124 mutex_enter(&hfs_nhash_lock); 125 hpp = &nhashtbl[HNOHASH(dev, cnid, fork)]; 126 LIST_FOREACH(hp, hpp, h_hash) { 127 if (cnid == hp->h_rec.u.cnid && dev == hp->h_dev) { 128 vp = HTOV(hp); 129 if (flags == 0) { 130 mutex_exit(&hfs_nhash_lock); 131 } else { 132 mutex_enter(vp->v_interlock); 133 mutex_exit(&hfs_nhash_lock); 134 if (vget(vp, flags)) 135 goto loop; 136 } 137 return vp; 138 } 139 } 140 mutex_exit(&hfs_nhash_lock); 141 return NULL; 142} 143 144/* 145* Insert the hfsnode into the hash table, and return it locked. 146 */ 147void 148hfs_nhashinsert(struct hfsnode *hp) 149{ 150 struct nhashhead *hpp; 151 152 /* lock the inode, then put it on the appropriate hash list */ 153 VOP_LOCK(HTOV(hp), LK_EXCLUSIVE); 154 155 mutex_enter(&hfs_nhash_lock); 156 hpp = &nhashtbl[HNOHASH(hp->h_dev, hp->h_rec.u.cnid, hp->h_fork)]; 157 LIST_INSERT_HEAD(hpp, hp, h_hash); 158 mutex_exit(&hfs_nhash_lock); 159} 160 161/* 162 * Remove the inode from the hash table. 163 */ 164void 165hfs_nhashremove(struct hfsnode *hp) 166{ 167 168 mutex_enter(&hfs_nhash_lock); 169 LIST_REMOVE(hp, h_hash); 170 mutex_exit(&hfs_nhash_lock); 171} 172