1: #if !defined(lint) && defined(DOSCCS)
   2: char    *sccsid = "@(#)mkfs.c	2.9 (2.11BSD) 1996/5/8";
   3: #endif
   4: 
   5: /*
   6:  * Make a file system.  Run by 'newfs' and not directly by users.
   7:  * usage: mkfs -s size -i byte/ino -n num -m num filsys
   8:  *
   9:  * NOTE:  the size is specified in filesystem (1k) blocks NOT sectors.
  10:  *	  newfs does the conversion before running mkfs - if you run mkfs
  11:  *	  manually beware that the '-s' option means sectors to newfs but
  12:  *	  filesystem blocks to mkfs!
  13:  */
  14: 
  15: #include <sys/param.h>
  16: /*
  17:  * Need to do the following to get the larger incore inode structure
  18:  * (the kernel might be built with the inode times external/mapped-out).
  19:  * See /sys/h/localtimes.h and /sys/conf.
  20: */
  21: #undef  EXTERNALITIMES
  22: 
  23: #include <sys/file.h>
  24: #include <sys/dir.h>
  25: #include <sys/stat.h>
  26: #include <sys/fs.h>
  27: 
  28: #ifndef STANDALONE
  29: #include <stdlib.h>
  30: #include <stdio.h>
  31: #include <sys/inode.h>
  32: #else
  33: #include "saio.h"
  34: #endif
  35: 
  36: #define UMASK   0755
  37: #define MAXFN   750
  38: 
  39: time_t  utime;
  40: 
  41: #ifdef STANDALONE
  42: int fin;
  43: char    module[] = "Mkfs";
  44: extern  char    *ltoa();
  45: extern  long    atol();
  46: extern  struct  iob iob[];
  47: #endif
  48: 
  49: int fsi;
  50: int fso;
  51: char    buf[DEV_BSIZE];
  52: 
  53: union {
  54:     struct fblk fb;
  55:     char pad1[DEV_BSIZE];
  56: } fbuf;
  57: 
  58: union {
  59:     struct fs fs;
  60:     char pad2[DEV_BSIZE];
  61: } filsys;
  62: 
  63: u_int   f_i = 4096;     /* bytes/inode default */
  64: int f_n = 100;
  65: int f_m = 2;
  66: 
  67:     daddr_t alloc();
  68: 
  69: main(argc,argv)
  70:     int argc;
  71:     char    **argv;
  72: {
  73: register int c;
  74:     long n;
  75:     char *size = 0;
  76:     char    *special;
  77: #ifdef  STANDALONE
  78:     struct  disklabel *lp;
  79: register struct partition *pp;
  80:     struct  iob *io;
  81: #endif
  82: 
  83: #ifndef STANDALONE
  84:     time(&utime);
  85:     while   ((c = getopt(argc, argv, "i:m:n:s:")) != EOF)
  86:         {
  87:         switch  (c)
  88:             {
  89:             case    'i':
  90:                 f_i = atoi(optarg);
  91:                 break;
  92:             case    'm':
  93:                 f_m = atoi(optarg);
  94:                 break;
  95:             case    'n':
  96:                 f_n = atoi(optarg);
  97:                 break;
  98:             case    's':
  99:                 size = optarg;
 100:                 break;
 101:             default:
 102:                 usage();
 103:                 break;
 104:             }
 105:         }
 106:     argc -= optind;
 107:     argv += optind;
 108:     if  (argc != 1 || !size || !f_i || !f_m || !f_n)
 109:         usage();
 110:     special = *argv;
 111: 
 112: /*
 113:  * NOTE: this will fail if the device is currently mounted and the system
 114:  * is at securelevel 1 or higher.
 115:  *
 116:  * We do not get the partition information because 'newfs' has already
 117:  * done so and invoked us.  This program should not be run manually unless
 118:  * you are absolutely sure you know what you are doing - use 'newfs' instead.
 119: */
 120:     fso = creat(special, 0666);
 121:     if  (fso < 0)
 122:         err(1, "cannot create %s\n", special);
 123:     fsi = open(special, 0);
 124:     if  (fsi < 0)
 125:         err(1, "cannot open %s\n", special);
 126: #else
 127: /*
 128:  * Something more modern than January 1, 1970 - the date that the new
 129:  * standalone mkfs worked.  1995/06/08 2121.
 130: */
 131:     utime = 802671684L;
 132:     printf("%s\n",module);
 133:     do {
 134:         printf("file system: ");
 135:         gets(buf);
 136:         fso = open(buf, 1);
 137:         fsi = open(buf, 0);
 138:     } while (fso < 0 || fsi < 0);
 139: 
 140: /*
 141:  * If the underlying driver supports disklabels then do not make a file
 142:  * system unless: there is a valid label present, the specified partition
 143:  * is of type FS_V71K, and the size is not zero.
 144:  *
 145:  * The 'open' above will have already fetched the label if the driver supports
 146:  * labels - the check below will only fail if the driver doesn't do labels
 147:  * or if the drive blew up in the millisecond since the last read.
 148: */
 149:     io = &iob[fsi - 3];
 150:     lp = &io->i_label;
 151:     pp = &lp->d_partitions[io->i_part];
 152: 
 153:     if  (devlabel(io, READLABEL) < 0)
 154:         {
 155: /*
 156:  * The driver does not implement labels.  The 'iob' structure still contains
 157:  * a label structure so initialize the items that will be looked at later.
 158: */
 159:         pp->p_size = 0;
 160:         lp->d_secpercyl = 0;
 161:         goto nolabels;
 162:         }
 163:     if  (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
 164:          dkcksum(lp))
 165:         {
 166:         printf("'%s' is either unlabeled or the label is corrupt.\n",
 167:             buf);
 168:         printf("Since the driver for '%s' supports disklabels you\n",
 169:             buf);
 170:         printf("must use the standalone 'disklabel' before making\n");
 171:         printf("a filesystem on '%s'\n", buf);
 172:         return;
 173:         }
 174:     if  (pp->p_fstype != FS_V71K)
 175:         {
 176:         printf("%s is not a 2.11BSD (FS_V71K) partition.", buf);
 177:         return;
 178:         }
 179:     if  (pp->p_size == 0)
 180:         {
 181:         printf("%s is a zero length partition.\n", buf);
 182:         return;
 183:         }
 184: nolabels:
 185:     printf("file sys size [%D]: ", dbtofsb(pp->p_size));
 186:     size = buf+128;
 187:     gets(size);
 188:     if  (size[0] == '\0')
 189:         strcpy(size, ltoa(dbtofsb(pp->p_size)));
 190:     if  (pp->p_size && atol(size) > pp->p_size)
 191:         {
 192:         printf("specified size larger than disklabel says.\n");
 193:         return;
 194:         }
 195:     printf("bytes per inode [%u]: ", f_i);
 196:     gets(buf);
 197:     if  (buf[0])
 198:         f_i = atoi(buf);
 199:     printf("interleaving factor (m; %d default): ", f_m);
 200:     gets(buf);
 201:     if  (buf[0])
 202:         f_m = atoi(buf);
 203:     if  (lp->d_secpercyl)
 204:         f_n = dbtofsb(lp->d_secpercyl);
 205:     printf("interleaving modulus (n; %d default): ", f_n);
 206:     gets(buf);
 207:     if  (buf[0])
 208:         f_n = atoi(buf);
 209: #endif
 210: 
 211:     if  (f_n <= 0 || f_n >= MAXFN)
 212:         f_n = MAXFN;
 213:     if  (f_m <= 0 || f_m > f_n)
 214:         f_m = 3;
 215: 
 216:     n = atol(size);
 217:     if  (!n)
 218:         {
 219:         printf("Can't make zero length filesystem\n");
 220:         return;
 221:         }
 222:     filsys.fs.fs_fsize = n;
 223: 
 224: /*
 225:  * Calculate number of blocks of inodes as follows:
 226:  *
 227:  *	dbtob(n) = # of bytes in the filesystem
 228:  *	dbtob(n) / f_i = # of inodes to allocate
 229:  *	(dbtob(n) / f_i) / INOPB = # of fs blocks of inodes
 230:  *
 231:  * Pretty - isn't it?
 232: */
 233:     n = (dbtob(n) / f_i) / INOPB;
 234:     if  (n <= 0)
 235:         n = 1;
 236:     if  (n > 65500/INOPB)
 237:         n = 65500/INOPB;
 238:     filsys.fs.fs_isize = n + 2;
 239:     printf("isize = %D\n", n*INOPB);
 240: 
 241:     filsys.fs.fs_step = f_m;
 242:     filsys.fs.fs_cyl = f_n;
 243:     printf("m/n = %d %d\n", f_m, f_n);
 244:     if  (filsys.fs.fs_isize >= filsys.fs.fs_fsize)
 245:         {
 246:         printf("%D/%D: bad ratio\n", filsys.fs.fs_fsize, filsys.fs.fs_isize-2);
 247:         exit(1);
 248:         }
 249:     filsys.fs.fs_tfree = 0;
 250:     filsys.fs.fs_tinode = 0;
 251:     bzero(buf, DEV_BSIZE);
 252:     for (n=2; n!=filsys.fs.fs_isize; n++) {
 253:         wtfs(n, buf);
 254:         filsys.fs.fs_tinode += INOPB;
 255:     }
 256: 
 257:     bflist();
 258: 
 259:     fsinit();
 260: 
 261:     filsys.fs.fs_time = utime;
 262:     wtfs((long)SBLOCK, (char *)&filsys.fs);
 263:     exit(0);
 264: }
 265: 
 266: /*
 267:  * initialize the file system
 268:  */
 269: struct inode node;
 270: #define PREDEFDIR 3
 271: struct direct root_dir[] = {
 272:     { ROOTINO, sizeof(struct direct), 1, "." },
 273:     { ROOTINO, sizeof(struct direct), 2, ".." },
 274:     { LOSTFOUNDINO, sizeof(struct direct), 10, "lost+found" },
 275: };
 276: struct direct lost_found_dir[] = {
 277:     { LOSTFOUNDINO, sizeof(struct direct), 1, "." },
 278:     { ROOTINO, sizeof(struct direct), 2, ".." },
 279:     { 0, DIRBLKSIZ, 0, 0 },
 280: };
 281: 
 282: fsinit()
 283: {
 284:     register int i;
 285: 
 286:     /*
 287: 	 * initialize the node
 288: 	 */
 289:     node.i_atime = utime;
 290:     node.i_mtime = utime;
 291:     node.i_ctime = utime;
 292:     /*
 293: 	 * create the lost+found directory
 294: 	 */
 295:     (void)makedir(lost_found_dir, 2);
 296:     for (i = DIRBLKSIZ; i < DEV_BSIZE; i += DIRBLKSIZ)
 297:         bcopy(&lost_found_dir[2], &buf[i], DIRSIZ(&lost_found_dir[2]));
 298:     node.i_number = LOSTFOUNDINO;
 299:     node.i_mode = IFDIR | UMASK;
 300:     node.i_nlink = 2;
 301:     node.i_size = DEV_BSIZE;
 302:     node.i_db[0] = alloc();
 303:     wtfs(node.i_db[0], buf);
 304:     iput(&node);
 305:     /*
 306: 	 * create the root directory
 307: 	 */
 308:     node.i_number = ROOTINO;
 309:     node.i_mode = IFDIR | UMASK;
 310:     node.i_nlink = PREDEFDIR;
 311:     node.i_size = makedir(root_dir, PREDEFDIR);
 312:     node.i_db[0] = alloc();
 313:     wtfs(node.i_db[0], buf);
 314:     iput(&node);
 315: }
 316: 
 317: /*
 318:  * construct a set of directory entries in "buf".
 319:  * return size of directory.
 320:  */
 321: makedir(protodir, entries)
 322:     register struct direct *protodir;
 323:     int entries;
 324: {
 325:     char *cp;
 326:     int i, spcleft;
 327: 
 328:     spcleft = DIRBLKSIZ;
 329:     for (cp = buf, i = 0; i < entries - 1; i++) {
 330:         protodir[i].d_reclen = DIRSIZ(&protodir[i]);
 331:         bcopy(&protodir[i], cp, protodir[i].d_reclen);
 332:         cp += protodir[i].d_reclen;
 333:         spcleft -= protodir[i].d_reclen;
 334:     }
 335:     protodir[i].d_reclen = spcleft;
 336:     bcopy(&protodir[i], cp, DIRSIZ(&protodir[i]));
 337:     return (DIRBLKSIZ);
 338: }
 339: 
 340: daddr_t
 341: alloc()
 342: {
 343:     register int i;
 344:     daddr_t bno;
 345: 
 346:     filsys.fs.fs_tfree--;
 347:     bno = filsys.fs.fs_free[--filsys.fs.fs_nfree];
 348:     if(bno == 0) {
 349:         printf("out of free space\n");
 350:         exit(1);
 351:     }
 352:     if(filsys.fs.fs_nfree <= 0) {
 353:         rdfs(bno, (char *)&fbuf);
 354:         filsys.fs.fs_nfree = fbuf.fb.df_nfree;
 355:         for(i=0; i<NICFREE; i++)
 356:             filsys.fs.fs_free[i] = fbuf.fb.df_free[i];
 357:     }
 358:     return(bno);
 359: }
 360: 
 361: rdfs(bno, bf)
 362: daddr_t bno;
 363: char *bf;
 364: {
 365:     int n;
 366: 
 367:     lseek(fsi, bno*DEV_BSIZE, 0);
 368:     n = read(fsi, bf, DEV_BSIZE);
 369:     if(n != DEV_BSIZE) {
 370:         printf("read error: %ld\n", bno);
 371:         exit(1);
 372:     }
 373: }
 374: 
 375: wtfs(bno, bf)
 376: daddr_t bno;
 377: char *bf;
 378: {
 379:     int n;
 380: 
 381:     lseek(fso, bno*DEV_BSIZE, 0);
 382:     n = write(fso, bf, DEV_BSIZE);
 383:     if(n != DEV_BSIZE) {
 384:         printf("write error: %D\n", bno);
 385:         exit(1);
 386:     }
 387: }
 388: 
 389: bfree(bno)
 390: daddr_t bno;
 391: {
 392:     register int i;
 393: 
 394:     if (bno != 0)
 395:         filsys.fs.fs_tfree++;
 396:     if(filsys.fs.fs_nfree >= NICFREE) {
 397:         fbuf.fb.df_nfree = filsys.fs.fs_nfree;
 398:         for(i=0; i<NICFREE; i++)
 399:             fbuf.fb.df_free[i] = filsys.fs.fs_free[i];
 400:         wtfs(bno, (char *)&fbuf);
 401:         filsys.fs.fs_nfree = 0;
 402:     }
 403:     filsys.fs.fs_free[filsys.fs.fs_nfree++] = bno;
 404: }
 405: 
 406: bflist()
 407: {
 408:     struct inode in;
 409:     char flg[MAXFN];
 410:     int adr[MAXFN];
 411:     register int i, j;
 412:     daddr_t f, d;
 413: 
 414:     bzero(flg, sizeof flg);
 415:     i = 0;
 416:     for(j=0; j<f_n; j++) {
 417:         while(flg[i])
 418:             i = (i+1)%f_n;
 419:         adr[j] = i+1;
 420:         flg[i]++;
 421:         i = (i+f_m)%f_n;
 422:     }
 423: 
 424:     bzero(&in, sizeof (in));
 425:     in.i_number = 1;        /* inode 1 is a historical hack */
 426:     in.i_mode = IFREG;
 427:     bfree((daddr_t)0);
 428:     d = filsys.fs.fs_fsize-1;
 429:     while(d%f_n)
 430:         d++;
 431:     for(; d > 0; d -= f_n)
 432:     for(i=0; i<f_n; i++) {
 433:         f = d - adr[i];
 434:         if(f < filsys.fs.fs_fsize && f >= filsys.fs.fs_isize)
 435:             bfree(f);
 436:     }
 437:     iput(&in);
 438: }
 439: 
 440: iput(ip)
 441: register struct inode *ip;
 442: {
 443:     struct  dinode  buf[INOPB];
 444:     register struct dinode *dp;
 445:     daddr_t d;
 446: 
 447:     filsys.fs.fs_tinode--;
 448:     d = itod(ip->i_number);
 449:     if(d >= filsys.fs.fs_isize) {
 450:         printf("ilist too small\n");
 451:         return;
 452:     }
 453:     rdfs(d, buf);
 454:     dp = (struct dinode *)buf;
 455:     dp += itoo(ip->i_number);
 456: 
 457:     dp->di_addr[0] = ip->i_addr[0];
 458:     dp->di_ic1 = ip->i_ic1;
 459:     dp->di_ic2 = ip->i_ic2;
 460:     wtfs(d, buf);
 461: }
 462: 
 463: #ifndef STANDALONE
 464: usage()
 465:     {
 466:     printf("usage: [-s size] [-i bytes/ino] [-n num] [-m num] special\n");
 467:     exit(1);
 468:     /* NOTREACHED */
 469:     }
 470: #endif

Defined functions

alloc defined in line 340; used 3 times
bflist defined in line 406; used 1 times
bfree defined in line 389; used 2 times
fsinit defined in line 282; used 1 times
iput defined in line 440; used 3 times
main defined in line 69; never used
makedir defined in line 321; used 2 times
rdfs defined in line 361; used 2 times
usage defined in line 464; used 2 times
wtfs defined in line 375; used 6 times

Defined variables

buf defined in line 51; used 28 times
f_i defined in line 63; used 5 times
f_m defined in line 65; used 10 times
f_n defined in line 64; used 17 times
fin defined in line 42; never used
fsi defined in line 49; used 7 times
fso defined in line 50; used 6 times
lost_found_dir defined in line 276; used 3 times
module defined in line 43; used 1 times
node defined in line 269; used 17 times
root_dir defined in line 271; used 1 times
sccsid defined in line 2; never used
utime defined in line 39; used 6 times

Defined macros

MAXFN defined in line 37; used 4 times
PREDEFDIR defined in line 270; used 2 times
UMASK defined in line 36; used 2 times
Last modified: 1996-05-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4447
Valid CSS Valid XHTML 1.0 Strict