home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / standalone / mkfs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-24  |  9.4 KB  |  616 lines

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