1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ufs_ihash.c 7.4 (Berkeley) 03/11/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/namei.h> 13 #include <sys/vnode.h> 14 #include <sys/malloc.h> 15 16 #include <ufs/ufs/quota.h> 17 #include <ufs/ufs/inode.h> 18 #include <ufs/ufs/ufs_extern.h> 19 20 /* 21 * Structures associated with inode cacheing. 22 */ 23 union ihash { 24 union ihash *ih_head[2]; 25 struct inode *ih_chain[2]; 26 } *ihashtbl; 27 #define ih_forw ih_chain[0] 28 #define ih_back ih_chain[1] 29 30 u_long ihash; /* size of hash table - 1 */ 31 #define INOHASH(dev, ino) (((dev) + (ino)) & ihash) 32 33 /* 34 * Initialize inode hash table. 35 */ 36 void 37 ufs_ihashinit() 38 { 39 register union ihash *ihp; 40 long ihashsize; 41 42 ihashsize = roundup((desiredvnodes + 1) * sizeof *ihp / 2, 43 NBPG * CLSIZE); 44 ihashtbl = (union ihash *)malloc((u_long)ihashsize, 45 M_UFSMNT, M_WAITOK); 46 for (ihash = 1; ihash <= ihashsize / sizeof *ihp; ihash <<= 1) 47 continue; 48 ihash = (ihash >> 1) - 1; 49 for (ihp = &ihashtbl[ihash]; ihp >= ihashtbl; ihp--) { 50 ihp->ih_head[0] = ihp; 51 ihp->ih_head[1] = ihp; 52 } 53 } 54 55 /* 56 * Use the dev/ino pair to find the incore inode, and return a pointer to it. 57 * If it is in core, but locked, wait for it. 58 */ 59 struct vnode * 60 ufs_ihashget(dev, ino) 61 /* dev_t */ int dev; 62 ino_t ino; 63 { 64 register union ihash *ihp; 65 register struct inode *ip; 66 struct vnode *vp; 67 68 ihp = &ihashtbl[INOHASH(dev, ino)]; 69 loop: 70 for (ip = ihp->ih_forw; ip != (struct inode *)ihp; ip = ip->i_forw) { 71 if (ino != ip->i_number || dev != ip->i_dev) 72 continue; 73 if ((ip->i_flag & ILOCKED) != 0) { 74 ip->i_flag |= IWANT; 75 sleep((caddr_t)ip, PINOD); 76 goto loop; 77 } 78 vp = ITOV(ip); 79 if (vget(vp)) 80 goto loop; 81 return (vp); 82 } 83 return (NULL); 84 } 85 86 /* 87 * Insert the inode into the hash table, and return it locked. 88 */ 89 void 90 ufs_ihashins(ip) 91 struct inode *ip; 92 { 93 insque(ip, &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]); 94 ILOCK(ip); 95 } 96