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