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 | * | |
a6e3920d | 7 | * @(#)ufs_ihash.c 7.4 (Berkeley) %G% |
0db0015e KB |
8 | */ |
9 | ||
10 | #include <sys/param.h> | |
11 | #include <sys/systm.h> | |
12 | #include <sys/namei.h> | |
13 | #include <sys/vnode.h> | |
e53da348 | 14 | #include <sys/malloc.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 | */ | |
23 | union ihash { | |
24 | union ihash *ih_head[2]; | |
25 | struct inode *ih_chain[2]; | |
26 | } *ihashtbl; | |
27 | #define ih_forw ih_chain[0] | |
28 | #define ih_back ih_chain[1] | |
0db0015e | 29 | |
e53da348 KM |
30 | u_long ihash; /* size of hash table - 1 */ |
31 | #define INOHASH(dev, ino) (((dev) + (ino)) & ihash) | |
0db0015e KB |
32 | |
33 | /* | |
34 | * Initialize inode hash table. | |
35 | */ | |
36 | void | |
37 | ufs_ihashinit() | |
38 | { | |
e53da348 KM |
39 | register union ihash *ihp; |
40 | long ihashsize; | |
0db0015e | 41 | |
e53da348 KM |
42 | ihashsize = roundup((desiredvnodes + 1) * sizeof *ihp / 2, |
43 | NBPG * CLSIZE); | |
44 | ihashtbl = (union ihash *)malloc((u_long)ihashsize, | |
45 | M_UFSMNT, M_WAITOK); | |
46 | for (ihash = 1; ihash <= ihashsize / sizeof *ihp; ihash <<= 1) | |
a6e3920d | 47 | continue; |
e53da348 KM |
48 | ihash = (ihash >> 1) - 1; |
49 | for (ihp = &ihashtbl[ihash]; ihp >= ihashtbl; ihp--) { | |
50 | ihp->ih_head[0] = ihp; | |
51 | ihp->ih_head[1] = ihp; | |
52 | } | |
0db0015e KB |
53 | } |
54 | ||
55 | /* | |
56 | * Use the dev/ino pair to find the incore inode, and return a pointer to it. | |
57 | * If it is in core, but locked, wait for it. | |
58 | */ | |
0e112b75 | 59 | struct vnode * |
0db0015e KB |
60 | ufs_ihashget(dev, ino) |
61 | /* dev_t */ int dev; | |
62 | ino_t ino; | |
63 | { | |
e53da348 | 64 | register union ihash *ihp; |
0db0015e | 65 | register struct inode *ip; |
0e112b75 | 66 | struct vnode *vp; |
0db0015e | 67 | |
e53da348 | 68 | ihp = &ihashtbl[INOHASH(dev, ino)]; |
0db0015e | 69 | loop: |
e53da348 | 70 | for (ip = ihp->ih_forw; ip != (struct inode *)ihp; ip = ip->i_forw) { |
0db0015e KB |
71 | if (ino != ip->i_number || dev != ip->i_dev) |
72 | continue; | |
73 | if ((ip->i_flag & ILOCKED) != 0) { | |
74 | ip->i_flag |= IWANT; | |
75 | sleep((caddr_t)ip, PINOD); | |
76 | goto loop; | |
77 | } | |
0e112b75 KM |
78 | vp = ITOV(ip); |
79 | if (vget(vp)) | |
0db0015e | 80 | goto loop; |
0e112b75 | 81 | return (vp); |
0db0015e KB |
82 | } |
83 | return (NULL); | |
84 | } | |
85 | ||
86 | /* | |
87 | * Insert the inode into the hash table, and return it locked. | |
88 | */ | |
89 | void | |
90 | ufs_ihashins(ip) | |
91 | struct inode *ip; | |
92 | { | |
e53da348 | 93 | insque(ip, &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]); |
0db0015e KB |
94 | ILOCK(ip); |
95 | } |