Changes in / [d7ff048:80099c19] in mainline
- Location:
- uspace
- Files:
-
- 10 deleted
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkmfs/mkmfs.c
rd7ff048 r80099c19 1 1 /* 2 * Copyright (c) 2010 Jiri Svoboda 2 3 * Copyright (c) 2011 Maurizio Lombardi 3 4 * All rights reserved. … … 55 56 #define USED 1 56 57 57 #define UPPER(n, size) (((n) / (size)) + (((n) % (size)) != 0))58 #define NEXT_DENTRY(p, dirsize) (p += (dirsize))58 #define UPPER(n, size) (((n) / (size)) + (((n) % (size)) != 0)) 59 #define NEXT_DENTRY(p, dirsize) (p += (dirsize)) 59 60 60 61 typedef enum { … … 63 64 } help_level_t; 64 65 65 /* Generic MFS superblock*/66 /*Generic MFS superblock*/ 66 67 struct mfs_sb_info { 67 68 uint64_t n_inodes; … … 83 84 84 85 static void help_cmd_mkmfs(help_level_t level); 85 static bool is_power_of_two(uint32_t n);86 static int num_of_set_bits(uint32_t n); 86 87 static int init_superblock(struct mfs_sb_info *sb); 87 88 static int write_superblock(const struct mfs_sb_info *sbi); … … 117 118 struct mfs_sb_info sb; 118 119 119 /* Default is MinixFS V3*/120 /*Default is MinixFS V3*/ 120 121 sb.magic = MFS_MAGIC_V3; 121 122 sb.fs_version = 3; 122 123 123 /* Default block size is 4Kb*/124 /*Default block size is 4Kb*/ 124 125 sb.block_size = MFS_MAX_BLOCKSIZE; 125 126 sb.dirsize = MFS3_DIRSIZE; … … 135 136 136 137 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 137 c = getopt_long(argc, argv, "lh12b:i:", 138 long_options, &opt_ind); 138 c = getopt_long(argc, argv, "lh12b:i:", long_options, &opt_ind); 139 139 switch (c) { 140 140 case 'h': … … 169 169 170 170 if (sb.block_size < MFS_MIN_BLOCKSIZE || 171 171 sb.block_size > MFS_MAX_BLOCKSIZE) { 172 172 printf(NAME ":Error! Invalid block size.\n"); 173 173 exit(0); 174 } else if ( !is_power_of_two(sb.block_size)) {175 /* Block size must be a power of 2.*/174 } else if (num_of_set_bits(sb.block_size) != 1) { 175 /*Block size must be a power of 2.*/ 176 176 printf(NAME ":Error! Invalid block size.\n"); 177 177 exit(0); 178 178 } else if (sb.block_size > MFS_BLOCKSIZE && 179 sb.fs_version != 3) { 180 printf(NAME ":Error! Block size > 1024 is " 181 "supported by V3 filesystem only.\n"); 179 sb.fs_version != 3) { 180 printf(NAME ":Error! Block size > 1024 is supported by V3 filesystem only.\n"); 182 181 exit(0); 183 182 } else if (sb.fs_version == 3 && sb.longnames) { 184 printf(NAME ":Error! Long filenames are supported " 185 "by V1/V2 filesystem only.\n"); 183 printf(NAME ":Error! Long filenames are supported by V1/V2 filesystem only.\n"); 186 184 exit(0); 187 185 } … … 223 221 rc = block_get_nblocks(service_id, &sb.dev_nblocks); 224 222 if (rc != EOK) { 225 printf(NAME ": Warning, failed to obtain " 226 "block device size.\n"); 223 printf(NAME ": Warning, failed to obtain block device size.\n"); 227 224 } else { 228 225 printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n", 229 226 sb.dev_nblocks); 230 227 } 231 228 … … 235 232 } 236 233 237 /* Minimum block size is 1 Kb*/234 /*Minimum block size is 1 Kb*/ 238 235 sb.dev_nblocks /= 2; 239 236 240 237 printf(NAME ": Creating Minix file system on device\n"); 241 printf(NAME ": Writing superblock\n"); 242 243 /* Initialize superblock */ 238 239 /*Initialize superblock*/ 244 240 if (init_superblock(&sb) != EOK) { 245 241 printf(NAME ": Error. Superblock initialization failed\n"); … … 247 243 } 248 244 249 printf(NAME ": Initializing bitmaps\n"); 250 251 /* Initialize bitmaps */ 245 /*Initialize bitmaps*/ 252 246 if (init_bitmaps(&sb) != EOK) { 253 247 printf(NAME ": Error. Bitmaps initialization failed\n"); … … 255 249 } 256 250 257 printf(NAME ": Initializing the inode table\n"); 258 259 /* Init inode table */ 251 /*Init inode table*/ 260 252 if (init_inode_table(&sb) != EOK) { 261 253 printf(NAME ": Error. Inode table initialization failed\n"); … … 263 255 } 264 256 265 printf(NAME ": Creating the root directory inode\n"); 266 267 /* Make the root inode */ 257 /*Make the root inode*/ 268 258 if (sb.fs_version == 1) 269 259 rc = make_root_ino(&sb); … … 276 266 } 277 267 278 /* Insert directory entries . and ..*/268 /*Insert directory entries . and ..*/ 279 269 if (insert_dentries(&sb) != EOK) { 280 270 printf(NAME ": Error. Root directory initialization failed\n"); … … 309 299 310 300 if (sb->fs_version != 3) { 311 /* Directory entries for V1/V2 filesystem*/301 /*Directory entries for V1/V2 filesystem*/ 312 302 struct mfs_dentry *dentry = root_block; 313 303 … … 316 306 317 307 dentry = (struct mfs_dentry *) NEXT_DENTRY(dentry_ptr, 318 308 sb->dirsize); 319 309 320 310 dentry->d_inum = MFS_ROOT_INO; 321 311 memcpy(dentry->d_name, "..\0", 3); 322 312 } else { 323 /* Directory entries for V3 filesystem*/313 /*Directory entries for V3 filesystem*/ 324 314 struct mfs3_dentry *dentry = root_block; 325 315 … … 328 318 329 319 dentry = (struct mfs3_dentry *) NEXT_DENTRY(dentry_ptr, 330 320 sb->dirsize); 331 321 332 322 dentry->d_inum = MFS_ROOT_INO; … … 399 389 ino_buf[MFS_ROOT_INO - 1].i_gid = 0; 400 390 ino_buf[MFS_ROOT_INO - 1].i_size = (sb->longnames ? MFSL_DIRSIZE : 401 391 MFS_DIRSIZE) * 2; 402 392 ino_buf[MFS_ROOT_INO - 1].i_mtime = sec; 403 393 ino_buf[MFS_ROOT_INO - 1].i_nlinks = 2; … … 421 411 int rc; 422 412 423 /* Compute offset of the first inode table block*/413 /*Compute offset of the first inode table block*/ 424 414 const long itable_off = sb->zbmap_blocks + sb->ibmap_blocks + 2; 425 415 … … 464 454 465 455 if (sb->longnames) 466 sb->magic = sb->fs_version == 1 ? MFS_MAGIC_V1L : 467 MFS_MAGIC_V2L; 468 469 /* Compute the number of zones on disk */ 456 sb->magic = sb->fs_version == 1 ? MFS_MAGIC_V1L : MFS_MAGIC_V2L; 457 458 /*Compute the number of zones on disk*/ 470 459 471 460 if (sb->fs_version == 1) { 472 /* Valid only for MFS V1*/461 /*Valid only for MFS V1*/ 473 462 sb->n_zones = sb->dev_nblocks > UINT16_MAX ? 474 463 UINT16_MAX : sb->dev_nblocks; 475 464 ind = MFS_BLOCKSIZE / sizeof(uint16_t); 476 465 ind2 = ind * ind; 477 sb->max_file_size = (V1_NR_DIRECT_ZONES + ind + ind2) * 478 MFS_BLOCKSIZE; 466 sb->max_file_size = (V1_NR_DIRECT_ZONES + ind + ind2) * MFS_BLOCKSIZE; 479 467 } else { 480 468 /*Valid for MFS V2/V3*/ … … 484 472 else 485 473 ptrsize = sizeof(uint32_t); 486 487 474 ind = sb->block_size / ptrsize; 488 475 ind2 = ind * ind; … … 490 477 sb->max_file_size = zones * sb->block_size; 491 478 sb->n_zones = sb->dev_nblocks > UINT32_MAX ? 492 479 UINT32_MAX : sb->dev_nblocks; 493 480 494 481 if (sb->fs_version == 3) { … … 500 487 } 501 488 502 /* Round up the number of inodes to fill block size*/489 /*Round up the number of inodes to fill block size*/ 503 490 if (sb->n_inodes == 0) 504 491 inodes = sb->dev_nblocks / 3; … … 507 494 508 495 if (inodes % sb->ino_per_block) 509 inodes = ((inodes / sb->ino_per_block) + 1) * 510 sb->ino_per_block; 496 inodes = ((inodes / sb->ino_per_block) + 1) * sb->ino_per_block; 511 497 512 498 if (sb->fs_version < 3) … … 515 501 sb->n_inodes = inodes > UINT32_MAX ? UINT32_MAX : inodes; 516 502 517 /* Compute inode bitmap size in blocks*/503 /*Compute inode bitmap size in blocks*/ 518 504 sb->ibmap_blocks = UPPER(sb->n_inodes, sb->block_size * 8); 519 505 520 /* Compute inode table size*/506 /*Compute inode table size*/ 521 507 sb->itable_size = sb->n_inodes / sb->ino_per_block; 522 508 523 /* Compute zone bitmap size in blocks*/509 /*Compute zone bitmap size in blocks*/ 524 510 sb->zbmap_blocks = UPPER(sb->n_zones, sb->block_size * 8); 525 511 526 /* Compute first data zone position*/512 /*Compute first data zone position*/ 527 513 sb->first_data_zone = 2 + sb->itable_size + 528 529 530 /* Set log2 of zone to block ratio to zero*/514 sb->zbmap_blocks + sb->ibmap_blocks; 515 516 /*Set log2 of zone to block ratio to zero*/ 531 517 sb->log2_zone_size = 0; 532 518 533 /* Check for errors*/519 /*Check for errors*/ 534 520 if (sb->first_data_zone >= sb->n_zones) { 535 521 printf(NAME ": Error! Insufficient disk space"); … … 537 523 } 538 524 539 /* Superblock is now ready to be written on disk*/525 /*Superblock is now ready to be written on disk*/ 540 526 printf(NAME ": %d block size\n", sb->block_size); 541 527 printf(NAME ": %d inodes\n", (uint32_t) sb->n_inodes); … … 544 530 printf(NAME ": inode bitmap blocks = %ld\n", sb->ibmap_blocks); 545 531 printf(NAME ": zone bitmap blocks = %ld\n", sb->zbmap_blocks); 546 printf(NAME ": first data zone = %d\n", (uint32_t) sb->first_data_zone);532 printf(NAME ": first data zone = %d\n", (uint32_t) sb->first_data_zone); 547 533 printf(NAME ": max file size = %u\n", sb->max_file_size); 548 534 printf(NAME ": long fnames = %s\n", sb->longnames ? "Yes" : "No"); … … 659 645 for (i = 0; i < ibmap_nblocks; ++i) { 660 646 if ((rc = write_block(start_block + i, 661 647 1, (ibmap_buf8 + i * sb->block_size))) != EOK) 662 648 return rc; 663 649 } … … 667 653 for (i = 0; i < zbmap_nblocks; ++i) { 668 654 if ((rc = write_block(start_block + i, 669 655 1, (zbmap_buf8 + i * sb->block_size))) != EOK) 670 656 return rc; 671 657 } … … 706 692 uint8_t *data_ptr = (uint8_t *) data; 707 693 708 rc = block_write_direct(service_id, tmp_off << 2, 709 size << 2, data_ptr); 694 rc = block_write_direct(service_id, tmp_off << 2, size << 2, data_ptr); 710 695 711 696 if (rc != EOK) … … 715 700 tmp_off++; 716 701 717 return block_write_direct(service_id, tmp_off << 2, 718 size << 2, data_ptr); 719 } 720 return block_write_direct(service_id, off << shift, 721 size << shift, data); 702 return block_write_direct(service_id, tmp_off << 2, size << 2, data_ptr); 703 } 704 return block_write_direct(service_id, off << shift, size << shift, data); 722 705 } 723 706 … … 728 711 } else { 729 712 printf("Usage: [options] device\n" 730 "-1 Make a Minix version 1 filesystem\n" 731 "-2 Make a Minix version 2 filesystem\n" 732 "-b ## Specify the block size in bytes (V3 only),\n" 733 " valid block size values are 1024, 2048 and" 734 " 4096 bytes per block\n" 735 "-i ## Specify the number of inodes" 736 " for the filesystem\n" 737 "-l Use 30-char long filenames (V1/V2 only)\n"); 738 } 739 } 740 741 /** Check if a given number is a power of two. 742 * 743 * @param n The number to check. 744 * 745 * @return true if it is a power of two, false otherwise. 746 */ 747 static bool is_power_of_two(uint32_t n) 748 { 749 if (n == 0) 750 return false; 751 752 return (n & (n - 1)) == 0; 713 "-1 Make a Minix version 1 filesystem\n" 714 "-2 Make a Minix version 2 filesystem\n" 715 "-b ## Specify the block size in bytes (V3 only),\n" 716 " valid block size values are 1024, 2048 and 4096 bytes per block\n" 717 "-i ## Specify the number of inodes for the filesystem\n" 718 "-l Use 30-char long filenames (V1/V2 only)\n"); 719 } 720 } 721 722 static int num_of_set_bits(uint32_t n) 723 { 724 n = n - ((n >> 1) & 0x55555555); 725 n = (n & 0x33333333) + ((n >> 2) & 0x33333333); 726 return (((n + (n >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; 753 727 } 754 728
Note:
See TracChangeset
for help on using the changeset viewer.