diff options
-rw-r--r-- | applets/Kbuild | 6 | ||||
-rw-r--r-- | include/usage.h | 15 | ||||
-rw-r--r-- | util-linux/mkfs_ext2.c | 51 | ||||
-rw-r--r-- | util-linux/mkfs_ext2.txt | 2 | ||||
-rwxr-xr-x | util-linux/mkfs_ext2_test.sh | 2 |
5 files changed, 46 insertions, 30 deletions
diff --git a/applets/Kbuild b/applets/Kbuild index a966f6e5b..a6b0cf6fb 100644 --- a/applets/Kbuild +++ b/applets/Kbuild | |||
@@ -27,9 +27,9 @@ HOSTCFLAGS_usage_pod.o = -I$(srctree_slash)include -Iinclude | |||
27 | 27 | ||
28 | applets/applets.o: include/usage_compressed.h include/applet_tables.h | 28 | applets/applets.o: include/usage_compressed.h include/applet_tables.h |
29 | 29 | ||
30 | applets/applet_tables: .config | 30 | applets/applet_tables: .config $(srctree_slash)include/applets.h |
31 | applets/usage: .config | 31 | applets/usage: .config $(srctree_slash)include/applets.h |
32 | applets/usage_pod: .config include/applet_tables.h | 32 | applets/usage_pod: .config include/applet_tables.h $(srctree_slash)include/applets.h |
33 | 33 | ||
34 | quiet_cmd_gen_usage_compressed = GEN include/usage_compressed.h | 34 | quiet_cmd_gen_usage_compressed = GEN include/usage_compressed.h |
35 | cmd_gen_usage_compressed = $(srctree_slash)applets/usage_compressed include/usage_compressed.h applets | 35 | cmd_gen_usage_compressed = $(srctree_slash)applets/usage_compressed include/usage_compressed.h applets |
diff --git a/include/usage.h b/include/usage.h index 9c0d29d94..01f6daf13 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -2716,7 +2716,7 @@ | |||
2716 | /* "[-c|-l filename] " */ \ | 2716 | /* "[-c|-l filename] " */ \ |
2717 | "[-b BLK_SIZE] " \ | 2717 | "[-b BLK_SIZE] " \ |
2718 | /* "[-f fragment-size] [-g blocks-per-group] " */ \ | 2718 | /* "[-f fragment-size] [-g blocks-per-group] " */ \ |
2719 | "[-i BYTES_PER_INODE] " \ | 2719 | "[-i INODE_RATIO] [-I INODE_SIZE] " \ |
2720 | /* "[-j] [-J journal-options] [-N number-of-inodes] " */ \ | 2720 | /* "[-j] [-J journal-options] [-N number-of-inodes] " */ \ |
2721 | "[-m RESERVED_PERCENT] " \ | 2721 | "[-m RESERVED_PERCENT] " \ |
2722 | /* "[-o creator-os] [-O feature[,...]] [-q] " */ \ | 2722 | /* "[-o creator-os] [-O feature[,...]] [-q] " */ \ |
@@ -2724,15 +2724,16 @@ | |||
2724 | "[-L LABEL] " \ | 2724 | "[-L LABEL] " \ |
2725 | "[-n] " \ | 2725 | "[-n] " \ |
2726 | /* "[-M last-mounted-directory] [-S] [-T filesystem-type] " */ \ | 2726 | /* "[-M last-mounted-directory] [-S] [-T filesystem-type] " */ \ |
2727 | "DEVICE [KBYTES]" | 2727 | "BLOCKDEV [KBYTES]" |
2728 | #define mkfs_ext2_full_usage "\n" \ | 2728 | #define mkfs_ext2_full_usage "\n" \ |
2729 | "\n -b BLK_SIZE Block size in bytes" \ | 2729 | "\n -b BLK_SIZE Block size, bytes" \ |
2730 | /* "\n -c Check for bad blocks before creating" */ \ | 2730 | /* "\n -c Check device for bad blocks" */ \ |
2731 | /* "\n -E opts Set extended options" */ \ | 2731 | /* "\n -E opts Set extended options" */ \ |
2732 | /* "\n -f size Fragment size in bytes" */ \ | 2732 | /* "\n -f size Fragment size in bytes" */ \ |
2733 | /* "\n -F Force (ignore sanity checks)" */ \ | 2733 | /* "\n -F Force (ignore sanity checks)" */ \ |
2734 | /* "\n -g num Number of blocks in a block group" */ \ | 2734 | /* "\n -g num Number of blocks in a block group" */ \ |
2735 | "\n -i BYTES The bytes/inode ratio" \ | 2735 | "\n -i RATIO Set max number of files to filesystem_size / RATIO" \ |
2736 | "\n -I BYTES Inode size (min 128)" \ | ||
2736 | /* "\n -j Create a journal (ext3)" */ \ | 2737 | /* "\n -j Create a journal (ext3)" */ \ |
2737 | /* "\n -J opts Set journal options (size/device)" */ \ | 2738 | /* "\n -J opts Set journal options (size/device)" */ \ |
2738 | /* "\n -l file Read bad blocks list from file" */ \ | 2739 | /* "\n -l file Read bad blocks list from file" */ \ |
@@ -2750,7 +2751,7 @@ | |||
2750 | /* "\n -v Verbose" */ \ | 2751 | /* "\n -v Verbose" */ \ |
2751 | 2752 | ||
2752 | #define mkfs_minix_trivial_usage \ | 2753 | #define mkfs_minix_trivial_usage \ |
2753 | "[-c | -l filename] [-nXX] [-iXX] /dev/name [blocks]" | 2754 | "[-c | -l filename] [-nXX] [-iXX] BLOCKDEV [KBYTES]" |
2754 | #define mkfs_minix_full_usage "\n\n" \ | 2755 | #define mkfs_minix_full_usage "\n\n" \ |
2755 | "Make a MINIX filesystem\n" \ | 2756 | "Make a MINIX filesystem\n" \ |
2756 | "\nOptions:" \ | 2757 | "\nOptions:" \ |
@@ -2761,7 +2762,7 @@ | |||
2761 | "\n -v Make version 2 filesystem" \ | 2762 | "\n -v Make version 2 filesystem" \ |
2762 | 2763 | ||
2763 | #define mkfs_vfat_trivial_usage \ | 2764 | #define mkfs_vfat_trivial_usage \ |
2764 | "[-v] [-n LABEL] FILE_OR_DEVICE [SIZE_IN_KB]" | 2765 | "[-v] [-n LABEL] BLOCKDEV [KBYTES]" |
2765 | /* Accepted but ignored: | 2766 | /* Accepted but ignored: |
2766 | "[-c] [-C] [-I] [-l bad-block-file] [-b backup-boot-sector] " | 2767 | "[-c] [-C] [-I] [-l bad-block-file] [-b backup-boot-sector] " |
2767 | "[-m boot-msg-file] [-i volume-id] " | 2768 | "[-m boot-msg-file] [-i volume-id] " |
diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c index ef22ec7e6..10f7f5fb4 100644 --- a/util-linux/mkfs_ext2.c +++ b/util-linux/mkfs_ext2.c | |||
@@ -159,7 +159,7 @@ enum { | |||
159 | OPT_b = 1 << 2, // block size, in bytes | 159 | OPT_b = 1 << 2, // block size, in bytes |
160 | OPT_f = 1 << 3, | 160 | OPT_f = 1 << 3, |
161 | OPT_i = 1 << 4, // bytes per inode | 161 | OPT_i = 1 << 4, // bytes per inode |
162 | OPT_I = 1 << 5, | 162 | OPT_I = 1 << 5, // custom inode size, in bytes |
163 | OPT_J = 1 << 6, | 163 | OPT_J = 1 << 6, |
164 | OPT_G = 1 << 7, | 164 | OPT_G = 1 << 7, |
165 | OPT_N = 1 << 8, | 165 | OPT_N = 1 << 8, |
@@ -188,6 +188,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
188 | unsigned i, pos, n; | 188 | unsigned i, pos, n; |
189 | unsigned bs, bpi; | 189 | unsigned bs, bpi; |
190 | unsigned blocksize, blocksize_log2; | 190 | unsigned blocksize, blocksize_log2; |
191 | unsigned inodesize, user_inodesize; | ||
191 | unsigned reserved_percent = 5; | 192 | unsigned reserved_percent = 5; |
192 | unsigned long long kilobytes; | 193 | unsigned long long kilobytes; |
193 | uint32_t nblocks, nblocks_full; | 194 | uint32_t nblocks, nblocks_full; |
@@ -211,7 +212,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
211 | 212 | ||
212 | opt_complementary = "-1:b+:m+:i+"; | 213 | opt_complementary = "-1:b+:m+:i+"; |
213 | opts = getopt32(argv, "cl:b:f:i:I:J:G:N:m:o:g:L:M:O:r:E:T:U:jnqvFS", | 214 | opts = getopt32(argv, "cl:b:f:i:I:J:G:N:m:o:g:L:M:O:r:E:T:U:jnqvFS", |
214 | NULL, &bs, NULL, &bpi, NULL, NULL, NULL, NULL, | 215 | NULL, &bs, NULL, &bpi, &user_inodesize, NULL, NULL, NULL, |
215 | &reserved_percent, NULL, NULL, &label, NULL, NULL, NULL, NULL, NULL, NULL); | 216 | &reserved_percent, NULL, NULL, &label, NULL, NULL, NULL, NULL, NULL, NULL); |
216 | argv += optind; // argv[0] -- device | 217 | argv += optind; // argv[0] -- device |
217 | 218 | ||
@@ -249,11 +250,15 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
249 | if (opts & OPT_i) | 250 | if (opts & OPT_i) |
250 | bytes_per_inode = bpi; | 251 | bytes_per_inode = bpi; |
251 | 252 | ||
252 | // Determine block size | 253 | // Determine block size and inode size |
253 | // block size is a multiple of 1024 | 254 | // block size is a multiple of 1024 |
255 | // inode size is a multiple of 128 | ||
254 | blocksize = 1024; | 256 | blocksize = 1024; |
255 | if (kilobytes >= 512*1024) // mke2fs 1.41.9 compat | 257 | inodesize = sizeof(struct ext2_inode); // 128 |
258 | if (kilobytes >= 512*1024) { // mke2fs 1.41.9 compat | ||
256 | blocksize = 4096; | 259 | blocksize = 4096; |
260 | inodesize = 256; | ||
261 | } | ||
257 | if (EXT2_MAX_BLOCK_SIZE > 4096) { | 262 | if (EXT2_MAX_BLOCK_SIZE > 4096) { |
258 | // kilobytes >> 22 == size in 4gigabyte chunks. | 263 | // kilobytes >> 22 == size in 4gigabyte chunks. |
259 | // if size >= 16k gigs, blocksize must be increased. | 264 | // if size >= 16k gigs, blocksize must be increased. |
@@ -269,6 +274,18 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
269 | ) { | 274 | ) { |
270 | bb_error_msg_and_die("blocksize %u is bad", blocksize); | 275 | bb_error_msg_and_die("blocksize %u is bad", blocksize); |
271 | } | 276 | } |
277 | // Do we have custom inode size? | ||
278 | if (opts & OPT_I) { | ||
279 | if (user_inodesize < sizeof(*inode) | ||
280 | || user_inodesize > blocksize | ||
281 | || (user_inodesize & (user_inodesize - 1)) // not power of 2 | ||
282 | ) { | ||
283 | bb_error_msg("-%c is bad", 'I'); | ||
284 | } else { | ||
285 | inodesize = user_inodesize; | ||
286 | } | ||
287 | } | ||
288 | |||
272 | if ((int32_t)bytes_per_inode < blocksize) | 289 | if ((int32_t)bytes_per_inode < blocksize) |
273 | bb_error_msg_and_die("-%c is bad", 'i'); | 290 | bb_error_msg_and_die("-%c is bad", 'i'); |
274 | // number of bits in one block, i.e. 8*blocksize | 291 | // number of bits in one block, i.e. 8*blocksize |
@@ -340,14 +357,10 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
340 | if (inodes_per_group > blocks_per_group) | 357 | if (inodes_per_group > blocks_per_group) |
341 | inodes_per_group = blocks_per_group; | 358 | inodes_per_group = blocks_per_group; |
342 | // adjust inodes per group so they completely fill the inode table blocks in the descriptor | 359 | // adjust inodes per group so they completely fill the inode table blocks in the descriptor |
343 | //incompatibility on images >= 0.5GB: | 360 | inodes_per_group = (div_roundup(inodes_per_group * inodesize, blocksize) * blocksize) / inodesize; |
344 | //difference in sizeof(*inode) sometimes | ||
345 | //results in slightly bigger inodes_per_group here | ||
346 | //compared to standard mke2fs: | ||
347 | inodes_per_group = (div_roundup(inodes_per_group * sizeof(*inode), blocksize) * blocksize) / sizeof(*inode); | ||
348 | // make sure the number of inodes per group is a multiple of 8 | 361 | // make sure the number of inodes per group is a multiple of 8 |
349 | inodes_per_group &= ~7; | 362 | inodes_per_group &= ~7; |
350 | inode_table_blocks = div_roundup(inodes_per_group * sizeof(*inode), blocksize); | 363 | inode_table_blocks = div_roundup(inodes_per_group * inodesize, blocksize); |
351 | 364 | ||
352 | // to be useful, lost+found should occupy at least 2 blocks (but not exceeding 16*1024 bytes), | 365 | // to be useful, lost+found should occupy at least 2 blocks (but not exceeding 16*1024 bytes), |
353 | // and at most EXT2_NDIR_BLOCKS. So reserve these blocks right now | 366 | // and at most EXT2_NDIR_BLOCKS. So reserve these blocks right now |
@@ -434,12 +447,12 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
434 | 447 | ||
435 | // fill the superblock | 448 | // fill the superblock |
436 | sb = xzalloc(1024); | 449 | sb = xzalloc(1024); |
437 | STORE_LE(sb->s_rev_level, 1); // revision 1 filesystem | 450 | STORE_LE(sb->s_rev_level, EXT2_DYNAMIC_REV); // revision 1 filesystem |
438 | STORE_LE(sb->s_magic, EXT2_SUPER_MAGIC); | 451 | STORE_LE(sb->s_magic, EXT2_SUPER_MAGIC); |
439 | //incompatibility: | 452 | STORE_LE(sb->s_inode_size, inodesize); |
440 | //on images > 0.5GB, standard mke2fs uses 256 byte inodes. | 453 | // set "Required extra isize" and "Desired extra isize" fields to 28 |
441 | //we always use 128 byte ones: | 454 | if (inodesize != sizeof(*inode)) |
442 | STORE_LE(sb->s_inode_size, sizeof(*inode)); | 455 | STORE_LE(sb->s_reserved[21], 0x001C001C); |
443 | STORE_LE(sb->s_first_ino, EXT2_GOOD_OLD_FIRST_INO); | 456 | STORE_LE(sb->s_first_ino, EXT2_GOOD_OLD_FIRST_INO); |
444 | STORE_LE(sb->s_log_block_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); | 457 | STORE_LE(sb->s_log_block_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); |
445 | STORE_LE(sb->s_log_frag_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); | 458 | STORE_LE(sb->s_log_frag_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); |
@@ -592,8 +605,8 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
592 | // dump root dir inode | 605 | // dump root dir inode |
593 | STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode | 606 | STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode |
594 | STORE_LE(inode->i_block[0], FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks); | 607 | STORE_LE(inode->i_block[0], FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks); |
595 | PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_ROOT_INO-1) * sizeof(*inode), | 608 | PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_ROOT_INO-1) * inodesize, |
596 | buf, sizeof(*inode)); | 609 | buf, inodesize); |
597 | 610 | ||
598 | // dump lost+found dir inode | 611 | // dump lost+found dir inode |
599 | STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode | 612 | STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode |
@@ -603,8 +616,8 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) | |||
603 | for (i = 0; i < lost_and_found_blocks; ++i) | 616 | for (i = 0; i < lost_and_found_blocks; ++i) |
604 | STORE_LE(inode->i_block[i], i + n); // use next block | 617 | STORE_LE(inode->i_block[i], i + n); // use next block |
605 | //bb_info_msg("LAST BLOCK USED[%u]", i + n); | 618 | //bb_info_msg("LAST BLOCK USED[%u]", i + n); |
606 | PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * sizeof(*inode), | 619 | PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize, |
607 | buf, sizeof(*inode)); | 620 | buf, inodesize); |
608 | 621 | ||
609 | // dump directories | 622 | // dump directories |
610 | memset(buf, 0, blocksize); | 623 | memset(buf, 0, blocksize); |
diff --git a/util-linux/mkfs_ext2.txt b/util-linux/mkfs_ext2.txt index 7c551ea04..273d5b644 100644 --- a/util-linux/mkfs_ext2.txt +++ b/util-linux/mkfs_ext2.txt | |||
@@ -1,5 +1,7 @@ | |||
1 | Difference between bbox mke2fs and standard one (dumpe2fs comparison): | 1 | Difference between bbox mke2fs and standard one (dumpe2fs comparison): |
2 | 2 | ||
3 | [upd: inode size has been fixed since then] | ||
4 | |||
3 | Two significant differences: | 5 | Two significant differences: |
4 | - standard mke2fs has resize_inode feature and thus has reserved GDT blocks, | 6 | - standard mke2fs has resize_inode feature and thus has reserved GDT blocks, |
5 | which decreases free blocks; | 7 | which decreases free blocks; |
diff --git a/util-linux/mkfs_ext2_test.sh b/util-linux/mkfs_ext2_test.sh index 79f8126cd..f5347cc04 100755 --- a/util-linux/mkfs_ext2_test.sh +++ b/util-linux/mkfs_ext2_test.sh | |||
@@ -1,7 +1,7 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | # Disabling features we do not match exactly: | 3 | # Disabling features we do not match exactly: |
4 | system_mke2fs='/sbin/mke2fs -I 128 -O ^resize_inode' | 4 | system_mke2fs='/sbin/mke2fs -O ^resize_inode' |
5 | bbox_mke2fs='./busybox mke2fs' | 5 | bbox_mke2fs='./busybox mke2fs' |
6 | 6 | ||
7 | gen_image() { # params: mke2fs_invocation image_name | 7 | gen_image() { # params: mke2fs_invocation image_name |