Commit | Line | Data |
---|---|---|
0db0015e | 1 | /* |
ad0f93d2 KB |
2 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
0db0015e KB |
4 | * |
5 | * %sccs.include.redist.c% | |
6 | * | |
5685f766 | 7 | * @(#)ufs_ihash.c 8.2 (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 */ | |
5685f766 | 25 | #define INOHASH(device, inum) (((device) + (inum)) & 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 | 37 | /* |
5685f766 KB |
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. | |
ba0aa422 MS |
40 | */ |
41 | struct vnode * | |
5685f766 KB |
42 | ufs_ihashlookup(device, inum) |
43 | dev_t device; | |
44 | ino_t inum; | |
ba0aa422 MS |
45 | { |
46 | register struct inode **ipp, *ip; | |
47 | ||
5685f766 KB |
48 | ipp = &ihashtbl[INOHASH(device, inum)]; |
49 | for (ip = *ipp; ip; ip = ip->i_next) | |
50 | if (inum == ip->i_number && device == ip->i_dev) | |
51 | return (ITOV(ip)); | |
ba0aa422 MS |
52 | return (NULL); |
53 | } | |
54 | ||
0db0015e | 55 | /* |
5685f766 KB |
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. | |
0db0015e | 58 | */ |
0e112b75 | 59 | struct vnode * |
5685f766 KB |
60 | ufs_ihashget(device, inum) |
61 | dev_t device; | |
62 | ino_t inum; | |
0db0015e | 63 | { |
38785877 | 64 | register struct inode **ipp, *ip; |
0e112b75 | 65 | struct vnode *vp; |
0db0015e | 66 | |
5685f766 KB |
67 | ipp = &ihashtbl[INOHASH(device, inum)]; |
68 | retry: for (ip = *ipp; ip != NULL; ip = ip->i_next) | |
69 | if (inum == ip->i_number && device == ip->i_dev) { | |
70 | if (ip->i_flag & ILOCKED) { | |
71 | ip->i_flag |= IWANT; | |
72 | sleep(ip, PINOD); | |
73 | goto retry; | |
74 | } | |
75 | vp = ITOV(ip); | |
76 | if (vget(vp)) | |
77 | goto retry; | |
78 | return (vp); | |
0db0015e | 79 | } |
0db0015e KB |
80 | return (NULL); |
81 | } | |
82 | ||
83 | /* | |
84 | * Insert the inode into the hash table, and return it locked. | |
85 | */ | |
86 | void | |
87 | ufs_ihashins(ip) | |
88 | struct inode *ip; | |
89 | { | |
38785877 KM |
90 | struct inode **ipp, *iq; |
91 | ||
92 | ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]; | |
93 | if (iq = *ipp) | |
94 | iq->i_prev = &ip->i_next; | |
95 | ip->i_next = iq; | |
96 | ip->i_prev = ipp; | |
97 | *ipp = ip; | |
e22374d9 KM |
98 | if ((ip->i_flag & ILOCKED) != 0) |
99 | panic("ufs_ihashins: already locked"); | |
28d864e8 KM |
100 | if (curproc) |
101 | ip->i_lockholder = curproc->p_pid; | |
102 | else | |
103 | ip->i_lockholder = -1; | |
e22374d9 | 104 | ip->i_flag |= ILOCKED; |
0db0015e | 105 | } |
38785877 KM |
106 | |
107 | /* | |
108 | * Remove the inode from the hash table. | |
109 | */ | |
110 | void | |
111 | ufs_ihashrem(ip) | |
112 | register struct inode *ip; | |
113 | { | |
114 | register struct inode *iq; | |
115 | ||
116 | if (iq = ip->i_next) | |
117 | iq->i_prev = ip->i_prev; | |
118 | *ip->i_prev = iq; | |
119 | #ifdef DIAGNOSTIC | |
120 | ip->i_next = NULL; | |
121 | ip->i_prev = NULL; | |
122 | #endif | |
123 | } |