Commit | Line | Data |
---|---|---|
0db0015e KB |
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 | * | |
ba0aa422 | 7 | * @(#)ufs_ihash.c 7.8 (Berkeley) %G% |
0db0015e KB |
8 | */ |
9 | ||
10 | #include <sys/param.h> | |
11 | #include <sys/systm.h> | |
0db0015e | 12 | #include <sys/vnode.h> |
e53da348 | 13 | #include <sys/malloc.h> |
28d864e8 | 14 | #include <sys/proc.h> |
0db0015e KB |
15 | |
16 | #include <ufs/ufs/quota.h> | |
17 | #include <ufs/ufs/inode.h> | |
18 | #include <ufs/ufs/ufs_extern.h> | |
19 | ||
e53da348 KM |
20 | /* |
21 | * Structures associated with inode cacheing. | |
22 | */ | |
38785877 KM |
23 | struct inode **ihashtbl; |
24 | u_long ihash; /* size of hash table - 1 */ | |
e53da348 | 25 | #define INOHASH(dev, ino) (((dev) + (ino)) & ihash) |
0db0015e KB |
26 | |
27 | /* | |
28 | * Initialize inode hash table. | |
29 | */ | |
30 | void | |
31 | ufs_ihashinit() | |
32 | { | |
0db0015e | 33 | |
38785877 | 34 | ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash); |
0db0015e KB |
35 | } |
36 | ||
ba0aa422 MS |
37 | /* |
38 | * Use the dev/ino pair to find the incore inode, and return a pointer to it. | |
39 | * If it is in core, return it, even if it is locked. | |
40 | */ | |
41 | struct vnode * | |
42 | ufs_ihashlookup(dev, ino) | |
43 | dev_t dev; | |
44 | ino_t ino; | |
45 | { | |
46 | register struct inode **ipp, *ip; | |
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 | return (ITOV(ip)); | |
54 | } | |
55 | return (NULL); | |
56 | } | |
57 | ||
0db0015e KB |
58 | /* |
59 | * Use the dev/ino pair to find the incore inode, and return a pointer to it. | |
60 | * If it is in core, but locked, wait for it. | |
61 | */ | |
0e112b75 | 62 | struct vnode * |
0db0015e | 63 | ufs_ihashget(dev, ino) |
38785877 | 64 | dev_t dev; |
0db0015e KB |
65 | ino_t ino; |
66 | { | |
38785877 | 67 | register struct inode **ipp, *ip; |
0e112b75 | 68 | struct vnode *vp; |
0db0015e | 69 | |
38785877 | 70 | ipp = &ihashtbl[INOHASH(dev, ino)]; |
0db0015e | 71 | loop: |
38785877 | 72 | for (ip = *ipp; ip; ip = ip->i_next) { |
0db0015e KB |
73 | if (ino != ip->i_number || dev != ip->i_dev) |
74 | continue; | |
75 | if ((ip->i_flag & ILOCKED) != 0) { | |
76 | ip->i_flag |= IWANT; | |
77 | sleep((caddr_t)ip, PINOD); | |
78 | goto loop; | |
79 | } | |
0e112b75 KM |
80 | vp = ITOV(ip); |
81 | if (vget(vp)) | |
0db0015e | 82 | goto loop; |
0e112b75 | 83 | return (vp); |
0db0015e KB |
84 | } |
85 | return (NULL); | |
86 | } | |
87 | ||
88 | /* | |
89 | * Insert the inode into the hash table, and return it locked. | |
90 | */ | |
91 | void | |
92 | ufs_ihashins(ip) | |
93 | struct inode *ip; | |
94 | { | |
38785877 KM |
95 | struct inode **ipp, *iq; |
96 | ||
97 | ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]; | |
98 | if (iq = *ipp) | |
99 | iq->i_prev = &ip->i_next; | |
100 | ip->i_next = iq; | |
101 | ip->i_prev = ipp; | |
102 | *ipp = ip; | |
e22374d9 KM |
103 | if ((ip->i_flag & ILOCKED) != 0) |
104 | panic("ufs_ihashins: already locked"); | |
28d864e8 KM |
105 | if (curproc) |
106 | ip->i_lockholder = curproc->p_pid; | |
107 | else | |
108 | ip->i_lockholder = -1; | |
e22374d9 | 109 | ip->i_flag |= ILOCKED; |
0db0015e | 110 | } |
38785877 KM |
111 | |
112 | /* | |
113 | * Remove the inode from the hash table. | |
114 | */ | |
115 | void | |
116 | ufs_ihashrem(ip) | |
117 | register struct inode *ip; | |
118 | { | |
119 | register struct inode *iq; | |
120 | ||
121 | if (iq = ip->i_next) | |
122 | iq->i_prev = ip->i_prev; | |
123 | *ip->i_prev = iq; | |
124 | #ifdef DIAGNOSTIC | |
125 | ip->i_next = NULL; | |
126 | ip->i_prev = NULL; | |
127 | #endif | |
128 | } |