zero out usec fields (from Rick Macklem)
[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 *
7188ac27
KM
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * @(#)ffs_subr.c 7.8 (Berkeley) %G%
da7c5cc6 18 */
764e2379
BJ
19
20#ifdef KERNEL
94368568
JB
21#include "param.h"
22#include "systm.h"
94368568 23#include "buf.h"
7188ac27 24#include "time.h"
94368568 25#include "kernel.h"
7188ac27
KM
26#include "file.h"
27#include "mount.h"
28#include "vnode.h"
29#include "../ufs/inode.h"
30#include "../ufs/ufsmount.h"
31#include "../ufs/fs.h"
32#include "../ufs/quota.h"
764e2379
BJ
33#else
34#include <sys/param.h>
4f083fd7 35#include <sys/systm.h>
4f083fd7 36#include <sys/buf.h>
7188ac27
KM
37#include <sys/time.h>
38#include <sys/file.h>
39#include <sys/mount.h>
40#include <sys/vnode.h>
41#include <ufs/inode.h>
42#include <ufs/ufsmount.h>
43#include <ufs/fs.h>
44#include <ufs/quota.h>
4f083fd7
SL
45#endif
46
47#ifdef KERNEL
4f083fd7
SL
48/*
49 * Flush all the blocks associated with an inode.
9a5e5086
KM
50 * There are two strategies based on the size of the file;
51 * large files are those with more than (nbuf / 2) blocks.
52 * Large files
53 * Walk through the buffer pool and push any dirty pages
54 * associated with the device on which the file resides.
55 * Small files
56 * Look up each block in the file to see if it is in the
57 * buffer pool writing any that are found to disk.
58 * Note that we make a more stringent check of
59 * writing out any block in the buffer pool that may
60 * overlap the inode. This brings the inode up to
61 * date with recent mods to the cooked device.
4f083fd7
SL
62 */
63syncip(ip)
64 register struct inode *ip;
65{
66 register struct fs *fs;
9a5e5086
KM
67 register struct buf *bp;
68 struct buf *lastbufp;
a5e62f37 69 long lbn, lastlbn;
7188ac27 70 int s, error, allerror = 0;
4f083fd7
SL
71 daddr_t blkno;
72
73 fs = ip->i_fs;
74 lastlbn = howmany(ip->i_size, fs->fs_bsize);
9a5e5086 75 if (lastlbn < nbuf / 2) {
ec67a3ce
MK
76#ifdef SECSIZE
77 lastlbn--;
78 s = fsbtodb(fs, fs->fs_frag);
79 for (lbn = 0; lbn < lastlbn; lbn++) {
7188ac27
KM
80 error = bmap(ip, lbn, &blkno, (daddr_t *)0, (int *)0);
81 if (error)
82 allerror = error;
83 if (error = blkflush(ip->i_devvp, blkno,
84 blksize(fs, ip, lbn)))
85 allerror = error;
9a5e5086 86 }
ec67a3ce 87#endif SECSIZE
9a5e5086
KM
88 } else {
89 lastbufp = &buf[nbuf];
90 for (bp = buf; bp < lastbufp; bp++) {
91 if (bp->b_dev != ip->i_dev ||
92 (bp->b_flags & B_DELWRI) == 0)
93 continue;
a5e62f37 94 s = splbio();
9a5e5086
KM
95 if (bp->b_flags & B_BUSY) {
96 bp->b_flags |= B_WANTED;
97 sleep((caddr_t)bp, PRIBIO+1);
98 splx(s);
99 bp--;
100 continue;
101 }
102 splx(s);
103 notavail(bp);
7188ac27
KM
104 if (error = bwrite(bp))
105 allerror = error;
9a5e5086 106 }
4f083fd7 107 }
7188ac27
KM
108 if (error = iupdat(ip, &time, &time, 1))
109 allerror = error;
110 return (allerror);
4f083fd7 111}
7188ac27 112#endif KERNEL
764e2379
BJ
113
114extern int around[9];
115extern int inside[9];
116extern u_char *fragtbl[];
117
118/*
119 * Update the frsum fields to reflect addition or deletion
120 * of some frags.
121 */
122fragacct(fs, fragmap, fraglist, cnt)
123 struct fs *fs;
124 int fragmap;
125 long fraglist[];
126 int cnt;
127{
128 int inblk;
129 register int field, subfield;
130 register int siz, pos;
131
132 inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
133 fragmap <<= 1;
134 for (siz = 1; siz < fs->fs_frag; siz++) {
135 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
136 continue;
137 field = around[siz];
138 subfield = inside[siz];
139 for (pos = siz; pos <= fs->fs_frag; pos++) {
140 if ((fragmap & field) == subfield) {
141 fraglist[siz] += cnt;
142 pos += siz;
143 field <<= siz;
144 subfield <<= siz;
145 }
146 field <<= 1;
147 subfield <<= 1;
148 }
149 }
150}
151
152#ifdef KERNEL
153/*
154 * Check that a specified block number is in range.
155 */
156badblock(fs, bn)
157 register struct fs *fs;
158 daddr_t bn;
159{
160
161 if ((unsigned)bn >= fs->fs_size) {
162 printf("bad block %d, ", bn);
163 fserr(fs, "bad block");
164 return (1);
165 }
166 return (0);
167}
168#endif
169
170/*
171 * block operations
172 *
173 * check if a block is available
174 */
175isblock(fs, cp, h)
176 struct fs *fs;
177 unsigned char *cp;
178 daddr_t h;
179{
180 unsigned char mask;
181
cae611dc 182 switch ((int)fs->fs_frag) {
764e2379
BJ
183 case 8:
184 return (cp[h] == 0xff);
185 case 4:
186 mask = 0x0f << ((h & 0x1) << 2);
187 return ((cp[h >> 1] & mask) == mask);
188 case 2:
189 mask = 0x03 << ((h & 0x3) << 1);
190 return ((cp[h >> 2] & mask) == mask);
191 case 1:
192 mask = 0x01 << (h & 0x7);
193 return ((cp[h >> 3] & mask) == mask);
194 default:
195 panic("isblock");
196 return (NULL);
197 }
198}
199
200/*
201 * take a block out of the map
202 */
203clrblock(fs, cp, h)
204 struct fs *fs;
39d536e6 205 u_char *cp;
764e2379
BJ
206 daddr_t h;
207{
208
cae611dc 209 switch ((int)fs->fs_frag) {
764e2379
BJ
210 case 8:
211 cp[h] = 0;
212 return;
213 case 4:
214 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
215 return;
216 case 2:
217 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
218 return;
219 case 1:
220 cp[h >> 3] &= ~(0x01 << (h & 0x7));
221 return;
222 default:
223 panic("clrblock");
224 }
225}
226
227/*
228 * put a block into the map
229 */
230setblock(fs, cp, h)
231 struct fs *fs;
232 unsigned char *cp;
233 daddr_t h;
234{
235
cae611dc 236 switch ((int)fs->fs_frag) {
764e2379
BJ
237
238 case 8:
239 cp[h] = 0xff;
240 return;
241 case 4:
242 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
243 return;
244 case 2:
245 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
246 return;
247 case 1:
248 cp[h >> 3] |= (0x01 << (h & 0x7));
249 return;
250 default:
251 panic("setblock");
252 }
253}
4f083fd7
SL
254
255#ifdef KERNEL
256/*
257 * Getfs maps a device number into a pointer to the incore super block.
258 *
259 * The algorithm is a linear search through the mount table. A
260 * consistency check of the super block magic number is performed.
3649dfe2 261 * Filesystems still working on a mount are skipped.
4f083fd7
SL
262 *
263 * panic: no fs -- the device is not mounted.
264 * this "cannot happen"
265 */
266struct fs *
267getfs(dev)
268 dev_t dev;
269{
7188ac27 270 register struct ufsmount *mp;
4f083fd7
SL
271 register struct fs *fs;
272
7188ac27
KM
273 for (mp = &mounttab[0]; mp < &mounttab[NMOUNT]; mp++) {
274 if (mp->um_fs == NULL || mp->um_dev != dev ||
275 mp->um_fs == (struct fs *)1) /* XXX */
4f083fd7 276 continue;
7188ac27 277 fs = mp->um_fs;
4f083fd7
SL
278 if (fs->fs_magic != FS_MAGIC) {
279 printf("dev = 0x%x, fs = %s\n", dev, fs->fs_fsmnt);
280 panic("getfs: bad magic");
281 }
282 return (fs);
283 }
284 printf("dev = 0x%x\n", dev);
285 panic("getfs: no fs");
286 return (NULL);
287}
288
289/*
290 * Getfsx returns the index in the file system
291 * table of the specified device. The swap device
292 * is also assigned a pseudo-index. The index may
293 * be used as a compressed indication of the location
294 * of a block, recording
295 * <getfsx(dev),blkno>
296 * rather than
297 * <dev, blkno>
298 * provided the information need remain valid only
299 * as long as the file system is mounted.
300 */
301getfsx(dev)
302 dev_t dev;
303{
7188ac27 304 register struct ufsmount *mp;
4f083fd7
SL
305
306 if (dev == swapdev)
307 return (MSWAPX);
7188ac27
KM
308 for(mp = &mounttab[0]; mp < &mounttab[NMOUNT]; mp++)
309 if (mp->um_dev == dev)
310 return (mp - &mounttab[0]);
4f083fd7
SL
311 return (-1);
312}
4f083fd7 313#endif
8570887c 314
a94023e0 315#if (!defined(vax) && !defined(tahoe)) || defined(VAX630) || defined(VAX650)
8570887c 316/*
fb1db32c
MK
317 * C definitions of special instructions.
318 * Normally expanded with inline.
8570887c
KM
319 */
320scanc(size, cp, table, mask)
321 u_int size;
322 register u_char *cp, table[];
323 register u_char mask;
324{
325 register u_char *end = &cp[size];
326
327 while (cp < end && (table[*cp] & mask) == 0)
328 cp++;
329 return (end - cp);
330}
ac3e1f5c 331#endif
ac3e1f5c 332
fb1db32c 333#if !defined(vax) && !defined(tahoe)
8570887c
KM
334skpc(mask, size, cp)
335 register u_char mask;
336 u_int size;
337 register u_char *cp;
338{
339 register u_char *end = &cp[size];
340
341 while (cp < end && *cp == mask)
342 cp++;
343 return (end - cp);
344}
345
346locc(mask, size, cp)
347 register u_char mask;
348 u_int size;
349 register u_char *cp;
350{
351 register u_char *end = &cp[size];
352
353 while (cp < end && *cp != mask)
354 cp++;
355 return (end - cp);
356}
fb1db32c 357#endif