work around linux/ext2_fs.h breakage
[platform/upstream/busybox.git] / util-linux / mkfs_ext2.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * mkfs_ext2: utility to create EXT2 filesystem
4  * inspired by genext2fs
5  *
6  * Busybox'ed (2009) by Vladimir Dronnikov <dronnikov@gmail.com>
7  *
8  * Licensed under GPLv2, see file LICENSE in this source tree.
9  */
10
11 //usage:#define mkfs_ext2_trivial_usage
12 //usage:       "[-Fn] "
13 /* //usage:    "[-c|-l filename] " */
14 //usage:       "[-b BLK_SIZE] "
15 /* //usage:    "[-f fragment-size] [-g blocks-per-group] " */
16 //usage:       "[-i INODE_RATIO] [-I INODE_SIZE] "
17 /* //usage:    "[-j] [-J journal-options] [-N number-of-inodes] " */
18 //usage:       "[-m RESERVED_PERCENT] "
19 /* //usage:    "[-o creator-os] [-O feature[,...]] [-q] " */
20 /* //usage:    "[r fs-revision-level] [-E extended-options] [-v] [-F] " */
21 //usage:       "[-L LABEL] "
22 /* //usage:    "[-M last-mounted-directory] [-S] [-T filesystem-type] " */
23 //usage:       "BLOCKDEV [KBYTES]"
24 //usage:#define mkfs_ext2_full_usage "\n\n"
25 //usage:       "        -b BLK_SIZE     Block size, bytes"
26 /* //usage:  "\n        -c              Check device for bad blocks" */
27 /* //usage:  "\n        -E opts         Set extended options" */
28 /* //usage:  "\n        -f size         Fragment size in bytes" */
29 //usage:     "\n        -F              Force"
30 /* //usage:  "\n        -g N            Number of blocks in a block group" */
31 //usage:     "\n        -i RATIO        Max number of files is filesystem_size / RATIO"
32 //usage:     "\n        -I BYTES        Inode size (min 128)"
33 /* //usage:  "\n        -j              Create a journal (ext3)" */
34 /* //usage:  "\n        -J opts         Set journal options (size/device)" */
35 /* //usage:  "\n        -l file         Read bad blocks list from file" */
36 //usage:     "\n        -L LBL          Volume label"
37 //usage:     "\n        -m PERCENT      Percent of blocks to reserve for admin"
38 /* //usage:  "\n        -M dir          Set last mounted directory" */
39 //usage:     "\n        -n              Dry run"
40 /* //usage:  "\n        -N N            Number of inodes to create" */
41 /* //usage:  "\n        -o os           Set the 'creator os' field" */
42 /* //usage:  "\n        -O features     Dir_index/filetype/has_journal/journal_dev/sparse_super" */
43 /* //usage:  "\n        -q              Quiet" */
44 /* //usage:  "\n        -r rev          Set filesystem revision" */
45 /* //usage:  "\n        -S              Write superblock and group descriptors only" */
46 /* //usage:  "\n        -T fs-type      Set usage type (news/largefile/largefile4)" */
47 /* //usage:  "\n        -v              Verbose" */
48
49 #include "libbb.h"
50 #include <linux/fs.h>
51 /*
52  * Work around linux/ext2_fs.h breakage.
53  * See https://bugzilla.kernel.org/show_bug.cgi?id=42986.
54  */
55 typedef mode_t bb__umode_t;
56 #define umode_t bb__umode_t
57 #include <linux/ext2_fs.h>
58
59 #define ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT 0
60 #define ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX    1
61
62 // from e2fsprogs
63 #define s_reserved_gdt_blocks s_padding1
64 #define s_mkfs_time           s_reserved[0]
65 #define s_flags               s_reserved[22]
66
67 #define EXT2_HASH_HALF_MD4       1
68 #define EXT2_FLAGS_SIGNED_HASH   0x0001
69 #define EXT2_FLAGS_UNSIGNED_HASH 0x0002
70
71 // storage helpers
72 char BUG_wrong_field_size(void);
73 #define STORE_LE(field, value) \
74 do { \
75         if (sizeof(field) == 4) \
76                 field = SWAP_LE32(value); \
77         else if (sizeof(field) == 2) \
78                 field = SWAP_LE16(value); \
79         else if (sizeof(field) == 1) \
80                 field = (value); \
81         else \
82                 BUG_wrong_field_size(); \
83 } while (0)
84
85 #define FETCH_LE32(field) \
86         (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size())
87
88 // All fields are little-endian
89 struct ext2_dir {
90         uint32_t inode1;
91         uint16_t rec_len1;
92         uint8_t  name_len1;
93         uint8_t  file_type1;
94         char     name1[4];
95         uint32_t inode2;
96         uint16_t rec_len2;
97         uint8_t  name_len2;
98         uint8_t  file_type2;
99         char     name2[4];
100         uint32_t inode3;
101         uint16_t rec_len3;
102         uint8_t  name_len3;
103         uint8_t  file_type3;
104         char     name3[12];
105 };
106
107 static unsigned int_log2(unsigned arg)
108 {
109         unsigned r = 0;
110         while ((arg >>= 1) != 0)
111                 r++;
112         return r;
113 }
114
115 // taken from mkfs_minix.c. libbb candidate?
116 // "uint32_t size", since we never use it for anything >32 bits
117 static uint32_t div_roundup(uint32_t size, uint32_t n)
118 {
119         // Overflow-resistant
120         uint32_t res = size / n;
121         if (res * n != size)
122                 res++;
123         return res;
124 }
125
126 static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32_t end)
127 {
128         uint32_t i;
129
130 //bb_info_msg("ALLOC: [%u][%u][%u]: [%u-%u]:=[%x],[%x]", blocksize, start, end, start/8, blocksize - end/8 - 1, (1 << (start & 7)) - 1, (uint8_t)(0xFF00 >> (end & 7)));
131         memset(bitmap, 0, blocksize);
132         i = start / 8;
133         memset(bitmap, 0xFF, i);
134         bitmap[i] = (1 << (start & 7)) - 1; //0..7 => 00000000..01111111
135         i = end / 8;
136         bitmap[blocksize - i - 1] |= 0x7F00 >> (end & 7); //0..7 => 00000000..11111110
137         memset(bitmap + blocksize - i, 0xFF, i); // N.B. no overflow here!
138 }
139
140 static uint32_t has_super(uint32_t x)
141 {
142         // 0, 1 and powers of 3, 5, 7 up to 2^32 limit
143         static const uint32_t supers[] = {
144                 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729,
145                 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125,
146                 117649, 177147, 390625, 531441, 823543, 1594323, 1953125,
147                 4782969, 5764801, 9765625, 14348907, 40353607, 43046721,
148                 48828125, 129140163, 244140625, 282475249, 387420489,
149                 1162261467, 1220703125, 1977326743, 3486784401/* >2^31 */,
150         };
151         const uint32_t *sp = supers + ARRAY_SIZE(supers);
152         while (1) {
153                 sp--;
154                 if (x == *sp)
155                         return 1;
156                 if (x > *sp)
157                         return 0;
158         }
159 }
160
161 #define fd 3    /* predefined output descriptor */
162
163 static void PUT(uint64_t off, void *buf, uint32_t size)
164 {
165 //      bb_info_msg("PUT[%llu]:[%u]", off, size);
166         xlseek(fd, off, SEEK_SET);
167         xwrite(fd, buf, size);
168 }
169
170 // 128 and 256-byte inodes:
171 // 128-byte inode is described by struct ext2_inode.
172 // 256-byte one just has these fields appended:
173 //      __u16   i_extra_isize;
174 //      __u16   i_pad1;
175 //      __u32   i_ctime_extra;  /* extra Change time (nsec << 2 | epoch) */
176 //      __u32   i_mtime_extra;  /* extra Modification time (nsec << 2 | epoch) */
177 //      __u32   i_atime_extra;  /* extra Access time (nsec << 2 | epoch) */
178 //      __u32   i_crtime;       /* File creation time */
179 //      __u32   i_crtime_extra; /* extra File creation time (nsec << 2 | epoch)*/
180 //      __u32   i_version_hi;   /* high 32 bits for 64-bit version */
181 // the rest is padding.
182 //
183 // linux/ext2_fs.h has "#define i_size_high i_dir_acl" which suggests that even
184 // 128-byte inode is capable of describing large files (i_dir_acl is meaningful
185 // only for directories, which never need i_size_high).
186 //
187 // Standard mke2fs creates a filesystem with 256-byte inodes if it is
188 // bigger than 0.5GB.
189
190 // Standard mke2fs 1.41.9:
191 // Usage: mke2fs [-c|-l filename] [-b block-size] [-f fragment-size]
192 //      [-i bytes-per-inode] [-I inode-size] [-J journal-options]
193 //      [-G meta group size] [-N number-of-inodes]
194 //      [-m reserved-blocks-percentage] [-o creator-os]
195 //      [-g blocks-per-group] [-L volume-label] [-M last-mounted-directory]
196 //      [-O feature[,...]] [-r fs-revision] [-E extended-option[,...]]
197 //      [-T fs-type] [-U UUID] [-jnqvFSV] device [blocks-count]
198 //
199 // Options not commented below are taken but silently ignored:
200 enum {
201         OPT_c = 1 << 0,
202         OPT_l = 1 << 1,
203         OPT_b = 1 << 2,         // block size, in bytes
204         OPT_f = 1 << 3,
205         OPT_i = 1 << 4,         // bytes per inode
206         OPT_I = 1 << 5,         // custom inode size, in bytes
207         OPT_J = 1 << 6,
208         OPT_G = 1 << 7,
209         OPT_N = 1 << 8,
210         OPT_m = 1 << 9,         // percentage of blocks reserved for superuser
211         OPT_o = 1 << 10,
212         OPT_g = 1 << 11,
213         OPT_L = 1 << 12,        // label
214         OPT_M = 1 << 13,
215         OPT_O = 1 << 14,
216         OPT_r = 1 << 15,
217         OPT_E = 1 << 16,
218         OPT_T = 1 << 17,
219         OPT_U = 1 << 18,
220         OPT_j = 1 << 19,
221         OPT_n = 1 << 20,        // dry run: do not write anything
222         OPT_q = 1 << 21,
223         OPT_v = 1 << 22,
224         OPT_F = 1 << 23,
225         OPT_S = 1 << 24,
226         //OPT_V = 1 << 25,      // -V version. bbox applets don't support that
227 };
228
229 int mkfs_ext2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
230 int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
231 {
232         unsigned i, pos, n;
233         unsigned bs, bpi;
234         unsigned blocksize, blocksize_log2;
235         unsigned inodesize, user_inodesize;
236         unsigned reserved_percent = 5;
237         unsigned long long kilobytes;
238         uint32_t nblocks, nblocks_full;
239         uint32_t nreserved;
240         uint32_t ngroups;
241         uint32_t bytes_per_inode;
242         uint32_t first_block;
243         uint32_t inodes_per_group;
244         uint32_t group_desc_blocks;
245         uint32_t inode_table_blocks;
246         uint32_t lost_and_found_blocks;
247         time_t timestamp;
248         const char *label = "";
249         struct stat st;
250         struct ext2_super_block *sb; // superblock
251         struct ext2_group_desc *gd; // group descriptors
252         struct ext2_inode *inode;
253         struct ext2_dir *dir;
254         uint8_t *buf;
255
256         // using global "option_mask32" instead of local "opts":
257         // we are register starved here
258         opt_complementary = "-1:b+:i+:I+:m+";
259         /*opts =*/ getopt32(argv, "cl:b:f:i:I:J:G:N:m:o:g:L:M:O:r:E:T:U:jnqvFS",
260                 /*lbfi:*/ NULL, &bs, NULL, &bpi,
261                 /*IJGN:*/ &user_inodesize, NULL, NULL, NULL,
262                 /*mogL:*/ &reserved_percent, NULL, NULL, &label,
263                 /*MOrE:*/ NULL, NULL, NULL, NULL,
264                 /*TU:*/ NULL, NULL);
265         argv += optind; // argv[0] -- device
266
267         // open the device, check the device is a block device
268         xmove_fd(xopen(argv[0], O_WRONLY), fd);
269         xfstat(fd, &st, argv[0]);
270         if (!S_ISBLK(st.st_mode) && !(option_mask32 & OPT_F))
271                 bb_error_msg_and_die("%s: not a block device", argv[0]);
272
273         // check if it is mounted
274         // N.B. what if we format a file? find_mount_point will return false negative since
275         // it is loop block device which is mounted!
276         if (find_mount_point(argv[0], 0))
277                 bb_error_msg_and_die("can't format mounted filesystem");
278
279         // get size in kbytes
280         kilobytes = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ !(option_mask32 & OPT_n)) / 1024;
281
282         bytes_per_inode = 16384;
283         if (kilobytes < 512*1024)
284                 bytes_per_inode = 4096;
285         if (kilobytes < 3*1024)
286                 bytes_per_inode = 8192;
287         if (option_mask32 & OPT_i)
288                 bytes_per_inode = bpi;
289
290         // Determine block size and inode size
291         // block size is a multiple of 1024
292         // inode size is a multiple of 128
293         blocksize = 1024;
294         inodesize = sizeof(struct ext2_inode); // 128
295         if (kilobytes >= 512*1024) { // mke2fs 1.41.9 compat
296                 blocksize = 4096;
297                 inodesize = 256;
298         }
299         if (EXT2_MAX_BLOCK_SIZE > 4096) {
300                 // kilobytes >> 22 == size in 4gigabyte chunks.
301                 // if size >= 16k gigs, blocksize must be increased.
302                 // Try "mke2fs -F image $((16 * 1024*1024*1024))"
303                 while ((kilobytes >> 22) >= blocksize)
304                         blocksize *= 2;
305         }
306         if (option_mask32 & OPT_b)
307                 blocksize = bs;
308         if (blocksize < EXT2_MIN_BLOCK_SIZE
309          || blocksize > EXT2_MAX_BLOCK_SIZE
310          || (blocksize & (blocksize - 1)) // not power of 2
311         ) {
312                 bb_error_msg_and_die("blocksize %u is bad", blocksize);
313         }
314         // Do we have custom inode size?
315         if (option_mask32 & OPT_I) {
316                 if (user_inodesize < sizeof(*inode)
317                  || user_inodesize > blocksize
318                  || (user_inodesize & (user_inodesize - 1)) // not power of 2
319                 ) {
320                         bb_error_msg("-%c is bad", 'I');
321                 } else {
322                         inodesize = user_inodesize;
323                 }
324         }
325
326         if ((int32_t)bytes_per_inode < blocksize)
327                 bb_error_msg_and_die("-%c is bad", 'i');
328         // number of bits in one block, i.e. 8*blocksize
329 #define blocks_per_group (8 * blocksize)
330         first_block = (EXT2_MIN_BLOCK_SIZE == blocksize);
331         blocksize_log2 = int_log2(blocksize);
332
333         // Determine number of blocks
334         kilobytes >>= (blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
335         nblocks = kilobytes;
336         if (nblocks != kilobytes)
337                 bb_error_msg_and_die("block count doesn't fit in 32 bits");
338 #define kilobytes kilobytes_unused_after_this
339         // Experimentally, standard mke2fs won't work on images smaller than 60k
340         if (nblocks < 60)
341                 bb_error_msg_and_die("need >= 60 blocks");
342
343         // How many reserved blocks?
344         if (reserved_percent > 50)
345                 bb_error_msg_and_die("-%c is bad", 'm');
346         nreserved = (uint64_t)nblocks * reserved_percent / 100;
347
348         // N.B. killing e2fsprogs feature! Unused blocks don't account in calculations
349         nblocks_full = nblocks;
350
351         // If last block group is too small, nblocks may be decreased in order
352         // to discard it, and control returns here to recalculate some
353         // parameters.
354         // Note: blocksize and bytes_per_inode are never recalculated.
355  retry:
356         // N.B. a block group can have no more than blocks_per_group blocks
357         ngroups = div_roundup(nblocks - first_block, blocks_per_group);
358
359         group_desc_blocks = div_roundup(ngroups, blocksize / sizeof(*gd));
360         // TODO: reserved blocks must be marked as such in the bitmaps,
361         // or resulting filesystem is corrupt
362         if (ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT) {
363                 /*
364                  * From e2fsprogs: Calculate the number of GDT blocks to reserve for online
365                  * filesystem growth.
366                  * The absolute maximum number of GDT blocks we can reserve is determined by
367                  * the number of block pointers that can fit into a single block.
368                  * We set it at 1024x the current filesystem size, or
369                  * the upper block count limit (2^32), whichever is lower.
370                  */
371                 uint32_t reserved_group_desc_blocks = 0xFFFFFFFF; // maximum block number
372                 if (nblocks < reserved_group_desc_blocks / 1024)
373                         reserved_group_desc_blocks = nblocks * 1024;
374                 reserved_group_desc_blocks = div_roundup(reserved_group_desc_blocks - first_block, blocks_per_group);
375                 reserved_group_desc_blocks = div_roundup(reserved_group_desc_blocks, blocksize / sizeof(*gd)) - group_desc_blocks;
376                 if (reserved_group_desc_blocks > blocksize / sizeof(uint32_t))
377                         reserved_group_desc_blocks = blocksize / sizeof(uint32_t);
378                 //TODO: STORE_LE(sb->s_reserved_gdt_blocks, reserved_group_desc_blocks);
379                 group_desc_blocks += reserved_group_desc_blocks;
380         }
381
382         {
383                 // N.B. e2fsprogs does as follows!
384                 uint32_t overhead, remainder;
385                 // ninodes is the max number of inodes in this filesystem
386                 uint32_t ninodes = ((uint64_t) nblocks_full * blocksize) / bytes_per_inode;
387                 if (ninodes < EXT2_GOOD_OLD_FIRST_INO+1)
388                         ninodes = EXT2_GOOD_OLD_FIRST_INO+1;
389                 inodes_per_group = div_roundup(ninodes, ngroups);
390                 // minimum number because the first EXT2_GOOD_OLD_FIRST_INO-1 are reserved
391                 if (inodes_per_group < 16)
392                         inodes_per_group = 16;
393                 // a block group can't have more inodes than blocks
394                 if (inodes_per_group > blocks_per_group)
395                         inodes_per_group = blocks_per_group;
396                 // adjust inodes per group so they completely fill the inode table blocks in the descriptor
397                 inodes_per_group = (div_roundup(inodes_per_group * inodesize, blocksize) * blocksize) / inodesize;
398                 // make sure the number of inodes per group is a multiple of 8
399                 inodes_per_group &= ~7;
400                 inode_table_blocks = div_roundup(inodes_per_group * inodesize, blocksize);
401
402                 // to be useful, lost+found should occupy at least 2 blocks (but not exceeding 16*1024 bytes),
403                 // and at most EXT2_NDIR_BLOCKS. So reserve these blocks right now
404                 /* Or e2fsprogs comment verbatim (what does it mean?):
405                  * Ensure that lost+found is at least 2 blocks, so we always
406                  * test large empty blocks for big-block filesystems. */
407                 lost_and_found_blocks = MIN(EXT2_NDIR_BLOCKS, 16 >> (blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE));
408
409                 // the last group needs more attention: isn't it too small for possible overhead?
410                 overhead = (has_super(ngroups - 1) ? (1/*sb*/ + group_desc_blocks) : 0) + 1/*bbmp*/ + 1/*ibmp*/ + inode_table_blocks;
411                 remainder = (nblocks - first_block) % blocks_per_group;
412                 ////can't happen, nblocks >= 60 guarantees this
413                 ////if ((1 == ngroups)
414                 //// && remainder
415                 //// && (remainder < overhead + 1/* "/" */ + lost_and_found_blocks)
416                 ////) {
417                 ////    bb_error_msg_and_die("way small device");
418                 ////}
419
420                 // Standard mke2fs uses 50. Looks like a bug in our calculation
421                 // of "remainder" or "overhead" - we don't match standard mke2fs
422                 // when we transition from one group to two groups
423                 // (a bit after 8M image size), but it works for two->three groups
424                 // transition (at 16M).
425                 if (remainder && (remainder < overhead + 50)) {
426 //bb_info_msg("CHOP[%u]", remainder);
427                         nblocks -= remainder;
428                         goto retry;
429                 }
430         }
431
432         if (nblocks_full - nblocks)
433                 printf("warning: %u blocks unused\n\n", nblocks_full - nblocks);
434         printf(
435                 "Filesystem label=%s\n"
436                 "OS type: Linux\n"
437                 "Block size=%u (log=%u)\n"
438                 "Fragment size=%u (log=%u)\n"
439                 "%u inodes, %u blocks\n"
440                 "%u blocks (%u%%) reserved for the super user\n"
441                 "First data block=%u\n"
442                 "Maximum filesystem blocks=%u\n"
443                 "%u block groups\n"
444                 "%u blocks per group, %u fragments per group\n"
445                 "%u inodes per group"
446                 , label
447                 , blocksize, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE
448                 , blocksize, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE
449                 , inodes_per_group * ngroups, nblocks
450                 , nreserved, reserved_percent
451                 , first_block
452                 , group_desc_blocks * (blocksize / (unsigned)sizeof(*gd)) * blocks_per_group
453                 , ngroups
454                 , blocks_per_group, blocks_per_group
455                 , inodes_per_group
456         );
457         {
458                 const char *fmt = "\nSuperblock backups stored on blocks:\n"
459                         "\t%u";
460                 pos = first_block;
461                 for (i = 1; i < ngroups; i++) {
462                         pos += blocks_per_group;
463                         if (has_super(i)) {
464                                 printf(fmt, (unsigned)pos);
465                                 fmt = ", %u";
466                         }
467                 }
468         }
469         bb_putchar('\n');
470
471         if (option_mask32 & OPT_n) {
472                 if (ENABLE_FEATURE_CLEAN_UP)
473                         close(fd);
474                 return EXIT_SUCCESS;
475         }
476
477         // TODO: 3/5 refuse if mounted
478         // TODO: 4/5 compat options
479         // TODO: 1/5 sanity checks
480         // TODO: 0/5 more verbose error messages
481         // TODO: 4/5 bigendianness: recheck, wait for ARM reporters
482         // TODO: 2/5 reserved GDT: how to mark but not allocate?
483         // TODO: 3/5 dir_index?
484
485         // fill the superblock
486         sb = xzalloc(1024);
487         STORE_LE(sb->s_rev_level, EXT2_DYNAMIC_REV); // revision 1 filesystem
488         STORE_LE(sb->s_magic, EXT2_SUPER_MAGIC);
489         STORE_LE(sb->s_inode_size, inodesize);
490         // set "Required extra isize" and "Desired extra isize" fields to 28
491         if (inodesize != sizeof(*inode))
492                 STORE_LE(sb->s_reserved[21], 0x001C001C);
493         STORE_LE(sb->s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
494         STORE_LE(sb->s_log_block_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
495         STORE_LE(sb->s_log_frag_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
496         // first 1024 bytes of the device are for boot record. If block size is 1024 bytes, then
497         // the first block is 1, otherwise 0
498         STORE_LE(sb->s_first_data_block, first_block);
499         // block and inode bitmaps occupy no more than one block, so maximum number of blocks is
500         STORE_LE(sb->s_blocks_per_group, blocks_per_group);
501         STORE_LE(sb->s_frags_per_group, blocks_per_group);
502         // blocks
503         STORE_LE(sb->s_blocks_count, nblocks);
504         // reserve blocks for superuser
505         STORE_LE(sb->s_r_blocks_count, nreserved);
506         // ninodes
507         STORE_LE(sb->s_inodes_per_group, inodes_per_group);
508         STORE_LE(sb->s_inodes_count, inodes_per_group * ngroups);
509         STORE_LE(sb->s_free_inodes_count, inodes_per_group * ngroups - EXT2_GOOD_OLD_FIRST_INO);
510         // timestamps
511         timestamp = time(NULL);
512         STORE_LE(sb->s_mkfs_time, timestamp);
513         STORE_LE(sb->s_wtime, timestamp);
514         STORE_LE(sb->s_lastcheck, timestamp);
515         // misc. Values are chosen to match mke2fs 1.41.9
516         STORE_LE(sb->s_state, 1); // TODO: what's 1?
517         STORE_LE(sb->s_creator_os, EXT2_OS_LINUX);
518         STORE_LE(sb->s_checkinterval, 24*60*60 * 180); // 180 days
519         STORE_LE(sb->s_errors, EXT2_ERRORS_DEFAULT);
520         // mke2fs 1.41.9 also sets EXT3_FEATURE_COMPAT_RESIZE_INODE
521         // and if >= 0.5GB, EXT3_FEATURE_RO_COMPAT_LARGE_FILE.
522         // we use values which match "mke2fs -O ^resize_inode":
523         // in this case 1.41.9 never sets EXT3_FEATURE_RO_COMPAT_LARGE_FILE.
524         STORE_LE(sb->s_feature_compat, EXT2_FEATURE_COMPAT_SUPP
525                 | (EXT2_FEATURE_COMPAT_RESIZE_INO * ENABLE_FEATURE_MKFS_EXT2_RESERVED_GDT)
526                 | (EXT2_FEATURE_COMPAT_DIR_INDEX * ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX)
527         );
528         STORE_LE(sb->s_feature_incompat, EXT2_FEATURE_INCOMPAT_FILETYPE);
529         STORE_LE(sb->s_feature_ro_compat, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);
530         STORE_LE(sb->s_flags, EXT2_FLAGS_UNSIGNED_HASH * ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX);
531         generate_uuid(sb->s_uuid);
532         if (ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX) {
533                 STORE_LE(sb->s_def_hash_version, EXT2_HASH_HALF_MD4);
534                 generate_uuid((uint8_t *)sb->s_hash_seed);
535         }
536         /*
537          * From e2fsprogs: add "jitter" to the superblock's check interval so that we
538          * don't check all the filesystems at the same time.  We use a
539          * kludgy hack of using the UUID to derive a random jitter value.
540          */
541         STORE_LE(sb->s_max_mnt_count,
542                 EXT2_DFL_MAX_MNT_COUNT
543                 + (sb->s_uuid[ARRAY_SIZE(sb->s_uuid)-1] % EXT2_DFL_MAX_MNT_COUNT));
544
545         // write the label
546         safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name));
547
548         // calculate filesystem skeleton structures
549         gd = xzalloc(group_desc_blocks * blocksize);
550         buf = xmalloc(blocksize);
551         sb->s_free_blocks_count = 0;
552         for (i = 0, pos = first_block, n = nblocks - first_block;
553                 i < ngroups;
554                 i++, pos += blocks_per_group, n -= blocks_per_group
555         ) {
556                 uint32_t overhead = pos + (has_super(i) ? (1/*sb*/ + group_desc_blocks) : 0);
557                 uint32_t free_blocks;
558                 // fill group descriptors
559                 STORE_LE(gd[i].bg_block_bitmap, overhead + 0);
560                 STORE_LE(gd[i].bg_inode_bitmap, overhead + 1);
561                 STORE_LE(gd[i].bg_inode_table, overhead + 2);
562                 overhead = overhead - pos + 1/*bbmp*/ + 1/*ibmp*/ + inode_table_blocks;
563                 gd[i].bg_free_inodes_count = inodes_per_group;
564                 //STORE_LE(gd[i].bg_used_dirs_count, 0);
565                 // N.B. both "/" and "/lost+found" are within the first block group
566                 // "/" occupies 1 block, "/lost+found" occupies lost_and_found_blocks...
567                 if (0 == i) {
568                         // ... thus increased overhead for the first block group ...
569                         overhead += 1 + lost_and_found_blocks;
570                         // ... and 2 used directories
571                         STORE_LE(gd[i].bg_used_dirs_count, 2);
572                         // well known reserved inodes belong to the first block too
573                         gd[i].bg_free_inodes_count -= EXT2_GOOD_OLD_FIRST_INO;
574                 }
575
576                 // cache free block count of the group
577                 free_blocks = (n < blocks_per_group ? n : blocks_per_group) - overhead;
578
579                 // mark preallocated blocks as allocated
580 //bb_info_msg("ALLOC: [%u][%u][%u]", blocksize, overhead, blocks_per_group - (free_blocks + overhead));
581                 allocate(buf, blocksize,
582                         // reserve "overhead" blocks
583                         overhead,
584                         // mark unused trailing blocks
585                         blocks_per_group - (free_blocks + overhead)
586                 );
587                 // dump block bitmap
588                 PUT((uint64_t)(FETCH_LE32(gd[i].bg_block_bitmap)) * blocksize, buf, blocksize);
589                 STORE_LE(gd[i].bg_free_blocks_count, free_blocks);
590
591                 // mark preallocated inodes as allocated
592                 allocate(buf, blocksize,
593                         // mark reserved inodes
594                         inodes_per_group - gd[i].bg_free_inodes_count,
595                         // mark unused trailing inodes
596                         blocks_per_group - inodes_per_group
597                 );
598                 // dump inode bitmap
599                 //PUT((uint64_t)(FETCH_LE32(gd[i].bg_block_bitmap)) * blocksize, buf, blocksize);
600                 //but it's right after block bitmap, so we can just:
601                 xwrite(fd, buf, blocksize);
602                 STORE_LE(gd[i].bg_free_inodes_count, gd[i].bg_free_inodes_count);
603
604                 // count overall free blocks
605                 sb->s_free_blocks_count += free_blocks;
606         }
607         STORE_LE(sb->s_free_blocks_count, sb->s_free_blocks_count);
608
609         // dump filesystem skeleton structures
610 //      printf("Writing superblocks and filesystem accounting information: ");
611         for (i = 0, pos = first_block; i < ngroups; i++, pos += blocks_per_group) {
612                 // dump superblock and group descriptors and their backups
613                 if (has_super(i)) {
614                         // N.B. 1024 byte blocks are special
615                         PUT(((uint64_t)pos * blocksize) + ((0 == i && 1024 != blocksize) ? 1024 : 0),
616                                         sb, 1024);
617                         PUT(((uint64_t)pos * blocksize) + blocksize,
618                                         gd, group_desc_blocks * blocksize);
619                 }
620         }
621
622         // zero boot sectors
623         memset(buf, 0, blocksize);
624         // Disabled: standard mke2fs doesn't do this, and
625         // on SPARC this destroys Sun disklabel.
626         // Users who need/want zeroing can easily do it with dd.
627         //PUT(0, buf, 1024); // N.B. 1024 <= blocksize, so buf[0..1023] contains zeros
628
629         // zero inode tables
630         for (i = 0; i < ngroups; ++i)
631                 for (n = 0; n < inode_table_blocks; ++n)
632                         PUT((uint64_t)(FETCH_LE32(gd[i].bg_inode_table) + n) * blocksize,
633                                 buf, blocksize);
634
635         // prepare directory inode
636         inode = (struct ext2_inode *)buf;
637         STORE_LE(inode->i_mode, S_IFDIR | S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH);
638         STORE_LE(inode->i_mtime, timestamp);
639         STORE_LE(inode->i_atime, timestamp);
640         STORE_LE(inode->i_ctime, timestamp);
641         STORE_LE(inode->i_size, blocksize);
642         // inode->i_blocks stores the number of 512 byte data blocks
643         // (512, because it goes directly to struct stat without scaling)
644         STORE_LE(inode->i_blocks, blocksize / 512);
645
646         // dump root dir inode
647         STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode
648         STORE_LE(inode->i_block[0], FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks);
649         PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_ROOT_INO-1) * inodesize,
650                                 buf, inodesize);
651
652         // dump lost+found dir inode
653         STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode
654         STORE_LE(inode->i_size, lost_and_found_blocks * blocksize);
655         STORE_LE(inode->i_blocks, (lost_and_found_blocks * blocksize) / 512);
656         n = FETCH_LE32(inode->i_block[0]) + 1;
657         for (i = 0; i < lost_and_found_blocks; ++i)
658                 STORE_LE(inode->i_block[i], i + n); // use next block
659 //bb_info_msg("LAST BLOCK USED[%u]", i + n);
660         PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize,
661                                 buf, inodesize);
662
663         // dump directories
664         memset(buf, 0, blocksize);
665         dir = (struct ext2_dir *)buf;
666
667         // dump 2nd+ blocks of "/lost+found"
668         STORE_LE(dir->rec_len1, blocksize); // e2fsck 1.41.4 compat (1.41.9 does not need this)
669         for (i = 1; i < lost_and_found_blocks; ++i)
670                 PUT((uint64_t)(FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks + 1+i) * blocksize,
671                                 buf, blocksize);
672
673         // dump 1st block of "/lost+found"
674         STORE_LE(dir->inode1, EXT2_GOOD_OLD_FIRST_INO);
675         STORE_LE(dir->rec_len1, 12);
676         STORE_LE(dir->name_len1, 1);
677         STORE_LE(dir->file_type1, EXT2_FT_DIR);
678         dir->name1[0] = '.';
679         STORE_LE(dir->inode2, EXT2_ROOT_INO);
680         STORE_LE(dir->rec_len2, blocksize - 12);
681         STORE_LE(dir->name_len2, 2);
682         STORE_LE(dir->file_type2, EXT2_FT_DIR);
683         dir->name2[0] = '.'; dir->name2[1] = '.';
684         PUT((uint64_t)(FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks + 1) * blocksize, buf, blocksize);
685
686         // dump root dir block
687         STORE_LE(dir->inode1, EXT2_ROOT_INO);
688         STORE_LE(dir->rec_len2, 12);
689         STORE_LE(dir->inode3, EXT2_GOOD_OLD_FIRST_INO);
690         STORE_LE(dir->rec_len3, blocksize - 12 - 12);
691         STORE_LE(dir->name_len3, 10);
692         STORE_LE(dir->file_type3, EXT2_FT_DIR);
693         strcpy(dir->name3, "lost+found");
694         PUT((uint64_t)(FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks + 0) * blocksize, buf, blocksize);
695
696         // cleanup
697         if (ENABLE_FEATURE_CLEAN_UP) {
698                 free(buf);
699                 free(gd);
700                 free(sb);
701         }
702
703         xclose(fd);
704         return EXIT_SUCCESS;
705 }