aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mkfs_ext2.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-10-18 16:29:30 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-10-18 16:29:30 +0200
commit77da1cae94acbeef90da66bf6530556fe191a6e2 (patch)
tree712db9a18d648b14cc6c7e587e8c4edbe11fd079 /util-linux/mkfs_ext2.c
parentf37eb3999bce2ea46fef0214e33279b81609e596 (diff)
downloadbusybox-w32-77da1cae94acbeef90da66bf6530556fe191a6e2.tar.gz
busybox-w32-77da1cae94acbeef90da66bf6530556fe191a6e2.tar.bz2
busybox-w32-77da1cae94acbeef90da66bf6530556fe191a6e2.zip
mkfs_ext2: make it able to create images larger than 4G
function old new delta mkfs_ext2_main 1904 2145 +241 has_super 29 23 -6 PUT 52 40 -12 packed_usage 26807 26792 -15 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 241/-33) Total: 208 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'util-linux/mkfs_ext2.c')
-rw-r--r--util-linux/mkfs_ext2.c150
1 files changed, 95 insertions, 55 deletions
diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c
index 8df9f1a66..a990668df 100644
--- a/util-linux/mkfs_ext2.c
+++ b/util-linux/mkfs_ext2.c
@@ -77,33 +77,18 @@ static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32
77{ 77{
78 uint32_t i; 78 uint32_t i;
79 memset(bitmap, 0, blocksize); 79 memset(bitmap, 0, blocksize);
80 i = start/8; 80 i = start / 8;
81 memset(bitmap, 0xFF, i); 81 memset(bitmap, 0xFF, i);
82 bitmap[i] = 0xFF >> (8-(start&7)); 82 bitmap[i] = 0xFF >> (8-(start&7));
83//bb_info_msg("ALLOC: [%u][%u][%u]: [%u]:=[%x]", blocksize, start, end, blocksize - end/8 - 1, (uint8_t)(0xFF << (8-(end&7)))); 83//bb_info_msg("ALLOC: [%u][%u][%u]: [%u]:=[%x]", blocksize, start, end, blocksize - end/8 - 1, (uint8_t)(0xFF << (8-(end&7))));
84 i = end/8; 84 i = end / 8;
85 bitmap[blocksize - i - 1] = 0xFF << (8-(end&7)); 85 bitmap[blocksize - i - 1] = 0xFF << (8 - (end & 7));
86 memset(bitmap + blocksize - i, 0xFF, i); // N.B. no overflow here! 86 memset(bitmap + blocksize - i, 0xFF, i); // N.B. no overflow here!
87} 87}
88 88
89#if 0
90// TODO: get rid of FPU
91static bool is_power_of(uint32_t x, uint16_t n)
92{
93// return (!(x % n) && is_power_of(x / n, n));
94 double z = logf(x)/logf(n);
95 return (z == (int)z);
96}
97
98static uint32_t has_super(uint32_t x)
99{
100 return (0 == x || 1 == x || is_power_of(x, 3) || is_power_of(x, 5) || is_power_of(x, 7));
101}
102
103#else
104
105static uint32_t has_super(uint32_t x) 89static uint32_t has_super(uint32_t x)
106{ 90{
91 // 0, 1 and powers of 3, 5, 7 up to 2^32 limit
107 static const uint32_t supers[] = { 92 static const uint32_t supers[] = {
108 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729, 93 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729,
109 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125, 94 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125,
@@ -112,16 +97,15 @@ static uint32_t has_super(uint32_t x)
112 48828125, 129140163, 244140625, 282475249, 387420489, 97 48828125, 129140163, 244140625, 282475249, 387420489,
113 1162261467, 1220703125, 1977326743, 3486784401/* >2^31 */, 98 1162261467, 1220703125, 1977326743, 3486784401/* >2^31 */,
114 }; 99 };
115 const uint32_t *sp = supers + ARRAY_SIZE(supers)-1; 100 const uint32_t *sp = supers + ARRAY_SIZE(supers);
116 while (1) { 101 while (1) {
102 sp--;
117 if (x == *sp) 103 if (x == *sp)
118 return 1; 104 return 1;
119 if (0 == *sp) 105 if (x > *sp)
120 return 0; 106 return 0;
121 sp--;
122 } 107 }
123} 108}
124#endif
125 109
126/* Standard mke2fs 1.41.9: 110/* Standard mke2fs 1.41.9:
127 * Usage: mke2fs [-c|-l filename] [-b block-size] [-f fragment-size] 111 * Usage: mke2fs [-c|-l filename] [-b block-size] [-f fragment-size]
@@ -154,7 +138,7 @@ enum {
154 OPT_T = 1 << 17, 138 OPT_T = 1 << 17,
155 OPT_U = 1 << 18, 139 OPT_U = 1 << 18,
156 OPT_j = 1 << 19, 140 OPT_j = 1 << 19,
157 OPT_n = 1 << 20, 141 OPT_n = 1 << 20, // dry run: do not write anything
158 OPT_q = 1 << 21, 142 OPT_q = 1 << 21,
159 OPT_v = 1 << 22, 143 OPT_v = 1 << 22,
160 OPT_F = 1 << 23, 144 OPT_F = 1 << 23,
@@ -166,17 +150,16 @@ enum {
166 150
167static void PUT(uint64_t off, void *buf, uint32_t size) 151static void PUT(uint64_t off, void *buf, uint32_t size)
168{ 152{
169 if (!(option_mask32 & OPT_n)) { 153// bb_info_msg("PUT[%llu]:[%u]", off, size);
170 xlseek(fd, off, SEEK_SET); 154 xlseek(fd, off, SEEK_SET);
171 xwrite(fd, buf, size); 155 xwrite(fd, buf, size);
172 }
173} 156}
174 157
175int mkfs_ext2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 158int mkfs_ext2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
176int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) 159int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
177{ 160{
178 unsigned i, pos, n; 161 unsigned i, pos, n;
179 unsigned bs, blocksize; 162 unsigned bs, blocksize, blocksize_log2;
180 unsigned nreserved = 5; 163 unsigned nreserved = 5;
181 uint32_t nblocks; 164 uint32_t nblocks;
182 uint32_t ngroups; 165 uint32_t ngroups;
@@ -235,7 +218,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
235 // TODO: 0/5 info printing 218 // TODO: 0/5 info printing
236 // TODO: 2/5 bigendianness! Spot where it comes to play! sb->, gd-> 219 // TODO: 2/5 bigendianness! Spot where it comes to play! sb->, gd->
237 // TODO: 2/5 reserved GDT: how to mark but not allocate? 220 // TODO: 2/5 reserved GDT: how to mark but not allocate?
238 // TODO: 0/5 dir_index? 221 // TODO: 3/5 dir_index?
239 222
240 // fill the superblock 223 // fill the superblock
241 sb = xzalloc(blocksize); 224 sb = xzalloc(blocksize);
@@ -243,13 +226,14 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
243 sb->s_magic = EXT2_SUPER_MAGIC; 226 sb->s_magic = EXT2_SUPER_MAGIC;
244 sb->s_inode_size = sizeof(*inode); 227 sb->s_inode_size = sizeof(*inode);
245 sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO; 228 sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
246 sb->s_log_block_size = sb->s_log_frag_size = int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); 229 blocksize_log2 = int_log2(blocksize);
230 sb->s_log_block_size = sb->s_log_frag_size = blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE;
247 // first 1024 bytes of the device are for boot record. If block size is 1024 bytes, then 231 // first 1024 bytes of the device are for boot record. If block size is 1024 bytes, then
248 // the first block available for data is 1, otherwise 0 232 // the first block available for data is 1, otherwise 0
249 first_data_block = sb->s_first_data_block = (EXT2_MIN_BLOCK_SIZE == blocksize); 233 first_data_block = sb->s_first_data_block = (EXT2_MIN_BLOCK_SIZE == blocksize);
250 // block and inode bitmaps occupy no more than one block, so maximum number of blocks is 234 // block and inode bitmaps occupy no more than one block, so maximum number of blocks is
251 // number of bits in one block, i.e. 8*blocksize 235 // number of bits in one block, i.e. 8*blocksize
252 nblocks_per_group = sb->s_blocks_per_group = sb->s_frags_per_group = sb->s_inodes_per_group = 8*blocksize; 236 nblocks_per_group = sb->s_blocks_per_group = sb->s_frags_per_group = sb->s_inodes_per_group = 8 * blocksize;
253 timestamp = time(NULL); 237 timestamp = time(NULL);
254 sb->s_mkfs_time = sb->s_wtime = sb->s_lastcheck = timestamp; 238 sb->s_mkfs_time = sb->s_wtime = sb->s_lastcheck = timestamp;
255 sb->s_state = 1; 239 sb->s_state = 1;
@@ -266,10 +250,10 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
266 sb->s_feature_ro_compat = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; 250 sb->s_feature_ro_compat = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
267 sb->s_flags = EXT2_FLAGS_SIGNED_HASH * ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX; 251 sb->s_flags = EXT2_FLAGS_SIGNED_HASH * ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX;
268 generate_uuid(sb->s_uuid); 252 generate_uuid(sb->s_uuid);
269#if ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX 253 if (ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX) {
270 sb->s_def_hash_version = EXT2_HASH_HALF_MD4; 254 sb->s_def_hash_version = EXT2_HASH_HALF_MD4;
271 generate_uuid((uint8_t *)sb->s_hash_seed); 255 generate_uuid((uint8_t *)sb->s_hash_seed);
272#endif 256 }
273 /* 257 /*
274 * From e2fsprogs: add "jitter" to the superblock's check interval so that we 258 * From e2fsprogs: add "jitter" to the superblock's check interval so that we
275 * don't check all the filesystems at the same time. We use a 259 * don't check all the filesystems at the same time. We use a
@@ -282,7 +266,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
282 if (argv[1]) { 266 if (argv[1]) {
283 nblocks = xatou(argv[1]); 267 nblocks = xatou(argv[1]);
284 } else { 268 } else {
285 nblocks = ((uoff_t)xlseek(fd, 0, SEEK_END)) / blocksize; 269 nblocks = (uoff_t)xlseek(fd, 0, SEEK_END) >> blocksize_log2;
286 } 270 }
287 sb->s_blocks_count = nblocks; 271 sb->s_blocks_count = nblocks;
288 272
@@ -328,17 +312,17 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
328 if (nblocks < 3*1024) 312 if (nblocks < 3*1024)
329 bytes_per_inode = 8192; 313 bytes_per_inode = 8192;
330 } 314 }
331 ninodes = nblocks / (bytes_per_inode / blocksize); 315 ninodes = nblocks / (bytes_per_inode >> blocksize_log2);
332 if (ninodes < EXT2_GOOD_OLD_FIRST_INO+1) 316 if (ninodes < EXT2_GOOD_OLD_FIRST_INO+1)
333 ninodes = EXT2_GOOD_OLD_FIRST_INO+1; 317 ninodes = EXT2_GOOD_OLD_FIRST_INO+1;
334 ninodes_per_group = div_roundup(ninodes, ngroups); 318 ninodes_per_group = div_roundup(ninodes, ngroups);
335 if (ninodes_per_group < 16) 319 if (ninodes_per_group < 16)
336 ninodes_per_group = 16; // minimum number because the first 10 are reserved 320 ninodes_per_group = 16; // minimum number because the first EXT2_GOOD_OLD_FIRST_INO-1 are reserved
337 // N.B. a block group can have no more than 8*blocksize = sb->s_inodes_per_group inodes 321 // N.B. a block group can have no more than 8*blocksize = sb->s_inodes_per_group inodes
338 if (ninodes_per_group > sb->s_inodes_per_group) 322 if (ninodes_per_group > sb->s_inodes_per_group)
339 ninodes_per_group = sb->s_inodes_per_group; 323 ninodes_per_group = sb->s_inodes_per_group;
340 // adjust inodes per group so they completely fill the inode table blocks in the descriptor 324 // adjust inodes per group so they completely fill the inode table blocks in the descriptor
341 ninodes_per_group = ((div_roundup(ninodes_per_group * EXT2_INODE_SIZE(sb), blocksize) * blocksize) / EXT2_INODE_SIZE(sb)); 325 ninodes_per_group = (div_roundup(ninodes_per_group * EXT2_INODE_SIZE(sb), blocksize) << blocksize_log2) / EXT2_INODE_SIZE(sb);
342 // make sure the number of inodes per group is a multiple of 8 326 // make sure the number of inodes per group is a multiple of 8
343 ninodes_per_group &= ~7; 327 ninodes_per_group &= ~7;
344 sb->s_inodes_per_group = ninodes_per_group;// = div_roundup(ninodes_per_group * sb->s_inode_size, blocksize); 328 sb->s_inodes_per_group = ninodes_per_group;// = div_roundup(ninodes_per_group * sb->s_inode_size, blocksize);
@@ -352,6 +336,52 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
352 if (opts & OPT_L) 336 if (opts & OPT_L)
353 safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name)); 337 safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name));
354 338
339#if 1
340/* if (fs_param.s_blocks_count != s->s_blocks_count)
341 fprintf(stderr, _("warning: %u blocks unused.\n\n"),
342 fs_param.s_blocks_count - s->s_blocks_count);
343*/
344
345 printf(
346 "Filesystem label=%s\n"
347 "OS type: Linux\n"
348 "Block size=%u (log=%u)\n"
349 "Fragment size=%u (log=%u)\n"
350 "%u inodes, %u blocks\n"
351 "%u blocks (%u%%) reserved for the super user\n"
352 "First data block=%u\n"
353// "Maximum filesystem blocks=%lu\n"
354 "%u block groups\n"
355 "%u blocks per group, %u fragments per group\n"
356 "%u inodes per group"
357 , (char *)sb->s_volume_name
358 , blocksize, sb->s_log_block_size
359 , blocksize, sb->s_log_block_size
360 , sb->s_inodes_count, sb->s_blocks_count
361 , sb->s_r_blocks_count, nreserved
362 , first_data_block
363// , (rgdtsz + gdtsz) * EXT2_DESC_PER_BLOCK(sb) * nblocks_per_group
364 , ngroups
365 , nblocks_per_group, nblocks_per_group
366 , ninodes_per_group
367 );
368 {
369 const char *fmt = "\nSuperblock backups stored on blocks: %u";
370 pos = first_data_block;
371 for (i = 1; i < ngroups; i++) {
372 pos += nblocks_per_group;
373 if (has_super(i)) {
374 printf(fmt, (unsigned)pos);
375 fmt = ", %u";
376 }
377 }
378 }
379 bb_putchar('\n');
380#endif
381
382 if (opts & OPT_n)
383 return EXIT_SUCCESS;
384
355 // fill group descriptors 385 // fill group descriptors
356 gd = xzalloc((gdtsz + rgdtsz) * blocksize); 386 gd = xzalloc((gdtsz + rgdtsz) * blocksize);
357 sb->s_free_blocks_count = 0; 387 sb->s_free_blocks_count = 0;
@@ -365,8 +395,8 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
365 gd[i].bg_inode_table = overhead + 2; 395 gd[i].bg_inode_table = overhead + 2;
366 overhead = overhead - pos + 1/*bbmp*/ + 1/*ibmp*/ + itsz; 396 overhead = overhead - pos + 1/*bbmp*/ + 1/*ibmp*/ + itsz;
367 gd[i].bg_free_inodes_count = ninodes_per_group; 397 gd[i].bg_free_inodes_count = ninodes_per_group;
368 // N.B. both root and lost+found dirs are within the first block group, thus +2
369 //gd[i].bg_used_dirs_count = 0; 398 //gd[i].bg_used_dirs_count = 0;
399 // N.B. both root and lost+found dirs are within the first block group, thus +2
370 if (0 == i) { 400 if (0 == i) {
371 overhead += 2; 401 overhead += 2;
372 gd[i].bg_used_dirs_count = 2; 402 gd[i].bg_used_dirs_count = 2;
@@ -383,6 +413,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
383 STORE_LE(sb->s_free_blocks_count, sb->s_free_blocks_count); 413 STORE_LE(sb->s_free_blocks_count, sb->s_free_blocks_count);
384 414
385 // dump filesystem skeleton structures 415 // dump filesystem skeleton structures
416// printf("Writing superblocks and filesystem accounting information: ");
386 buf = xmalloc(blocksize); 417 buf = xmalloc(blocksize);
387 for (i = 0, pos = first_data_block; i < ngroups; i++, pos += nblocks_per_group) { 418 for (i = 0, pos = first_data_block; i < ngroups; i++, pos += nblocks_per_group) {
388 uint32_t overhead = has_super(i) ? (1/*sb*/ + gdtsz + rgdtsz) : 0; 419 uint32_t overhead = has_super(i) ? (1/*sb*/ + gdtsz + rgdtsz) : 0;
@@ -391,28 +422,30 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
391 422
392 // dump superblock and group descriptors and their backups 423 // dump superblock and group descriptors and their backups
393 if (overhead) { // N.B. in fact, we want (has_super(i)) condition, but it is equal to (overhead != 0) and is cheaper 424 if (overhead) { // N.B. in fact, we want (has_super(i)) condition, but it is equal to (overhead != 0) and is cheaper
394//bb_info_msg("SUPER@[%d]", pos);
395 // N.B. 1024 byte blocks are special 425 // N.B. 1024 byte blocks are special
396 PUT(blocksize * pos + ((0 == i && 0 == first_data_block) ? 1024 : 0), sb, blocksize); 426 PUT(((uint64_t)pos << blocksize_log2) + ((0 == i && 0 == first_data_block) ? 1024 : 0), sb, 1024);//blocksize);
397 PUT(blocksize * pos + blocksize, gd, (gdtsz + rgdtsz) * blocksize); 427 PUT(((uint64_t)pos << blocksize_log2) + blocksize, gd, (gdtsz + rgdtsz) * blocksize);
398 } 428 }
399 429
400 start = overhead + 1/*bbmp*/ + 1/*ibmp*/ + itsz; 430 start = overhead + 1/*bbmp*/ + 1/*ibmp*/ + itsz;
401 if (i == 0) 431 if (i == 0)
402 start += 2; // for / and /lost+found 432 start += 2; // for "/" and "/lost+found"
403 end = nblocks_per_group - (start + gd[i].bg_free_blocks_count); 433 end = nblocks_per_group - (start + gd[i].bg_free_blocks_count);
434
404 // mark preallocated blocks as allocated 435 // mark preallocated blocks as allocated
405 allocate(buf, blocksize, start, end); 436 allocate(buf, blocksize, start, end);
406 // dump block bitmap 437 // dump block bitmap
407 PUT((pos + overhead) * blocksize, buf, blocksize); 438 PUT((uint64_t)(pos + overhead) * blocksize, buf, blocksize);
408 439
409 // mark preallocated inodes as allocated 440 // mark preallocated inodes as allocated
410 allocate(buf, blocksize, 441 allocate(buf, blocksize,
411 ninodes_per_group - gd[i].bg_free_inodes_count, 442 ninodes_per_group - gd[i].bg_free_inodes_count,
412 8*blocksize - ninodes_per_group 443 8 * blocksize - ninodes_per_group
413 ); 444 );
414 // dump inode bitmap 445 // dump inode bitmap
415 PUT((pos + overhead + 1) * blocksize, buf, blocksize); 446 //PUT((uint64_t)(pos + overhead + 1) * blocksize, buf, blocksize);
447 //but it's right after block bitmap, so we can just:
448 xwrite(fd, buf, blocksize);
416 } 449 }
417 450
418 // zero boot sectors 451 // zero boot sectors
@@ -421,12 +454,13 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
421 // zero inode tables 454 // zero inode tables
422 for (i = 0; i < ngroups; ++i) 455 for (i = 0; i < ngroups; ++i)
423 for (n = 0; n < itsz; ++n) 456 for (n = 0; n < itsz; ++n)
424 PUT((gd[i].bg_inode_table + n) * blocksize, buf, blocksize); 457 PUT((uint64_t)(gd[i].bg_inode_table + n) * blocksize, buf, blocksize);
425 458
426 // prepare directory inode 459 // prepare directory inode
427 inode = (struct ext2_inode *)buf; 460 inode = (struct ext2_inode *)buf;
428 STORE_LE(inode->i_mode, S_IFDIR | S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH); 461 STORE_LE(inode->i_mode, S_IFDIR | S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH);
429 inode->i_mtime = inode->i_atime = timestamp; 462 STORE_LE(inode->i_mtime, timestamp);
463 STORE_LE(inode->i_atime, timestamp);
430 STORE_LE(inode->i_ctime, timestamp); 464 STORE_LE(inode->i_ctime, timestamp);
431 STORE_LE(inode->i_size, blocksize); 465 STORE_LE(inode->i_size, blocksize);
432 // N.B. inode->i_blocks stores the number of 512 byte data blocks. Why on Earth?! 466 // N.B. inode->i_blocks stores the number of 512 byte data blocks. Why on Earth?!
@@ -435,12 +469,12 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
435 // dump root dir inode 469 // dump root dir inode
436 STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode 470 STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode
437 STORE_LE(inode->i_block[0], gd[0].bg_inode_table + itsz); 471 STORE_LE(inode->i_block[0], gd[0].bg_inode_table + itsz);
438 PUT(gd[0].bg_inode_table * blocksize + (EXT2_ROOT_INO-1) * sizeof(*inode), buf, sizeof(*inode)); 472 PUT(((uint64_t)gd[0].bg_inode_table << blocksize_log2) + (EXT2_ROOT_INO-1) * sizeof(*inode), buf, sizeof(*inode));
439 473
440 // dump lost+found dir inode 474 // dump lost+found dir inode
441 STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode 475 STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode
442 STORE_LE(inode->i_block[0], inode->i_block[0]+1); // use next block //= gd[0].bg_inode_table + itsz + 1; 476 STORE_LE(inode->i_block[0], inode->i_block[0]+1); // use next block //= gd[0].bg_inode_table + itsz + 1;
443 PUT(gd[0].bg_inode_table * blocksize + (EXT2_GOOD_OLD_FIRST_INO-1) * sizeof(*inode), buf, sizeof(*inode)); 477 PUT(((uint64_t)gd[0].bg_inode_table << blocksize_log2) + (EXT2_GOOD_OLD_FIRST_INO-1) * sizeof(*inode), buf, sizeof(*inode));
444 478
445 // dump directories 479 // dump directories
446 memset(buf, 0, blocksize); 480 memset(buf, 0, blocksize);
@@ -457,7 +491,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
457 STORE_LE(dir->name_len2, 2); 491 STORE_LE(dir->name_len2, 2);
458 STORE_LE(dir->file_type2, EXT2_FT_DIR); 492 STORE_LE(dir->file_type2, EXT2_FT_DIR);
459 dir->name2[0] = '.'; dir->name2[1] = '.'; 493 dir->name2[0] = '.'; dir->name2[1] = '.';
460 PUT((gd[0].bg_inode_table + itsz + 1) * blocksize, buf, blocksize); 494 PUT((uint64_t)(gd[0].bg_inode_table + itsz + 1) * blocksize, buf, blocksize);
461 495
462 // dump root dir block 496 // dump root dir block
463 STORE_LE(dir->inode1, EXT2_ROOT_INO); 497 STORE_LE(dir->inode1, EXT2_ROOT_INO);
@@ -467,15 +501,21 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
467 STORE_LE(dir->name_len3, 10); 501 STORE_LE(dir->name_len3, 10);
468 STORE_LE(dir->file_type3, EXT2_FT_DIR); 502 STORE_LE(dir->file_type3, EXT2_FT_DIR);
469 strcpy(dir->name3, "lost+found"); 503 strcpy(dir->name3, "lost+found");
470 PUT((gd[0].bg_inode_table + itsz + 0) * blocksize, buf, blocksize); 504 PUT((uint64_t)(gd[0].bg_inode_table + itsz + 0) * blocksize, buf, blocksize);
505
506// bb_info_msg("done\n"
507// "This filesystem will be automatically checked every %u mounts or\n"
508// "%u days, whichever comes first. Use tune2fs -c or -i to override.",
509// sb->s_max_mnt_count, sb->s_checkinterval / (3600 * 24)
510// );
471 511
472 // cleanup 512 // cleanup
473 if (ENABLE_FEATURE_CLEAN_UP) { 513 if (ENABLE_FEATURE_CLEAN_UP) {
474 free(buf); 514 free(buf);
475 free(gd); 515 free(gd);
476 free(sb); 516 free(sb);
477 close(fd);
478 } 517 }
479 518
519 xclose(fd);
480 return EXIT_SUCCESS; 520 return EXIT_SUCCESS;
481} 521}