ROOTINO is in common code
[unix-history] / usr / src / sys / ufs / ffs / ffs_subr.c
CommitLineData
da7c5cc6 1/*
7188ac27
KM
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
da7c5cc6 4 *
b702c21d 5 * %sccs.include.redist.c%
7188ac27 6 *
26c16549 7 * @(#)ffs_subr.c 7.14 (Berkeley) %G%
da7c5cc6 8 */
764e2379 9
764e2379 10#include <sys/param.h>
26c16549
KB
11#include <sys/buf.h>
12#include <sys/vnode.h>
13
14#include <ufs/ufs/quota.h>
15#include <ufs/ufs/inode.h>
4f083fd7 16
26c16549
KB
17#include <ufs/ffs/fs.h>
18#include <ufs/ffs/ffs_extern.h>
19
20/*
21 * Return buffer with the contents of block "offset" from the beginning of
22 * directory "ip". If "res" is non-zero, fill it in with a pointer to the
23 * remaining space in the directory.
24 */
25int
26ffs_blkatoff(ip, offset, res, bpp)
27 struct inode *ip;
28 off_t offset;
29 char **res;
30 struct buf **bpp;
31{
32 register struct fs *fs;
33 struct buf *bp;
34 daddr_t lbn;
35 int bsize, error;
36
37 fs = ip->i_fs;
38 lbn = lblkno(fs, offset);
39 bsize = blksize(fs, ip, lbn);
40
41 *bpp = NULL;
42 if (error = bread(ITOV(ip), lbn, bsize, NOCRED, &bp)) {
43 brelse(bp);
44 return (error);
45 }
46 if (res)
47 *res = bp->b_un.b_addr + blkoff(fs, offset);
48 *bpp = bp;
49 return (0);
50}
764e2379
BJ
51
52/*
53 * Update the frsum fields to reflect addition or deletion
54 * of some frags.
55 */
26c16549
KB
56void
57ffs_fragacct(fs, fragmap, fraglist, cnt)
764e2379
BJ
58 struct fs *fs;
59 int fragmap;
60 long fraglist[];
61 int cnt;
62{
63 int inblk;
64 register int field, subfield;
65 register int siz, pos;
66
67 inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
68 fragmap <<= 1;
69 for (siz = 1; siz < fs->fs_frag; siz++) {
70 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
71 continue;
72 field = around[siz];
73 subfield = inside[siz];
74 for (pos = siz; pos <= fs->fs_frag; pos++) {
75 if ((fragmap & field) == subfield) {
76 fraglist[siz] += cnt;
77 pos += siz;
78 field <<= siz;
79 subfield <<= siz;
80 }
81 field <<= 1;
82 subfield <<= 1;
83 }
84 }
85}
86
26c16549
KB
87#ifdef DIAGNOSTIC
88void
89ffs_checkoverlap(bp, ip)
90 struct buf *bp;
91 struct inode *ip;
92{
93 register struct buf *ebp, *ep;
94 register daddr_t start, last;
95 struct vnode *vp;
96
97 ebp = &buf[nbuf];
98 start = bp->b_blkno;
99 last = start + btodb(bp->b_bcount) - 1;
100 for (ep = buf; ep < ebp; ep++) {
101 if (ep == bp || (ep->b_flags & B_INVAL) ||
102 ep->b_vp == NULLVP)
103 continue;
104 if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0))
105 continue;
106 if (vp != ip->i_devvp)
107 continue;
108 /* look for overlap */
109 if (ep->b_bcount == 0 || ep->b_blkno > last ||
110 ep->b_blkno + btodb(ep->b_bcount) <= start)
111 continue;
112 vprint("Disk overlap", vp);
113 (void)printf("\tstart %d, end %d overlap start %d, end %d\n",
114 start, last, ep->b_blkno,
115 ep->b_blkno + btodb(ep->b_bcount) - 1);
116 panic("Disk buffer overlap");
117 }
118}
119#endif /* DIAGNOSTIC */
120
764e2379
BJ
121/*
122 * block operations
123 *
124 * check if a block is available
125 */
26c16549
KB
126int
127ffs_isblock(fs, cp, h)
764e2379
BJ
128 struct fs *fs;
129 unsigned char *cp;
130 daddr_t h;
131{
132 unsigned char mask;
133
cae611dc 134 switch ((int)fs->fs_frag) {
764e2379
BJ
135 case 8:
136 return (cp[h] == 0xff);
137 case 4:
138 mask = 0x0f << ((h & 0x1) << 2);
139 return ((cp[h >> 1] & mask) == mask);
140 case 2:
141 mask = 0x03 << ((h & 0x3) << 1);
142 return ((cp[h >> 2] & mask) == mask);
143 case 1:
144 mask = 0x01 << (h & 0x7);
145 return ((cp[h >> 3] & mask) == mask);
146 default:
26c16549 147 panic("ffs_isblock");
764e2379
BJ
148 }
149}
150
151/*
152 * take a block out of the map
153 */
26c16549
KB
154void
155ffs_clrblock(fs, cp, h)
764e2379 156 struct fs *fs;
39d536e6 157 u_char *cp;
764e2379
BJ
158 daddr_t h;
159{
160
cae611dc 161 switch ((int)fs->fs_frag) {
764e2379
BJ
162 case 8:
163 cp[h] = 0;
164 return;
165 case 4:
166 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
167 return;
168 case 2:
169 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
170 return;
171 case 1:
172 cp[h >> 3] &= ~(0x01 << (h & 0x7));
173 return;
174 default:
26c16549 175 panic("ffs_clrblock");
764e2379
BJ
176 }
177}
178
179/*
180 * put a block into the map
181 */
26c16549
KB
182void
183ffs_setblock(fs, cp, h)
764e2379
BJ
184 struct fs *fs;
185 unsigned char *cp;
186 daddr_t h;
187{
188
cae611dc 189 switch ((int)fs->fs_frag) {
764e2379
BJ
190
191 case 8:
192 cp[h] = 0xff;
193 return;
194 case 4:
195 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
196 return;
197 case 2:
198 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
199 return;
200 case 1:
201 cp[h >> 3] |= (0x01 << (h & 0x7));
202 return;
203 default:
26c16549 204 panic("ffs_setblock");
764e2379
BJ
205 }
206}
4f083fd7 207
081319d0
KM
208#if (!defined(vax) && !defined(tahoe) && !defined(hp300)) \
209 || defined(VAX630) || defined(VAX650)
8570887c 210/*
fb1db32c
MK
211 * C definitions of special instructions.
212 * Normally expanded with inline.
8570887c 213 */
26c16549 214int
8570887c
KM
215scanc(size, cp, table, mask)
216 u_int size;
217 register u_char *cp, table[];
218 register u_char mask;
219{
220 register u_char *end = &cp[size];
221
222 while (cp < end && (table[*cp] & mask) == 0)
223 cp++;
224 return (end - cp);
225}
ac3e1f5c 226#endif
ac3e1f5c 227
081319d0 228#if !defined(vax) && !defined(tahoe) && !defined(hp300)
26c16549 229int
8570887c
KM
230skpc(mask, size, cp)
231 register u_char mask;
232 u_int size;
233 register u_char *cp;
234{
235 register u_char *end = &cp[size];
236
237 while (cp < end && *cp == mask)
238 cp++;
239 return (end - cp);
240}
241
26c16549 242int
8570887c
KM
243locc(mask, size, cp)
244 register u_char mask;
245 u_int size;
246 register u_char *cp;
247{
248 register u_char *end = &cp[size];
249
250 while (cp < end && *cp != mask)
251 cp++;
252 return (end - cp);
253}
fb1db32c 254#endif