|
|
1.1 root 1: static char *sccsid = "@(#)dumptraverse.c 1.15 (Berkeley) 9/25/83";
2:
3: #include "dump.h"
4:
5: pass(fn, map)
6: int (*fn)();
7: char *map;
8: {
9: struct dinode *dp;
10: int bits;
11: ino_t maxino;
12:
13: maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
14: for (ino = 0; ino < maxino; ) {
15: if((ino % NBBY) == 0) {
16: bits = ~0;
17: if(map != NULL)
18: bits = *map++;
19: }
20: ino++;
21: if(bits & 1) {
22: dp = getino(ino);
23: (*fn)(dp);
24: }
25: bits >>= 1;
26: }
27: }
28:
29: mark(ip)
30: struct dinode *ip;
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);
40: if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
41: !BIT(ino, nodmap)) {
42: BIS(ino, nodmap);
43: if (f != IFREG && f != IFDIR && f != IFLNK) {
44: esize += 1;
45: return;
46: }
47: est(ip);
48: }
49: }
50:
51: add(ip)
52: register struct dinode *ip;
53: {
54: register int i;
55: long filesize;
56:
57: if(BIT(ino, nodmap))
58: return;
59: nsubdir = 0;
60: dadded = 0;
61: filesize = ip->di_size;
62: for (i = 0; i < NDADDR; i++) {
63: if (ip->di_db[i] != 0)
64: dsrch(ip->di_db[i], dblksize(sblock, ip, i), filesize);
65: filesize -= sblock->fs_bsize;
66: }
67: for (i = 0; i < NIADDR; i++) {
68: if (ip->di_ib[i] != 0)
69: indir(ip->di_ib[i], i, &filesize);
70: }
71: if(dadded) {
72: nadded++;
73: if (!BIT(ino, nodmap)) {
74: BIS(ino, nodmap);
75: est(ip);
76: }
77: }
78: if(nsubdir == 0)
79: if(!BIT(ino, nodmap))
80: BIC(ino, dirmap);
81: }
82:
83: indir(d, n, filesize)
84: daddr_t d;
85: int n, *filesize;
86: {
87: register i;
88: daddr_t idblk[MAXNINDIR];
89:
90: bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize);
91: if(n <= 0) {
92: for(i=0; i < NINDIR(sblock); i++) {
93: d = idblk[i];
94: if(d != 0)
95: dsrch(d, sblock->fs_bsize, *filesize);
96: *filesize -= sblock->fs_bsize;
97: }
98: } else {
99: n--;
100: for(i=0; i < NINDIR(sblock); i++) {
101: d = idblk[i];
102: if(d != 0)
103: indir(d, n, filesize);
104: }
105: }
106: }
107:
108: dump(ip)
109: struct dinode *ip;
110: {
111: register int i;
112: long size;
113:
114: if(newtape) {
115: newtape = 0;
116: bitmap(nodmap, TS_BITS);
117: }
118: BIC(ino, nodmap);
119: spcl.c_dinode = *ip;
120: spcl.c_type = TS_INODE;
121: spcl.c_count = 0;
122: i = ip->di_mode & IFMT;
123: if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) {
124: spclrec();
125: return;
126: }
127: if (ip->di_size > NDADDR * sblock->fs_bsize)
128: i = NDADDR * sblock->fs_frag;
129: else
130: i = howmany(ip->di_size, sblock->fs_fsize);
131: blksout(&ip->di_db[0], i);
132: size = ip->di_size - NDADDR * sblock->fs_bsize;
133: if (size <= 0)
134: return;
135: for (i = 0; i < NIADDR; i++) {
136: dmpindir(ip->di_ib[i], i, &size);
137: if (size <= 0)
138: return;
139: }
140: }
141:
142: dmpindir(blk, lvl, size)
143: daddr_t blk;
144: int lvl;
145: long *size;
146: {
147: int i, cnt;
148: daddr_t idblk[MAXNINDIR];
149:
150: if (blk != 0)
151: bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
152: else
153: bzero(idblk, sblock->fs_bsize);
154: if (lvl <= 0) {
155: if (*size < NINDIR(sblock) * sblock->fs_bsize)
156: cnt = howmany(*size, sblock->fs_fsize);
157: else
158: cnt = NINDIR(sblock) * sblock->fs_frag;
159: *size -= NINDIR(sblock) * sblock->fs_bsize;
160: blksout(&idblk[0], cnt);
161: return;
162: }
163: lvl--;
164: for (i = 0; i < NINDIR(sblock); i++) {
165: dmpindir(idblk[i], lvl, size);
166: if (*size <= 0)
167: return;
168: }
169: }
170:
171: blksout(blkp, frags)
172: daddr_t *blkp;
173: int frags;
174: {
175: int i, j, count, blks, tbperdb;
176:
177: blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
178: tbperdb = sblock->fs_bsize / TP_BSIZE;
179: for (i = 0; i < blks; i += TP_NINDIR) {
180: if (i + TP_NINDIR > blks)
181: count = blks;
182: else
183: count = i + TP_NINDIR;
184: for (j = i; j < count; j++)
185: if (blkp[j / tbperdb] != 0)
186: spcl.c_addr[j - i] = 1;
187: else
188: spcl.c_addr[j - i] = 0;
189: spcl.c_count = count - i;
190: spclrec();
191: for (j = i; j < count; j += tbperdb)
192: if (blkp[j / tbperdb] != 0)
193: if (j + tbperdb <= count)
194: dmpblk(blkp[j / tbperdb],
195: sblock->fs_bsize);
196: else
197: dmpblk(blkp[j / tbperdb],
198: (count - j) * TP_BSIZE);
199: spcl.c_type = TS_ADDR;
200: }
201: }
202:
203: bitmap(map, typ)
204: char *map;
205: {
206: register i, n;
207: char *cp;
208:
209: n = -1;
210: for (i = 0; i < msiz; i++)
211: if(map[i])
212: n = i;
213: if (n < 0)
214: return;
215: n++;
216: spcl.c_type = typ;
217: spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
218: spclrec();
219: for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
220: taprec(cp);
221: }
222:
223: spclrec()
224: {
225: register int s, i, *ip;
226:
227: spcl.c_inumber = ino;
228: spcl.c_magic = NFS_MAGIC;
229: spcl.c_checksum = 0;
230: ip = (int *)&spcl;
231: s = 0;
232: for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
233: s += *ip++;
234: spcl.c_checksum = CHECKSUM - s;
235: taprec((char *)&spcl);
236: }
237:
238: dsrch(d, size, filesize)
239: daddr_t d;
240: int size, filesize;
241: {
242: register struct direct *dp;
243: long loc;
244: char dblk[MAXBSIZE];
245:
246: if(dadded)
247: return;
248: if (filesize > size)
249: filesize = size;
250: bread(fsbtodb(sblock, d), dblk, filesize);
251: for (loc = 0; loc < filesize; ) {
252: dp = (struct direct *)(dblk + loc);
253: if (dp->d_reclen == 0) {
254: msg("corrupted directory, inumber %d\n", ino);
255: break;
256: }
257: loc += dp->d_reclen;
258: if(dp->d_ino == 0)
259: continue;
260: if(dp->d_name[0] == '.') {
261: if(dp->d_name[1] == '\0')
262: continue;
263: if(dp->d_name[1] == '.' && dp->d_name[2] == '\0')
264: continue;
265: }
266: if(BIT(dp->d_ino, nodmap)) {
267: dadded++;
268: return;
269: }
270: if(BIT(dp->d_ino, dirmap))
271: nsubdir++;
272: }
273: }
274:
275: struct dinode *
276: getino(ino)
277: daddr_t ino;
278: {
279: static daddr_t minino, maxino;
280: static struct dinode itab[MAXINOPB];
281:
282: if (ino >= minino && ino < maxino) {
283: return (&itab[ino - minino]);
284: }
285: bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize);
286: minino = ino - (ino % INOPB(sblock));
287: maxino = minino + INOPB(sblock);
288: return (&itab[ino - minino]);
289: }
290:
291: int breaderrors = 0;
292: #define BREADEMAX 32
293:
294: bread(da, ba, cnt)
295: daddr_t da;
296: char *ba;
297: int cnt;
298: {
299: int n;
300:
301: loop:
302: if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
303: msg("bread: lseek fails\n");
304: }
305: n = read(fi, ba, cnt);
306: if (n == cnt)
307: return;
308: if (da + (cnt / DEV_BSIZE) > fsbtodb(sblock, sblock->fs_size)) {
309: /*
310: * Trying to read the final fragment.
311: *
312: * NB - dump only works in TP_BSIZE blocks, hence
313: * rounds DEV_BSIZE fragments up to TP_BSIZE pieces.
314: * It should be smarter about not actually trying to
315: * read more than it can get, but for the time being
316: * we punt and scale back the read only when it gets
317: * us into trouble. (mkm 9/25/83)
318: */
319: cnt -= DEV_BSIZE;
320: goto loop;
321: }
322: msg("(This should not happen)bread from %s [block %d]: count=%d, got=%d\n",
323: disk, da, cnt, n);
324: if (++breaderrors > BREADEMAX){
325: msg("More than %d block read errors from %d\n",
326: BREADEMAX, disk);
327: broadcast("DUMP IS AILING!\n");
328: msg("This is an unrecoverable error.\n");
329: if (!query("Do you want to attempt to continue?")){
330: dumpabort();
331: /*NOTREACHED*/
332: } else
333: breaderrors = 0;
334: }
335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.