|
|
1.1 root 1: /*
2: * Phase 1b of fsck - Rescan for more Dups
3: */
4:
5: #include "fsck.h"
6:
7: extern int numdup; /* declared in phase1.c */
8:
9: phase1b()
10: {
11: if (!qflag)
12: printf("Phase 1b: Rescan for more Dups\n");
13: buildtable();
14: iscanb();
15: }
16:
17: buildtable()
18: {
19: unsigned cntr=0, numdiff=0;
20: daddr_t bn;
21:
22: while (cntr<totdups) {
23: bn = dupblck[cntr++];
24: if (!testdup(bn)) {
25: markdup(bn);
26: numdiff++;
27: }
28: }
29: totdups = numdiff;
30: }
31:
32: iscanb()
33: {
34: register daddr_t bn;
35: register struct dinode *dip;
36: register ino_t ino;
37: int i;
38:
39: ino = 1;
40:
41: for (bn=INODEI; bn<isize; bn++) {
42: if (testblock(bn)) { /* block is bad via inode 1 */
43: ino += INOPB;
44: continue;
45: }
46: bread(bn, databuf);
47: dip = (struct dinode *) databuf;
48: for (i=0; i<INOPB; i++) {
49: candino(dip);
50: if (inuse(dip) == TRUE)
51: ckblksb(dip, ino);
52: if (totdups == 0)
53: return;
54: ino++;
55: dip++;
56: }
57: }
58: }
59:
60: /*
61: * Check the blocks associated with the given inode to find the
62: * remaining duplicate blocks
63: */
64:
65: ckblksb(dip, ino)
66: register struct dinode *dip;
67: register ino_t ino;
68: {
69: daddr_t addrs[NADDR];
70: int i, lev;
71: int mode;
72:
73: mode = dip->di_mode & IFMT;
74:
75: if ( (mode != IFREG) && (mode != IFDIR) )
76: return;
77:
78: l3tol(addrs, dip->di_addr, NADDR);
79:
80: numdup = 0; /* num dup blocks so far THIS INODE */
81:
82: for(i=0; i<NADDR; i++)
83: for (lev=0; lev<4; lev++)
84: if (i < offsets[lev]) {
85: dblocksb(addrs[i], ino, lev);
86: break;
87: }
88: }
89:
90: /*
91: * Checks recursively the blocks pointed at via
92: * the inode list of blocks. 'bn' is the block number,
93: * 'ino' is the inode referencing it, and 'lev' is the
94: * level 0 == direct ... 3 = triple-indirect
95: */
96:
97: dblocksb(bn, ino, lev)
98: daddr_t bn;
99: ino_t ino;
100: int lev;
101: {
102: char buf[BSIZE];
103: int i;
104: daddr_t *bnptr;
105:
106: if (bn == 0)
107: return(OK);
108:
109: switch ( cdupb(bn, ino) ) {
110: case OK:
111: if (lev--==0)
112: return(OK);
113: bread(bn, buf);
114: bnptr = (long *) buf;
115: for (i=0; i<NBN; i++) {
116: bn = bnptr[i];
117: candaddr(bn);
118: if ( dblocksb(bn, ino, lev) == STOP )
119: return(STOP);
120: }
121: return(OK);
122: case STOP:
123: return(STOP);
124: }
125: }
126:
127: /*
128: * Check the given block number for duplicate reference.
129: */
130:
131: cdupb(bn, ino)
132: daddr_t bn;
133: ino_t ino;
134: {
135: if ( !testdup(bn) )
136: return(OK);
137:
138: totdups--;
139: unmarkdup(bn);
140: if (!fflag)
141: orflags(ino, IBAD_IDUP);
142: printf("Dup Block %U, i-number = %u\n", bn, ino);
143:
144: return(STOP);
145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.