|
|
1.1 root 1: /*
2: * Perform initialization for phases of fsck
3: */
4: #include "fsck.h"
5: #include <mnttab.h>
6: #include <mtab.h>
7:
8: int fsfd; /* file system file descriptor */
9: int writeflg; /* write ok or read-only flag */
10: daddr_t fsize = SUPERI+1; /* file system size in blocks */
11: /* Allows for read of Super Block */
12: int isize; /* First block not in inode list */
13: daddr_t totfree; /* Running total free block count */
14: unsigned ninodes; /* number of inodes */
15: int numfiles; /* number of files in file system */
16:
17: char superb[BSIZE]; /* Super Block */
18: struct filsys *sbp = superb;
19: int sbpfix; /* flag for super block fixes */
20:
21: int offsets[] = /* table of offsets for the levels */
22: { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */
23: ND+NI+NII+NIII }; /* inode block list */
24:
25: daddr_t dupblck[DUPTBLSIZE]; /* duplicate referenced blocks */
26: int totdups; /* number of dup blocks so far */
27:
28: /*
29: * A small aside is the fact that the link counter table allocates an
30: * unsigned short if !SMALLMODEL, but is in fact only an unsigned char
31: * if SMALLMODEL. As a result, we cannot currently fsck correctly a
32: * filesystem with any inode having more than 255 links if SMALLMODEL.
33: * The reason for this is that the virtual system is heavily designed
34: * to work with byte sized tables, and that's that for now! Anyway,
35: * everybody has a 386 by now!
36: */
37:
38: #if !SMALLMODEL
39: unsigned short *linkPtr;
40: unsigned char *flagptr, *blockPtr, *dupPtr;
41: #endif
42:
43: init()
44: {
45: int mode;
46: struct stat status;
47: unsigned short stmode;
48:
49: mode = (mdaction == NO) ? 0 : 2;
50:
51: if ( (fsfd = open(fsname, mode)) == (-1) ) {
52: mode = 0;
53: if ( (fsfd = open(fsname, mode)) == (-1) ) {
54: nonfatal("Can't open: %s", fsname);
55: return;
56: }
57: }
58:
59: if (mode == 0) {
60: daction = NO;
61: writeflg = FALSE;
62: } else {
63: daction = mdaction;
64: writeflg = TRUE;
65: }
66:
67: printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : "");
68:
69: if ( fstat(fsfd, &status) == (-1) ) {
70: nonfatal("Can't stat: %s", fsname);
71: return;
72: }
73:
74: stmode = status.st_mode & S_IFMT;
75: if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) )
76: switch(query("file is not a block or character device; OK?")){
77: case YES:
78: break;
79: case NO:
80: errflag = TRUE;
81: return;
82: }
83:
84: domount();
85: sbpfix = FALSE;
86: readsuper();
87: checksuper();
88: if ( !errflag )
89: alloctables();
90: }
91:
92: /*
93: * Read in the super block and canonicalize
94: */
95:
96: readsuper()
97: {
98: register int i;
99:
100: bread((daddr_t)SUPERI, superb);
101: sbp = superb;
102:
103: canshort(sbp->s_isize);
104: candaddr(sbp->s_fsize);
105: canshort(sbp->s_nfree);
106: for(i=0; i<NICFREE; i++)
107: candaddr(sbp->s_free[i]);
108: canshort(sbp->s_ninode);
109: for(i=0; i<NICINOD; i++)
110: canino(sbp->s_inode[i]);
111: cantime(sbp->s_time);
112: candaddr(sbp->s_tfree);
113: canino(sbp->s_tinode);
114: canshort(sbp->s_m);
115: canshort(sbp->s_n);
116: canlong(sbp->s_unique);
117:
118: }
119:
120: /*
121: * Check super block for obvious inconsistencies
122: */
123:
124: checksuper()
125: {
126: fsize = sbp->s_fsize;
127: isize = sbp->s_isize;
128: totfree = fsize - isize;
129:
130: if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) {
131: badsuper("Size check: fsize %U isize %u", fsize, isize);
132: errflag = TRUE;
133: }
134:
135: if ( sbp->s_nfree > NICFREE )
136: badsuper("Too large free block count");
137:
138: if ( sbp->s_ninode > NICINOD )
139: badsuper("Too large free i-node count");
140: }
141:
142: /*
143: * Super Block Error Functions
144: */
145: badsuper(x)
146: {
147: printf("%r\n", &x);
148: printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI);
149: }
150:
151: /*
152: * Allocate the necessary buffers for tables
153: */
154: alloctables()
155: {
156: unsigned num, numl;
157:
158: numl = 0;
159: if (!fflag) {
160: ninodes = (unsigned) (isize - INODEI) * INOPB;
161: numl = (unsigned) ninodes;
162: }
163:
164: num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
165: #if SMALLMODEL
166: initV(numl, numl, num, num); /* virtual allocation */
167: #else
168: if (NULL != linkPtr) {
169: free(linkPtr);
170: free(flagPtr);
171: free(blockPtr);
172: free(dupPtr);
173: }
174: linkPtr = calloc(numl, sizeof(unsigned short));
175: flagPtr = calloc(numl, sizeof(unsigned char));
176: blockPtr = calloc(num, sizeof(unsigned char));
177: dupPtr = calloc(num, sizeof(unsigned char));
178: #endif
179: numfiles = /* number of files in the file system */
180: totdups = 0; /* num dup blocks */
181: }
182:
183: /*
184: * domount() checks the files /etc/mnttab and /etc/mtab to find
185: * out where the file system is mounted (if at all). It then
186: * reports where (and when if possible) it was last mounted.
187: */
188: char *mnttab_name = "/etc/mnttab";
189: char *mtab_name = "/etc/mtab";
190: char *bttime_name = "/etc/boottime";
191:
192: domount()
193: {
194: int fd;
195: struct mnttab mnttab;
196: struct mtab mtab;
197: register char *name;
198: struct stat sbuf;
199: time_t boottime;
200: int nothing();
201: char devname[MNTNSIZ+6] = "/dev/";
202:
203: mounted = FALSE;
204: name = fsname; /* strip off all initial */
205: while (*name++ != '\0') ; /* directories in fsname */
206: while ( (*--name != '/') && (name>fsname) ) ;
207: if (*name == '/') name++;
208:
209: if ( stat(bttime_name, &sbuf) == -1 )
210: boottime = (time_t)0;
211: else
212: boottime = sbuf.st_mtime;
213:
214: if ( (fd=open(mnttab_name, 0)) != (-1) ) {
215: while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) )
216: if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) {
217: strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ);
218: devname[MNTNSIZ+5] = '\0';
219: statit(devname, nothing);
220: if (stats.st_rdev != fsysrdev)
221: continue;
222: statit(mnttab.mt_dev, nothing);
223: mounted = (stats.st_dev == fsysrdev);
224: prmnttab(&mnttab, boottime);
225: return;
226: }
227: }
228: if ( (fd=open(mtab_name, 0)) != (-1) ) {
229: while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) )
230: if ( mtab.mt_name[0] && mtab.mt_special[0] ) {
231: strncpy(&devname[5], mtab.mt_special, MNAMSIZ);
232: devname[MNAMSIZ+5] = '\0';
233: statit(devname, nothing);
234: if (stats.st_rdev != fsysrdev)
235: continue;
236: statit(mtab.mt_name, nothing);
237: mounted = (stats.st_dev == fsysrdev);
238: prmtab(&mtab);
239: return;
240: }
241: }
242:
243: if (fsysrdev == rootdev)
244: mounted = TRUE;
245: else
246: mounted = FALSE;
247:
248: }
249:
250: prmnttab(ptr, boottime)
251: struct mnttab *ptr;
252: time_t boottime;
253: {
254: if (mounted) {
255: if (boottime < ptr->mt_time)
256: boottime = ptr->mt_time;
257: printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ,
258: ptr->mt_dev, ctime(&boottime));
259: } else
260: printf("%s unmounted. Last mounted on %.*s -- %s",
261: fsname, MNTNSIZ, ptr->mt_dev,
262: ctime(&ptr->mt_time));
263: }
264:
265:
266: prmtab(ptr)
267: struct mtab *ptr;
268: {
269: if (mounted)
270: printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name);
271: else
272: printf("%s unmounted. Last mounted on %.*s\n", fsname,
273: MNAMSIZ, ptr->mt_name);
274: }
275:
276: nothing()
277: {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.