1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ufs_ihash.c 8.5 (Berkeley) 03/20/95 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/vnode.h> 13 #include <sys/malloc.h> 14 #include <sys/proc.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 LIST_HEAD(ihashhead, inode) *ihashtbl; 24 u_long ihash; /* size of hash table - 1 */ 25 #define INOHASH(device, inum) (&ihashtbl[((device) + (inum)) & ihash]) 26 27 /* 28 * Initialize inode hash table. 29 */ 30 void 31 ufs_ihashinit() 32 { 33 34 ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash); 35 } 36 37 /* 38 * Use the device/inum pair to find the incore inode, and return a pointer 39 * to it. If it is in core, return it, even if it is locked. 40 */ 41 struct vnode * 42 ufs_ihashlookup(dev, inum) 43 dev_t dev; 44 ino_t inum; 45 { 46 register struct inode *ip; 47 48 for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) { 49 if (inum == ip->i_number && dev == ip->i_dev) 50 return (ITOV(ip)); 51 } 52 return (NULL); 53 } 54 55 /* 56 * Use the device/inum pair to find the incore inode, and return a pointer 57 * to it. If it is in core, but locked, wait for it. 58 */ 59 struct vnode * 60 ufs_ihashget(dev, inum) 61 dev_t dev; 62 ino_t inum; 63 { 64 register struct inode *ip; 65 struct vnode *vp; 66 67 loop: 68 for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) { 69 if (inum == ip->i_number && dev == ip->i_dev) { 70 if (ip->i_flag & IN_LOCKED) { 71 ip->i_flag |= IN_WANTED; 72 sleep(ip, PINOD); 73 goto loop; 74 } 75 vp = ITOV(ip); 76 if (vget(vp, 1)) 77 goto loop; 78 return (vp); 79 } 80 } 81 return (NULL); 82 } 83 84 /* 85 * Insert the inode into the hash table, and return it locked. 86 */ 87 void 88 ufs_ihashins(ip) 89 struct inode *ip; 90 { 91 struct ihashhead *ipp; 92 93 ipp = INOHASH(ip->i_dev, ip->i_number); 94 LIST_INSERT_HEAD(ipp, ip, i_hash); 95 if (ip->i_flag & IN_LOCKED) 96 panic("ufs_ihashins: already locked"); 97 if (curproc) 98 ip->i_lockholder = curproc->p_pid; 99 else 100 ip->i_lockholder = -1; 101 ip->i_flag |= IN_LOCKED; 102 } 103 104 /* 105 * Remove the inode from the hash table. 106 */ 107 void 108 ufs_ihashrem(ip) 109 register struct inode *ip; 110 { 111 register struct inode *iq; 112 113 LIST_REMOVE(ip, i_hash); 114 #ifdef DIAGNOSTIC 115 ip->i_hash.le_next = NULL; 116 ip->i_hash.le_prev = NULL; 117 #endif 118 } 119