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.2 (Berkeley) 11/05/91 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/namei.h> 13 #include <sys/vnode.h> 14 15 #include <ufs/ufs/quota.h> 16 #include <ufs/ufs/inode.h> 17 #include <ufs/ufs/ufs_extern.h> 18 19 #define INOHSZ 512 20 #if ((INOHSZ & (INOHSZ - 1)) == 0) 21 #define INOHASH(dev, ino) (((dev) + (ino)) & (INOHSZ - 1)) 22 #else 23 #define INOHASH(dev, ino) (((unsigned int)((dev) + (ino))) % INOHSZ) 24 #endif 25 26 static union ihead { 27 union ihead *ih_head[2]; 28 struct inode *ih_chain[2]; 29 } ihead[INOHSZ]; 30 31 32 /* 33 * Initialize inode hash table. 34 */ 35 void 36 ufs_ihashinit() 37 { 38 register union ihead *ih; 39 register int i; 40 41 for (ih = ihead, i = INOHSZ; --i >= 0; ++ih) 42 ih->ih_head[0] = ih->ih_head[1] = ih; 43 } 44 45 /* 46 * Use the dev/ino pair to find the incore inode, and return a pointer to it. 47 * If it is in core, but locked, wait for it. 48 */ 49 struct vnode * 50 ufs_ihashget(dev, ino) 51 /* dev_t */ int dev; 52 ino_t ino; 53 { 54 register union ihead *ih; 55 register struct inode *ip; 56 struct vnode *vp; 57 58 ih = &ihead[INOHASH(dev, ino)]; 59 loop: 60 for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw) { 61 if (ino != ip->i_number || dev != ip->i_dev) 62 continue; 63 if ((ip->i_flag & ILOCKED) != 0) { 64 ip->i_flag |= IWANT; 65 sleep((caddr_t)ip, PINOD); 66 goto loop; 67 } 68 vp = ITOV(ip); 69 if (vget(vp)) 70 goto loop; 71 return (vp); 72 } 73 return (NULL); 74 } 75 76 /* 77 * Insert the inode into the hash table, and return it locked. 78 */ 79 void 80 ufs_ihashins(ip) 81 struct inode *ip; 82 { 83 insque(ip, &ihead[INOHASH(ip->i_dev, ip->i_number)]); 84 ILOCK(ip); 85 } 86