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.5 (Berkeley) 07/20/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/vnode.h> 13 #include <sys/malloc.h> 14 15 #include <ufs/ufs/quota.h> 16 #include <ufs/ufs/inode.h> 17 #include <ufs/ufs/ufs_extern.h> 18 19 /* 20 * Structures associated with inode cacheing. 21 */ 22 struct inode **ihashtbl; 23 u_long ihash; /* size of hash table - 1 */ 24 #define INOHASH(dev, ino) (((dev) + (ino)) & ihash) 25 26 /* 27 * Initialize inode hash table. 28 */ 29 void 30 ufs_ihashinit() 31 { 32 33 ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash); 34 } 35 36 /* 37 * Use the dev/ino pair to find the incore inode, and return a pointer to it. 38 * If it is in core, but locked, wait for it. 39 */ 40 struct vnode * 41 ufs_ihashget(dev, ino) 42 dev_t dev; 43 ino_t ino; 44 { 45 register struct inode **ipp, *ip; 46 struct vnode *vp; 47 48 ipp = &ihashtbl[INOHASH(dev, ino)]; 49 loop: 50 for (ip = *ipp; ip; ip = ip->i_next) { 51 if (ino != ip->i_number || dev != ip->i_dev) 52 continue; 53 if ((ip->i_flag & ILOCKED) != 0) { 54 ip->i_flag |= IWANT; 55 sleep((caddr_t)ip, PINOD); 56 goto loop; 57 } 58 vp = ITOV(ip); 59 if (vget(vp)) 60 goto loop; 61 return (vp); 62 } 63 return (NULL); 64 } 65 66 /* 67 * Insert the inode into the hash table, and return it locked. 68 */ 69 void 70 ufs_ihashins(ip) 71 struct inode *ip; 72 { 73 struct inode **ipp, *iq; 74 75 ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]; 76 if (iq = *ipp) 77 iq->i_prev = &ip->i_next; 78 ip->i_next = iq; 79 ip->i_prev = ipp; 80 *ipp = ip; 81 ILOCK(ip); 82 } 83 84 /* 85 * Remove the inode from the hash table. 86 */ 87 void 88 ufs_ihashrem(ip) 89 register struct inode *ip; 90 { 91 register struct inode *iq; 92 93 if (iq = ip->i_next) 94 iq->i_prev = ip->i_prev; 95 *ip->i_prev = iq; 96 #ifdef DIAGNOSTIC 97 ip->i_next = NULL; 98 ip->i_prev = NULL; 99 #endif 100 } 101