|
|
1.1 root 1: /*
2: * phase 6 of fsck - Salvage Free List
3: */
4:
5: #include "fsck.h"
6:
7: static unsigned char *maptab; /* table of interleave offsets */
8: static daddr_t mapbot; /* minimum block number to interleave map */
9: static daddr_t maptop; /* maximum block number to interleave map */
10: static short m,n; /* interleave factors */
11: #define DEF_N 1 /* default values */
12: #define DEF_M 1
13: daddr_t freeblks; /* number free blocks left to write out */
14: daddr_t blknm; /* current block number we are working with */
15: struct fblk *fblkp; /* pointer to free block list */
16: daddr_t *dp; /* pointer to block entry in free list block */
17:
18: phase6()
19: {
20: if (!fixerup) {
21: return;
22: }
23:
24: if (!qflag)
25: printf("Phase 6 : Salvage Free List\n");
26: if ( maketable() == BAD )
27: return;
28: writefree();
29: free(maptab);
30: }
31:
32: maketable()
33: {
34: register int i;
35: register int ratio;
36:
37: m = sbp->s_m;
38: n = sbp->s_n;
39:
40: if ( (n > MAXINTN) || (m > n) || (n%m != 0) ) {
41: printf("Invalid interleave factors in superblock.\n");
42: printf("Default free-block list spacing assumed.\n");
43: sbp->s_n = n = DEF_N;
44: sbp->s_m = m = DEF_M;
45: }
46:
47: if ( (maptab = malloc(n)) == NULL ) {
48: printf("Can't malloc space for interleave table.\n");
49: printf("Free-block list is not rebuilt.\n");
50: return(BAD);
51: }
52:
53: mapbot = (isize + n - 1)/n*n;
54: maptop = fsize/n*n;
55: ratio = n/m;
56: for (i=0; i<n; i++)
57: maptab[i] = (i/ratio) + (i%ratio)*m;
58:
59: return(GOOD);
60: }
61:
62: writefree()
63: {
64: register daddr_t bn;
65: daddr_t blk, bmap();
66: short num;
67:
68: sbpfix = TRUE;
69: freeblks = totfree;
70: blknm = SUPERI;
71: fblkp = (struct fblk *) &sbp->s_nfree;
72: fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
73: freeblks -= num;
74: dp = &fblkp->df_free[num];
75: for (bn=isize; bn<fsize; bn++) {
76: blk = bmap(bn);
77: if ( !testblock(blk) )
78: if ( addfree(blk) == STOP )
79: break;
80: }
81: }
82:
83: addfree(bn)
84: daddr_t bn;
85: {
86: short num;
87:
88: *--dp = bn;
89: if (dp > &fblkp->df_free[0])
90: return(OK);
91:
92: if ( blknm != SUPERI ) {
93: canwfblk(fblkp);
94: bwrite(blknm, databuf);
95: }
96:
97: bclear(databuf, BSIZE);
98: if (freeblks == 0) {
99: bwrite(bn, databuf);
100: return(STOP);
101: }
102: blknm = bn;
103: fblkp = (struct fblk *) databuf;
104: fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
105: freeblks -= num;
106: dp = &fblkp->df_free[num];
107: return(OK);
108: }
109:
110: daddr_t
111: bmap(blk)
112: register daddr_t blk;
113: {
114: short i;
115:
116: if ( (blk>=mapbot) && (blk<maptop) ) {
117: i = blk%n;
118: blk -= i;
119: blk += maptab[i];
120: }
121: return(blk);
122: }
123:
124: canwfblk(fbp)
125: register struct fblk *fbp;
126: {
127: register short i;
128:
129: for (i=0; i<fbp->df_nfree; i++)
130: candaddr(fbp->df_free[i]);
131: canshort(fbp->df_nfree);
132: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.