Commit | Line | Data |
---|---|---|
184c56be | 1 | static char *sccsid = "@(#)traverse.c 1.12 (Berkeley) %G%"; |
35fb2af5 | 2 | |
b6407c9d | 3 | #include "dump.h" |
35fb2af5 BJ |
4 | |
5 | pass(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 | 29 | mark(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 | ||
51 | add(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 |
80 | indir(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 | 104 | dump(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 |
138 | dmpindir(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 | ||
167 | blksout(blkp, frags) | |
168 | daddr_t *blkp; | |
169 | int frags; | |
170 | { | |
b6407c9d | 171 | int i, j, count, blks, tbperdb; |
1a350083 | 172 | |
184c56be | 173 | blks = howmany(frags * sblock->fs_fsize, TP_BSIZE); |
092ee994 | 174 | tbperdb = sblock->fs_bsize / TP_BSIZE; |
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 | ||
199 | bitmap(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 | ||
219 | spclrec() | |
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 | 234 | dsrch(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 |
267 | struct dinode * |
268 | getino(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 |
283 | int breaderrors = 0; |
284 | #define BREADEMAX 32 | |
285 | ||
286 | bread(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 |
319 | blkclr(cp, size) |
320 | char *cp; | |
321 | long size; | |
322 | { | |
323 | asm("movc5 $0,(r0),$0,8(ap),*4(ap)"); | |
324 | } |