1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #if !defined(lint) && defined(DOSCCS)
8: static char sccsid[] = "@(#)pass5.c 5.2 (Berkeley) 3/5/86";
9: #endif not lint
10:
11: #include <sys/param.h>
12: #include <sys/inode.h>
13: #include <sys/fs.h>
14: #include "fsck.h"
15:
16: pass5()
17: {
18: struct inodesc idesc;
19: daddr_t blkno;
20: int n;
21: BUFAREA *bp1, *bp2;
22: extern int debug;
23:
24: bzero(&idesc, sizeof (idesc));
25: idesc.id_type = ADDR;
26:
27: if(sflag)
28: fixfree = 1;
29: else {
30: ifreechk();
31: if(freemap)
32: bcopy(blockmap, freemap, (int)bmapsz);
33: else {
34: for(blkno = 0; blkno < fmapblk-bmapblk; blkno++) {
35: bp1 = getblk((BUFAREA *)NULL,blkno+bmapblk);
36: bp2 = getblk((BUFAREA *)NULL,blkno+fmapblk);
37: bcopy(bp1->b_un.b_buf,bp2->b_un.b_buf,DEV_BSIZE);
38: dirty(bp2);
39: }
40: }
41: badblk = dupblk = 0;
42: freeblk.df_nfree = sblock.fs_nfree;
43: for(n = 0; n < NICFREE; n++)
44: freeblk.df_free[n] = sblock.fs_free[n];
45: freechk();
46: if(badblk)
47: pfatal("%d BAD BLKS IN FREE LIST\n",badblk);
48: if(dupblk)
49: pwarn("%d DUP BLKS IN FREE LIST\n",dupblk);
50: if (debug)
51: printf("n_files %ld n_blks %ld n_free %ld fmax %ld fmin %ld ninode: %u\n",
52: n_files, n_blks, n_free, fmax, fmin,sblock.fs_ninode);
53: if(fixfree == 0) {
54: if ((n_blks+n_free) != (fmax-fmin) &&
55: dofix(&idesc, "BLK(S) MISSING"))
56: fixfree = 1;
57: else if (n_free != sblock.fs_tfree &&
58: dofix(&idesc,"FREE BLK COUNT WRONG IN SUPERBLOCK")) {
59: sblock.fs_tfree = n_free;
60: sbdirty();
61: }
62: }
63: if(fixfree && !dofix(&idesc, "BAD FREE LIST"))
64: fixfree = 0;
65: }
66:
67: if(fixfree) {
68: if (preen == 0)
69: printf("** Phase 6 - Salvage Free List\n");
70: makefree();
71: n_free = sblock.fs_tfree;
72: sblock.fs_ronly = 0;
73: sblock.fs_fmod = 0;
74: sbdirty();
75: }
76: }
77:
78: ifreechk() {
79: register int i;
80: ino_t inum;
81:
82: for (i=0; i<sblock.fs_ninode; i++) {
83: inum = sblock.fs_inode[i];
84: switch (getstate(inum)) {
85:
86: case USTATE:
87: continue;
88: default:
89: pwarn("ALLOCATED INODE(S) IN IFREE LIST");
90: if (preen)
91: printf(" (FIXED)\n");
92: if (preen || reply("FIX") == 1) {
93: sblock.fs_ninode = i-1;
94: sbdirty();
95: }
96: return;
97: }
98: }
99: }
100:
101: freechk()
102: {
103: register daddr_t *ap;
104:
105: if(freeblk.df_nfree == 0)
106: return;
107: do {
108: if(freeblk.df_nfree <= 0 || freeblk.df_nfree > NICFREE) {
109: pfatal("BAD FREEBLK COUNT");
110: printf("\n");
111: fixfree = 1;
112: return;
113: }
114: ap = &freeblk.df_free[freeblk.df_nfree];
115: while(--ap > &freeblk.df_free[0]) {
116: if(pass5check(*ap) == STOP)
117: return;
118: }
119: if(*ap == (daddr_t)0 || pass5check(*ap) != KEEPON)
120: return;
121: } while(getblk(&fileblk,*ap) != NULL);
122: }
123:
124:
125: makefree()
126: {
127: register i, cyl, step;
128: int j;
129: char flg[MAXCYL];
130: short addr[MAXCYL];
131: daddr_t blk, baseblk;
132:
133: sblock.fs_nfree = 0;
134: sblock.fs_flock = 0;
135: sblock.fs_fmod = 0;
136: sblock.fs_tfree = 0;
137: sblock.fs_ninode = 0;
138: sblock.fs_ilock = 0;
139: sblock.fs_ronly = 0;
140: if(cylsize == 0 || stepsize == 0) {
141: step = sblock.fs_step;
142: cyl = sblock.fs_cyl;
143: }
144: else {
145: step = stepsize;
146: cyl = cylsize;
147: }
148: if(step > cyl || step <= 0 || cyl <= 0 || cyl > MAXCYL) {
149: printf("Default free list spacing assumed\n");
150: step = STEPSIZE;
151: cyl = CYLSIZE;
152: }
153: sblock.fs_step = step;
154: sblock.fs_cyl = cyl;
155: bzero(flg,sizeof(flg));
156: i = 0;
157: for(j = 0; j < cyl; j++) {
158: while(flg[i])
159: i = (i + 1) % cyl;
160: addr[j] = i + 1;
161: flg[i]++;
162: i = (i + step) % cyl;
163: }
164: baseblk = (daddr_t)roundup(fmax,cyl);
165: bzero((char *)&freeblk,DEV_BSIZE);
166: freeblk.df_nfree++;
167: for( ; baseblk > 0; baseblk -= cyl)
168: for(i = 0; i < cyl; i++) {
169: blk = baseblk - addr[i];
170: if(!outrange(blk) && !getbmap(blk)) {
171: sblock.fs_tfree++;
172: if(freeblk.df_nfree >= NICFREE) {
173: fbdirty();
174: fileblk.b_bno = blk;
175: flush(&dfile,&fileblk);
176: bzero((char *)&freeblk,DEV_BSIZE);
177: }
178: freeblk.df_free[freeblk.df_nfree] = blk;
179: freeblk.df_nfree++;
180: }
181: }
182: sblock.fs_nfree = freeblk.df_nfree;
183: for(i = 0; i < NICFREE; i++)
184: sblock.fs_free[i] = freeblk.df_free[i];
185: sbdirty();
186: }
187:
188: pass5check(blk)
189: daddr_t blk;
190: {
191: if(outrange(blk)) {
192: fixfree = 1;
193: if (preen)
194: pfatal("BAD BLOCKS IN FREE LIST.");
195: if(++badblk >= MAXBAD) {
196: printf("EXCESSIVE BAD BLKS IN FREE LIST.");
197: if(reply("CONTINUE") == 0)
198: errexit("");
199: return(STOP);
200: }
201: return(SKIP);
202: }
203: if(getfmap(blk)) {
204: fixfree = 1;
205: if(++dupblk >= DUPTBLSIZE) {
206: printf("EXCESSIVE DUP BLKS IN FREE LIST.");
207: if(reply("CONTINUE") == 0)
208: errexit("");
209: return(STOP);
210: }
211: }
212: else {
213: n_free++;
214: setfmap(blk);
215: }
216: return(KEEPON);
217: }
Defined functions
pass5
defined in line
16; used 1 times
Defined variables
sccsid
defined in line
8;
never used