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