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