|
|
1.1 root 1: static char *sccsid = "@(#)mkfs.c 4.2 (Berkeley) 4/20/81";
2:
3: /*
4: * Make a file system prototype.
5: * usage: mkfs filsys proto/size [ m n ]
6: */
7: #define NIPB (BSIZE(0)/sizeof(struct dinode))
8: #define NDIRECT (BSIZE(0)/sizeof(struct direct))
9: #define LADDR 10
10: #define MAXFN 1000
11: #define MAXISIZE (65536-NIPB)
12: #ifndef STANDALONE
13: #include <stdio.h>
14: #include <a.out.h>
15: #endif
16: #include <sys/param.h>
17: #include <sys/ino.h>
18: #include <sys/inode.h>
19: #include <sys/filsys.h>
20: #include <sys/fblk.h>
21: #include <sys/dir.h>
22: time_t utime;
23: #ifndef STANDALONE
24: FILE *fin;
25: #else
26: int fin;
27: #endif
28: int fsi;
29: int fso;
30: char *charp;
31: char buf[BSIZE(0)];
32: union {
33: struct fblk fb;
34: char pad1[BSIZE(0)];
35: } fbun;
36: #define fbuf fbun.fb
37: #ifndef STANDALONE
38: struct exec head;
39: #endif
40: char string[50];
41: union {
42: struct filsys fs;
43: char pad2[BSIZE(0)];
44: } fsun;
45: #define filsys fsun.fs
46: char *fsys;
47: char *proto;
48: int f_n = MAXFN;
49: int f_m = 3;
50: int error;
51: ino_t ino;
52: long getnum();
53: daddr_t alloc();
54:
55: main(argc, argv)
56: char *argv[];
57: {
58: int f, c;
59: long n;
60:
61: #ifndef STANDALONE
62: time(&utime);
63: if(argc < 3) {
64: printf("usage: mkfs filsys proto/size [ m n ]\n");
65: exit(1);
66: }
67: fsys = argv[1];
68: proto = argv[2];
69: #else
70: {
71: static char protos[60];
72:
73: printf("file sys size: ");
74: gets(protos);
75: proto = protos;
76: }
77: #endif
78: #ifdef STANDALONE
79: {
80: char fsbuf[100];
81:
82: do {
83: printf("file system: ");
84: gets(fsbuf);
85: fso = open(fsbuf, 1);
86: fsi = open(fsbuf, 0);
87: } while (fso < 0 || fsi < 0);
88: }
89: fin = NULL;
90: argc = 0;
91: #else
92: fso = creat(fsys, 0666);
93: if(fso < 0) {
94: printf("%s: cannot create\n", fsys);
95: exit(1);
96: }
97: fsi = open(fsys, 0);
98: if(fsi < 0) {
99: printf("%s: cannot open\n", fsys);
100: exit(1);
101: }
102: fin = fopen(proto, "r");
103: #endif
104: if(fin == NULL) {
105: n = 0;
106: for(f=0; c=proto[f]; f++) {
107: if(c<'0' || c>'9') {
108: printf("%s: cannot open\n", proto);
109: exit(1);
110: }
111: n = n*10 + (c-'0');
112: }
113: filsys.s_fsize = n;
114: n = n/25;
115: if(n <= 0)
116: n = 1;
117: if(n > MAXISIZE/NIPB)
118: n = MAXISIZE/NIPB;
119: filsys.s_isize = n + 2;
120: printf("isize = %D\n", n*NIPB);
121: charp = "d--777 0 0 $ ";
122: goto f3;
123: }
124:
125: #ifndef STANDALONE
126: /*
127: * get name of boot load program
128: * and read onto block 0
129: */
130:
131: getstr();
132: f = open(string, 0);
133: if(f < 0) {
134: printf("%s: cannot open init\n", string);
135: goto f2;
136: }
137: c = BSIZE(0);
138: /*
139: read(f, (char *)&head, sizeof head);
140: if(head.a_magic != OMAGIC) {
141: printf("%s: bad format\n", string);
142: goto f1;
143: }
144: c = head.a_text + head.a_data;
145: if(c > BSIZE(0)) {
146: printf("%s: too big\n", string);
147: goto f1;
148: }
149: */
150: read(f, buf, c);
151: wtfs((long)0, buf);
152:
153: f1:
154: close(f);
155:
156: /*
157: * get total disk size
158: * and inode block size
159: */
160:
161: f2:
162: filsys.s_fsize = getnum();
163: n = getnum();
164: n /= NIPB;
165: filsys.s_isize = n + 3;
166:
167: #endif
168: f3:
169: if(argc >= 5) {
170: f_m = atoi(argv[3]);
171: f_n = atoi(argv[4]);
172: if(f_n <= 0 || f_n >= MAXFN)
173: f_n = MAXFN;
174: if(f_m <= 0 || f_m > f_n)
175: f_m = 3;
176: }
177: filsys.s_m = f_m;
178: filsys.s_n = f_n;
179: printf("m/n = %d %d\n", f_m, f_n);
180: if(filsys.s_isize >= filsys.s_fsize) {
181: printf("%ld/%ld: bad ratio\n", filsys.s_fsize, filsys.s_isize-2);
182: exit(1);
183: }
184: filsys.s_tfree = 0;
185: filsys.s_tinode = 0;
186: for(c=0; c<BSIZE(0); c++)
187: buf[c] = 0;
188: for(n=2; n!=filsys.s_isize; n++) {
189: wtfs(n, buf);
190: filsys.s_tinode += NIPB;
191: }
192: ino = 0;
193:
194: bflist();
195:
196: cfile((struct inode *)0);
197:
198: filsys.s_time = utime;
199: wtfs((long)1, (char *)&filsys);
200: #ifndef STANDALONE
201: exit(error);
202: #endif
203: }
204:
205: cfile(par)
206: struct inode *par;
207: {
208: struct inode in;
209: int dbc, ibc;
210: char db[BSIZE(0)];
211: daddr_t ib[NINDIR(0)];
212: int i, f, c;
213:
214: /*
215: * get mode, uid and gid
216: */
217:
218: getstr();
219: in.i_mode = gmode(string[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
220: in.i_mode |= gmode(string[1], "-u", 0, ISUID, 0, 0);
221: in.i_mode |= gmode(string[2], "-g", 0, ISGID, 0, 0);
222: for(i=3; i<6; i++) {
223: c = string[i];
224: if(c<'0' || c>'7') {
225: printf("%c/%s: bad octal mode digit\n", c, string);
226: error = 1;
227: c = 0;
228: }
229: in.i_mode |= (c-'0')<<(15-3*i);
230: }
231: in.i_uid = getnum();
232: in.i_gid = getnum();
233:
234: /*
235: * general initialization prior to
236: * switching on format
237: */
238:
239: ino++;
240: in.i_number = ino;
241: for(i=0; i<BSIZE(0); i++)
242: db[i] = 0;
243: for(i=0; i<NINDIR(0); i++)
244: ib[i] = (daddr_t)0;
245: in.i_nlink = 1;
246: in.i_size = 0;
247: for(i=0; i<NADDR; i++)
248: in.i_un.i_addr[i] = (daddr_t)0;
249: if(par == (struct inode *)0) {
250: par = ∈
251: in.i_nlink--;
252: }
253: dbc = 0;
254: ibc = 0;
255: switch(in.i_mode&IFMT) {
256:
257: case IFREG:
258: /*
259: * regular file
260: * contents is a file name
261: */
262:
263: getstr();
264: f = open(string, 0);
265: if(f < 0) {
266: printf("%s: cannot open\n", string);
267: error = 1;
268: break;
269: }
270: while((i=read(f, db, BSIZE(0))) > 0) {
271: in.i_size += i;
272: newblk(&dbc, db, &ibc, ib);
273: }
274: close(f);
275: break;
276:
277: case IFBLK:
278: case IFCHR:
279: /*
280: * special file
281: * content is maj/min types
282: */
283:
284: i = getnum() & 0377;
285: f = getnum() & 0377;
286: in.i_un.i_addr[0] = (i<<8) | f;
287: break;
288:
289: case IFDIR:
290: /*
291: * directory
292: * put in extra links
293: * call recursively until
294: * name of "$" found
295: */
296:
297: par->i_nlink++;
298: in.i_nlink++;
299: entry(in.i_number, ".", &dbc, db, &ibc, ib);
300: entry(par->i_number, "..", &dbc, db, &ibc, ib);
301: in.i_size = 2*sizeof(struct direct);
302: for(;;) {
303: getstr();
304: if(string[0]=='$' && string[1]=='\0')
305: break;
306: entry(ino+1, string, &dbc, db, &ibc, ib);
307: in.i_size += sizeof(struct direct);
308: cfile(&in);
309: }
310: break;
311: }
312: if(dbc != 0)
313: newblk(&dbc, db, &ibc, ib);
314: iput(&in, &ibc, ib);
315: }
316:
317: gmode(c, s, m0, m1, m2, m3)
318: char c, *s;
319: {
320: int i;
321:
322: for(i=0; s[i]; i++)
323: if(c == s[i])
324: return((&m0)[i]);
325: printf("%c/%s: bad mode\n", c, string);
326: error = 1;
327: return(0);
328: }
329:
330: long
331: getnum()
332: {
333: int i, c;
334: long n;
335:
336: getstr();
337: n = 0;
338: i = 0;
339: for(i=0; c=string[i]; i++) {
340: if(c<'0' || c>'9') {
341: printf("%s: bad number\n", string);
342: error = 1;
343: return((long)0);
344: }
345: n = n*10 + (c-'0');
346: }
347: return(n);
348: }
349:
350: getstr()
351: {
352: int i, c;
353:
354: loop:
355: switch(c=getch()) {
356:
357: case ' ':
358: case '\t':
359: case '\n':
360: goto loop;
361:
362: case '\0':
363: printf("EOF\n");
364: exit(1);
365:
366: case ':':
367: while(getch() != '\n');
368: goto loop;
369:
370: }
371: i = 0;
372:
373: do {
374: string[i++] = c;
375: c = getch();
376: } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0');
377: string[i] = '\0';
378: }
379:
380: rdfs(bno, bf)
381: daddr_t bno;
382: char *bf;
383: {
384: int n;
385:
386: lseek(fsi, bno*BSIZE(0), 0);
387: n = read(fsi, bf, BSIZE(0));
388: if(n != BSIZE(0)) {
389: printf("read error: %ld\n", bno);
390: exit(1);
391: }
392: }
393:
394: wtfs(bno, bf)
395: daddr_t bno;
396: char *bf;
397: {
398: int n;
399:
400: lseek(fso, bno*BSIZE(0), 0);
401: n = write(fso, bf, BSIZE(0));
402: if(n != BSIZE(0)) {
403: printf("write error: %D\n", bno);
404: exit(1);
405: }
406: }
407:
408: daddr_t
409: alloc()
410: {
411: int i;
412: daddr_t bno;
413:
414: filsys.s_tfree--;
415: bno = filsys.s_free[--filsys.s_nfree];
416: if(bno == 0) {
417: printf("out of free space\n");
418: exit(1);
419: }
420: if(filsys.s_nfree <= 0) {
421: rdfs(bno, (char *)&fbuf);
422: filsys.s_nfree = fbuf.df_nfree;
423: for(i=0; i<NICFREE; i++)
424: filsys.s_free[i] = fbuf.df_free[i];
425: }
426: return(bno);
427: }
428:
429: bfree(bno)
430: daddr_t bno;
431: {
432: int i;
433:
434: if (bno)
435: filsys.s_tfree++;
436: if(filsys.s_nfree >= NICFREE) {
437: fbuf.df_nfree = filsys.s_nfree;
438: for(i=0; i<NICFREE; i++)
439: fbuf.df_free[i] = filsys.s_free[i];
440: wtfs(bno, (char *)&fbuf);
441: filsys.s_nfree = 0;
442: }
443: filsys.s_free[filsys.s_nfree++] = bno;
444: }
445:
446: entry(inum, str, adbc, db, aibc, ib)
447: ino_t inum;
448: char *str;
449: int *adbc, *aibc;
450: char *db;
451: daddr_t *ib;
452: {
453: struct direct *dp;
454: int i;
455:
456: dp = (struct direct *)db;
457: dp += *adbc;
458: (*adbc)++;
459: dp->d_ino = inum;
460: for(i=0; i<DIRSIZ; i++)
461: dp->d_name[i] = 0;
462: for(i=0; i<DIRSIZ; i++)
463: if((dp->d_name[i] = str[i]) == 0)
464: break;
465: if(*adbc >= NDIRECT)
466: newblk(adbc, db, aibc, ib);
467: }
468:
469: newblk(adbc, db, aibc, ib)
470: int *adbc, *aibc;
471: char *db;
472: daddr_t *ib;
473: {
474: int i;
475: daddr_t bno;
476:
477: bno = alloc();
478: wtfs(bno, db);
479: for(i=0; i<BSIZE(0); i++)
480: db[i] = 0;
481: *adbc = 0;
482: ib[*aibc] = bno;
483: (*aibc)++;
484: if(*aibc >= NINDIR(0)) {
485: printf("indirect block full\n");
486: error = 1;
487: *aibc = 0;
488: }
489: }
490:
491: getch()
492: {
493:
494: #ifndef STANDALONE
495: if(charp)
496: #endif
497: return(*charp++);
498: #ifndef STANDALONE
499: return(getc(fin));
500: #endif
501: }
502:
503: bflist()
504: {
505: struct inode in;
506: daddr_t ib[NINDIR(0)];
507: int ibc;
508: char flg[MAXFN];
509: int adr[MAXFN];
510: int i, j;
511: daddr_t f, d;
512:
513: for(i=0; i<f_n; i++)
514: flg[i] = 0;
515: i = 0;
516: for(j=0; j<f_n; j++) {
517: while(flg[i])
518: i = (i+1)%f_n;
519: adr[j] = i+1;
520: flg[i]++;
521: i = (i+f_m)%f_n;
522: }
523:
524: ino++;
525: in.i_number = ino;
526: in.i_mode = IFREG;
527: in.i_uid = 0;
528: in.i_gid = 0;
529: in.i_nlink = 0;
530: in.i_size = 0;
531: for(i=0; i<NADDR; i++)
532: in.i_un.i_addr[i] = (daddr_t)0;
533:
534: for(i=0; i<NINDIR(0); i++)
535: ib[i] = (daddr_t)0;
536: ibc = 0;
537: bfree((daddr_t)0);
538: d = filsys.s_fsize-1;
539: while(d%f_n)
540: d++;
541: for(; d > 0; d -= f_n)
542: for(i=0; i<f_n; i++) {
543: f = d - adr[i];
544: if(f < filsys.s_fsize && f >= filsys.s_isize)
545: if(badblk(f)) {
546: if(ibc >= NINDIR(0)) {
547: printf("too many bad blocks\n");
548: error = 1;
549: ibc = 0;
550: }
551: ib[ibc] = f;
552: ibc++;
553: } else
554: bfree(f);
555: }
556: iput(&in, &ibc, ib);
557: }
558:
559: iput(ip, aibc, ib)
560: struct inode *ip;
561: int *aibc;
562: daddr_t *ib;
563: {
564: struct dinode *dp;
565: daddr_t d;
566: int i;
567:
568: filsys.s_tinode--;
569: d = itod(0,ip->i_number);
570: if(d >= filsys.s_isize) {
571: if(error == 0)
572: printf("ilist too small\n");
573: error = 1;
574: return;
575: }
576: rdfs(d, buf);
577: dp = (struct dinode *)buf;
578: dp += itoo(0,ip->i_number);
579:
580: dp->di_mode = ip->i_mode;
581: dp->di_nlink = ip->i_nlink;
582: dp->di_uid = ip->i_uid;
583: dp->di_gid = ip->i_gid;
584: dp->di_size = ip->i_size;
585: dp->di_atime = utime;
586: dp->di_mtime = utime;
587: dp->di_ctime = utime;
588:
589: switch(ip->i_mode&IFMT) {
590:
591: case IFDIR:
592: case IFREG:
593: for(i=0; i<*aibc; i++) {
594: if(i >= LADDR)
595: break;
596: ip->i_un.i_addr[i] = ib[i];
597: }
598: if(*aibc >= LADDR) {
599: ip->i_un.i_addr[LADDR] = alloc();
600: for(i=0; i<NINDIR(0)-LADDR; i++) {
601: ib[i] = ib[i+LADDR];
602: ib[i+LADDR] = (daddr_t)0;
603: }
604: wtfs(ip->i_un.i_addr[LADDR], (char *)ib);
605: }
606:
607: case IFBLK:
608: case IFCHR:
609: ltol3(dp->di_addr, ip->i_un.i_addr, NADDR);
610: break;
611:
612: default:
613: printf("bad mode %o\n", ip->i_mode);
614: exit(1);
615: }
616: wtfs(d, buf);
617: }
618:
619: badblk(bno)
620: daddr_t bno;
621: {
622:
623: return(0);
624: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.