speedups and cleanups
[unix-history] / usr / src / sbin / dump / traverse.c
CommitLineData
38f6cf09 1static char *sccsid = "@(#)traverse.c 1.10 (Berkeley) %G%";
35fb2af5 2
b6407c9d 3#include "dump.h"
35fb2af5
BJ
4
5pass(fn, map)
003a2a9e 6 int (*fn)();
b6407c9d 7 char *map;
35fb2af5 8{
003a2a9e 9 struct dinode *dp;
35fb2af5 10 int bits;
003a2a9e 11 ino_t maxino;
35fb2af5 12
b6407c9d 13 maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
003a2a9e 14 for (ino = 0; ino < maxino; ) {
b6407c9d 15 if((ino % NBBY) == 0) {
003a2a9e
KM
16 bits = ~0;
17 if(map != NULL)
18 bits = *map++;
19 }
20 ino++;
21 if(bits & 1) {
22 dp = getino(ino);
23 (*fn)(dp);
35fb2af5 24 }
003a2a9e 25 bits >>= 1;
35fb2af5
BJ
26 }
27}
28
35fb2af5 29mark(ip)
1a350083 30 struct dinode *ip;
35fb2af5
BJ
31{
32 register f;
33
34 f = ip->di_mode & IFMT;
35 if(f == 0)
36 return;
37 BIS(ino, clrmap);
38 if(f == IFDIR)
39 BIS(ino, dirmap);
b6407c9d
KM
40 if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
41 !BIT(ino, nodmap)) {
35fb2af5 42 BIS(ino, nodmap);
a6b18791 43 if (f != IFREG && f != IFDIR && f != IFLNK) {
35fb2af5
BJ
44 esize += 1;
45 return;
46 }
47 est(ip);
48 }
49}
50
51add(ip)
b6407c9d 52 register struct dinode *ip;
35fb2af5 53{
b6407c9d 54 register int i;
35fb2af5
BJ
55
56 if(BIT(ino, nodmap))
57 return;
58 nsubdir = 0;
59 dadded = 0;
b6407c9d
KM
60 for (i = 0; i < NDADDR; i++) {
61 if (ip->di_db[i] != 0)
62 dsrch(ip->di_db[i], dblksize(sblock, ip, i));
63 }
64 for (i = 0; i < NIADDR; i++) {
65 if (ip->di_ib[i] != 0)
66 indir(ip->di_ib[i], i);
67 }
35fb2af5 68 if(dadded) {
35fb2af5 69 nadded++;
b6407c9d
KM
70 if (!BIT(ino, nodmap)) {
71 BIS(ino, nodmap);
72 est(ip);
73 }
35fb2af5
BJ
74 }
75 if(nsubdir == 0)
76 if(!BIT(ino, nodmap))
77 BIC(ino, dirmap);
78}
79
b6407c9d
KM
80indir(d, n)
81 daddr_t d;
82 int n;
83{
84 register i;
85 daddr_t idblk[MAXNINDIR];
86
87 bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize);
88 if(n <= 0) {
89 for(i=0; i < NINDIR(sblock); i++) {
90 d = idblk[i];
91 if(d != 0)
92 dsrch(d, sblock->fs_bsize);
93 }
94 } else {
95 n--;
96 for(i=0; i < NINDIR(sblock); i++) {
97 d = idblk[i];
98 if(d != 0)
99 indir(d, n);
100 }
101 }
102}
103
35fb2af5 104dump(ip)
1a350083 105 struct dinode *ip;
35fb2af5 106{
1a350083
KM
107 register int i;
108 long size;
35fb2af5
BJ
109
110 if(newtape) {
111 newtape = 0;
112 bitmap(nodmap, TS_BITS);
113 }
114 BIC(ino, nodmap);
115 spcl.c_dinode = *ip;
116 spcl.c_type = TS_INODE;
117 spcl.c_count = 0;
118 i = ip->di_mode & IFMT;
a6b18791 119 if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) {
35fb2af5
BJ
120 spclrec();
121 return;
122 }
b6407c9d
KM
123 if (ip->di_size > NDADDR * sblock->fs_bsize)
124 i = NDADDR * sblock->fs_frag;
1a350083 125 else
b6407c9d 126 i = howmany(ip->di_size, sblock->fs_fsize);
1a350083 127 blksout(&ip->di_db[0], i);
b6407c9d 128 size = ip->di_size - NDADDR * sblock->fs_bsize;
1a350083
KM
129 if (size <= 0)
130 return;
131 for (i = 0; i < NIADDR; i++) {
132 dmpindir(ip->di_ib[i], i, &size);
133 if (size <= 0)
134 return;
135 }
35fb2af5
BJ
136}
137
1a350083
KM
138dmpindir(blk, lvl, size)
139 daddr_t blk;
140 int lvl;
141 long *size;
35fb2af5 142{
1a350083 143 int i, cnt;
b6407c9d 144 daddr_t idblk[MAXNINDIR];
35fb2af5 145
1a350083 146 if (blk != 0)
b6407c9d 147 bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
1a350083 148 else
b6407c9d 149 blkclr(idblk, sblock->fs_bsize);
1a350083 150 if (lvl <= 0) {
b6407c9d
KM
151 if (*size < NINDIR(sblock) * sblock->fs_bsize)
152 cnt = howmany(*size, sblock->fs_fsize);
1a350083 153 else
b6407c9d
KM
154 cnt = NINDIR(sblock) * sblock->fs_frag;
155 *size -= NINDIR(sblock) * sblock->fs_bsize;
1a350083
KM
156 blksout(&idblk[0], cnt);
157 return;
158 }
159 lvl--;
b6407c9d 160 for (i = 0; i < NINDIR(sblock); i++) {
1a350083
KM
161 dmpindir(idblk[i], lvl, size);
162 if (*size <= 0)
163 return;
164 }
165}
166
167blksout(blkp, frags)
168 daddr_t *blkp;
169 int frags;
170{
b6407c9d 171 int i, j, count, blks, tbperdb;
1a350083 172
b6407c9d
KM
173 blks = frags * BLKING(sblock);
174 tbperdb = BLKING(sblock) * sblock->fs_frag;
1a350083
KM
175 for (i = 0; i < blks; i += TP_NINDIR) {
176 if (i + TP_NINDIR > blks)
177 count = blks;
178 else
179 count = i + TP_NINDIR;
180 for (j = i; j < count; j++)
b6407c9d 181 if (blkp[j / tbperdb] != 0)
1a350083
KM
182 spcl.c_addr[j - i] = 1;
183 else
184 spcl.c_addr[j - i] = 0;
185 spcl.c_count = count - i;
186 spclrec();
b6407c9d
KM
187 for (j = i; j < count; j += tbperdb)
188 if (blkp[j / tbperdb] != 0)
189 if (j + tbperdb <= count)
190 dmpblk(blkp[j / tbperdb],
191 sblock->fs_bsize);
1a350083 192 else
b6407c9d 193 dmpblk(blkp[j / tbperdb],
1a350083
KM
194 (count - j) * TP_BSIZE);
195 spcl.c_type = TS_ADDR;
35fb2af5 196 }
35fb2af5
BJ
197}
198
199bitmap(map, typ)
b6407c9d 200 char *map;
35fb2af5
BJ
201{
202 register i, n;
203 char *cp;
204
205 n = -1;
b6407c9d 206 for (i = 0; i < msiz; i++)
35fb2af5
BJ
207 if(map[i])
208 n = i;
b6407c9d 209 if (n < 0)
35fb2af5 210 return;
b6407c9d 211 n++;
35fb2af5 212 spcl.c_type = typ;
b6407c9d 213 spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
35fb2af5 214 spclrec();
b6407c9d 215 for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
35fb2af5 216 taprec(cp);
35fb2af5
BJ
217}
218
219spclrec()
220{
1a350083 221 register int s, i, *ip;
35fb2af5
BJ
222
223 spcl.c_inumber = ino;
75c26040 224 spcl.c_magic = NFS_MAGIC;
35fb2af5
BJ
225 spcl.c_checksum = 0;
226 ip = (int *)&spcl;
227 s = 0;
1a350083 228 for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
35fb2af5
BJ
229 s += *ip++;
230 spcl.c_checksum = CHECKSUM - s;
231 taprec((char *)&spcl);
232}
233
b6407c9d 234dsrch(d, size)
1a350083 235 daddr_t d;
b6407c9d 236 int size;
35fb2af5 237{
b45e25c0
KM
238 register struct direct *dp;
239 long loc;
240 char dblk[MAXBSIZE];
35fb2af5
BJ
241
242 if(dadded)
243 return;
b45e25c0
KM
244 bread(fsbtodb(sblock, d), dblk, size);
245 for (loc = 0; loc < size; ) {
246 dp = (struct direct *)(dblk + loc);
247 if (dp->d_reclen == 0)
248 break;
249 loc += dp->d_reclen;
250 if(dp->d_ino == 0)
35fb2af5 251 continue;
b45e25c0
KM
252 if(dp->d_name[0] == '.') {
253 if(dp->d_name[1] == '\0')
35fb2af5 254 continue;
b45e25c0 255 if(dp->d_name[1] == '.' && dp->d_name[2] == '\0')
35fb2af5
BJ
256 continue;
257 }
b45e25c0 258 if(BIT(dp->d_ino, nodmap)) {
35fb2af5
BJ
259 dadded++;
260 return;
261 }
b45e25c0 262 if(BIT(dp->d_ino, dirmap))
35fb2af5
BJ
263 nsubdir++;
264 }
265}
266
003a2a9e
KM
267struct dinode *
268getino(ino)
269 daddr_t ino;
270{
271 static daddr_t minino, maxino;
b6407c9d 272 static struct dinode itab[MAXINOPB];
003a2a9e
KM
273
274 if (ino >= minino && ino < maxino) {
275 return (&itab[ino - minino]);
276 }
6994bf5d 277 bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize);
b6407c9d
KM
278 minino = ino - (ino % INOPB(sblock));
279 maxino = minino + INOPB(sblock);
003a2a9e
KM
280 return (&itab[ino - minino]);
281}
282
35fb2af5
BJ
283int breaderrors = 0;
284#define BREADEMAX 32
285
286bread(da, ba, c)
287 daddr_t da;
288 char *ba;
289 int c;
290{
291 register n;
292 register regc;
293
b6407c9d 294 if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
35fb2af5
BJ
295 msg("bread: lseek fails\n");
296 }
297 regc = c; /* put c someplace safe; it gets clobbered */
298 n = read(fi, ba, c);
b6407c9d 299 if (n != c || regc != c) {
35fb2af5
BJ
300 msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
301 disk, da, c, regc, &c, n);
302#ifdef ERNIE
303 msg("Notify Robert Henry of this error.\n");
304#endif
305 if (++breaderrors > BREADEMAX){
306 msg("More than %d block read errors from %d\n",
307 BREADEMAX, disk);
308 broadcast("DUMP IS AILING!\n");
309 msg("This is an unrecoverable error.\n");
310 if (!query("Do you want to attempt to continue?")){
311 dumpabort();
312 /*NOTREACHED*/
313 } else
314 breaderrors = 0;
315 }
316 }
317}
318
1a350083
KM
319blkclr(cp, size)
320 char *cp;
321 long size;
322{
323 asm("movc5 $0,(r0),$0,8(ap),*4(ap)");
324}