|
|
1.1 root 1: /*
2: * phase 5 of fsck - Check Free List
3: */
4:
5: #include "fsck.h"
6:
7: daddr_t badcnt; /* Number of bad blocks in free list */
8: daddr_t dupcnt; /* Number of dup blocks in free list */
9: int badflag; /* Bad free list flag */
10: int fixerup; /* Flag to salvage free list */
11:
12: phase5()
13: {
14: struct fblk *fbp;
15: unsigned size;
16:
17: if (!qflag)
18: printf("Phase 5 : Check Free List\n");
19: fbp = (struct fblk *) &sbp->s_nfree;
20: size = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
21: #if SMALLMODEL
22: copyV(size);
23: #else
24: memcpy(dupPtr, blockPtr, size);
25: #endif
26: badcnt = dupcnt = 0;
27: badflag = FALSE;
28: freetrav(fbp);
29: fixerup = FALSE;
30: if (badflag || sflag)
31: asksalvage();
32: }
33:
34:
35: #define IGNORE 3 /* Return Possibilities from chk() */
36: #define ABORT 4 /* as well as perhaps GOOD and BAD */
37:
38: freetrav(fbp)
39: struct fblk *fbp;
40: {
41: daddr_t total=0;
42: int i, flag;
43:
44: while ( fbp->df_nfree != 0 ) {
45: if ( (unsigned) fbp->df_nfree > NICFREE ) {
46: badflag = TRUE;
47: printf("Bad freeblock count.\n");
48: break;
49: }
50: for (i=1; i<fbp->df_nfree; i++) {
51: if ( (flag=chk(fbp->df_free[i])) == GOOD ) {
52: total++;
53: continue;
54: }
55: if (flag == BAD)
56: continue;
57: break; /* break for IGNORE or ABORT */
58: }
59: if ( (flag == IGNORE) || (flag == ABORT) )
60: break;
61: if ( chk(fbp->df_free[0]) != GOOD )
62: break;
63: total++;
64: bread(fbp->df_free[0], databuf);
65: fbp = (struct fblk *) databuf;
66: if ( !canfblk(fbp) ) {
67: badflag = TRUE;
68: printf("Bad freeblock count.\n");
69: break;
70: }
71: }
72:
73: #if 0
74: printf("Total traversed free blocks = %U\n", total);
75: printf("Total free blocks by Superblock = %U\n", sbp->s_tfree);
76: printf("Running total free blocks = %U\n", totfree);
77: #endif
78:
79: if ( flag == ABORT ) { /* To Terminate fsck on this */
80: badflag = FALSE; /* File System, because of */
81: return; /* excessive dup or bad blocks */
82: }
83:
84: if ( sbp->s_tfree != totfree )
85: if ( (qflag==FALSE) && (daction!=NO) ) {
86: printf("Free Block count wrong in superblock. ");
87: if ( action(fixit) == TRUE ) {
88: sbp->s_tfree = totfree;
89: sbpfix = TRUE;
90: }
91: } else {
92: sbp->s_tfree = totfree;
93: sbpfix = TRUE;
94: }
95:
96: report("%U Bad Block%s in Free List\n", badcnt);
97: report("%U Dup Block%s in Free List\n", dupcnt);
98: report("%U Block%s missing\n", totfree - total);
99:
100: }
101:
102: report(message, num)
103: char *message;
104: daddr_t num;
105: {
106: if ( num != 0 ) {
107: printf(message, num, ( (num>1) ? "s" : "" ) );
108: badflag = TRUE;
109: }
110: }
111:
112: chk(bn)
113: register daddr_t bn;
114: {
115: if ( (bn<isize) || (bn>=fsize) ) {
116: badflag = TRUE;
117: if (++badcnt > MAXBADFREE)
118: return( stopit("bad") );
119: return(BAD);
120: }
121:
122: if ( testdup(bn) ) {
123: badflag = TRUE;
124: if (++dupcnt > MAXDUPFREE)
125: return( stopit("dup") );
126: return(BAD);
127: } else {
128: markdup(bn);
129: return(GOOD);
130: }
131: }
132:
133: stopit(type)
134: char *type;
135: {
136: printf("Excessive %s blocks in free list ", type);
137: if ( query("(Continue)") == YES )
138: return(IGNORE);
139: else
140: return(ABORT);
141: }
142:
143:
144: canfblk(fbp)
145: register struct fblk *fbp;
146: {
147: register short i;
148:
149: canshort(fbp->df_nfree);
150: if ( (unsigned) fbp->df_nfree > NICFREE )
151: return(FALSE);
152:
153: for (i=0; i<fbp->df_nfree; i++)
154: candaddr(fbp->df_free[i]);
155: return(TRUE);
156: }
157:
158: asksalvage()
159: {
160: if ( (daction!=NO) && (qflag || sflag) ) {
161: fixerup = TRUE;
162: return;
163: }
164: if ( action("Bad Free List (SALVAGE)") )
165: fixerup = TRUE;
166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.