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 | * |
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 | */ | |
25 | int | |
26 | ffs_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 |
56 | void |
57 | ffs_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 |
88 | void | |
89 | ffs_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 |
126 | int |
127 | ffs_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 |
154 | void |
155 | ffs_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 |
182 | void |
183 | ffs_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 | 214 | int |
8570887c KM |
215 | scanc(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 | 229 | int |
8570887c KM |
230 | skpc(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 | 242 | int |
8570887c KM |
243 | locc(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 |