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