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