1 /* vi: set sw=4 ts=4: */
3 * mke2fs.c - Make a ext2fs filesystem.
5 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
6 * 2003, 2004, 2005 by Theodore Ts'o.
8 * Licensed under GPLv2, see file LICENSE in this source tree.
11 /* Usage: mke2fs [options] device
13 * The device may be a block device or a image of one, but this isn't
14 * enforced (but it's not much fun on a character device :-).
17 //usage:#define mke2fs_trivial_usage
18 //usage: "[-c|-l filename] [-b block-size] [-f fragment-size] [-g blocks-per-group] "
19 //usage: "[-i bytes-per-inode] [-j] [-J journal-options] [-N number-of-inodes] [-n] "
20 //usage: "[-m reserved-blocks-percentage] [-o creator-os] [-O feature[,...]] [-q] "
21 //usage: "[r fs-revision-level] [-E extended-options] [-v] [-F] [-L volume-label] "
22 //usage: "[-M last-mounted-directory] [-S] [-T filesystem-type] "
23 //usage: "device [blocks-count]"
25 //usage:#define mke2fs_full_usage "\n\n"
26 //usage: " -b size Block size in bytes"
27 //usage: "\n -c Check for bad blocks before creating"
28 //usage: "\n -E opts Set extended options"
29 //usage: "\n -f size Fragment size in bytes"
30 //usage: "\n -F Force (ignore sanity checks)"
31 //usage: "\n -g num Number of blocks in a block group"
32 //usage: "\n -i ratio The bytes/inode ratio"
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 Set the volume label"
37 //usage: "\n -m percent Percent of fs blocks to reserve for admin"
38 //usage: "\n -M dir Set last mounted directory"
39 //usage: "\n -n Do not actually create anything"
40 //usage: "\n -N num 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"
49 //applet:IF_MKE2FS(APPLET(mke2fs, _BB_DIR_SBIN, _BB_SUID_DROP))
50 //applet:IF_MKE2FS(APPLET_ODDNAME(mkfs.ext2, mke2fs, _BB_DIR_SBIN, _BB_SUID_DROP, mke2fs))
51 //applet:IF_MKE2FS(APPLET_ODDNAME(mkfs.ext3, mke2fs, _BB_DIR_SBIN, _BB_SUID_DROP, mke2fs))
52 //applet:IF_MKE2FS(APPLET(tune2fs, _BB_DIR_SBIN, _BB_SUID_DROP))
64 #include <sys/ioctl.h>
65 #include <sys/types.h>
68 #include "ext2fs/ext2_fs.h"
69 #include "../e2fs_lib.h"
71 #include "ext2fs/ext2fs.h"
74 #define STRIDE_LENGTH 8
80 static const char * device_name
;
82 /* Command line options */
85 static int super_only
;
88 static int journal_size
;
89 static int journal_flags
;
90 static const char *bad_blocks_filename
;
91 static __u32 fs_stride
;
93 static struct ext2_super_block param
;
94 static char *creator_os
;
95 static char *volume_label
;
96 static char *mount_dir
;
97 static char *journal_device
= NULL
;
98 static int sync_kludge
; /* Set using the MKE2FS_SYNC env. option */
100 static int sys_page_size
= 4096;
101 static int linux_version_code
= 0;
103 static int int_log2(int arg
)
115 static int int_log10(unsigned int arg
)
119 for (l
= 0; arg
; l
++)
125 * This function sets the default parameters for a filesystem
127 * The type is specified by the user. The size is the maximum size
128 * (in megabytes) for which a set of parameters applies, with a size
129 * of zero meaning that it is the default parameter for the type.
130 * Note that order is important in the table below.
132 #define DEF_MAX_BLOCKSIZE -1
133 static const char default_str
[] = "default";
134 struct mke2fs_defaults
{
141 static const struct mke2fs_defaults settings
[] = {
142 { default_str
, 0, 4096, 8192 },
143 { default_str
, 512, 1024, 4096 },
144 { default_str
, 3, 1024, 8192 },
145 { "journal", 0, 4096, 8192 },
146 { "news", 0, 4096, 4096 },
147 { "largefile", 0, 4096, 1024 * 1024 },
148 { "largefile4", 0, 4096, 4096 * 1024 },
152 static void set_fs_defaults(const char *fs_type
,
153 struct ext2_super_block
*super
,
154 int blocksize
, int sector_size
,
159 const struct mke2fs_defaults
*p
;
160 int use_bsize
= 1024;
162 megs
= super
->s_blocks_count
* (EXT2_BLOCK_SIZE(super
) / 1024) / 1024;
164 ratio
= *inode_ratio
;
166 fs_type
= default_str
;
167 for (p
= settings
; p
->type
; p
++) {
168 if ((strcmp(p
->type
, fs_type
) != 0) &&
169 (strcmp(p
->type
, default_str
) != 0))
171 if ((p
->size
!= 0) && (megs
> p
->size
))
174 *inode_ratio
= p
->inode_ratio
< blocksize
?
175 blocksize
: p
->inode_ratio
;
176 use_bsize
= p
->blocksize
;
178 if (blocksize
<= 0) {
179 if (use_bsize
== DEF_MAX_BLOCKSIZE
) {
180 use_bsize
= sys_page_size
;
181 if ((linux_version_code
< (2*65536 + 6*256)) &&
185 if (sector_size
&& use_bsize
< sector_size
)
186 use_bsize
= sector_size
;
187 if ((blocksize
< 0) && (use_bsize
< (-blocksize
)))
188 use_bsize
= -blocksize
;
189 blocksize
= use_bsize
;
190 super
->s_blocks_count
/= blocksize
/ 1024;
192 super
->s_log_frag_size
= super
->s_log_block_size
=
193 int_log2(blocksize
>> EXT2_MIN_BLOCK_LOG_SIZE
);
198 * Helper function for read_bb_file and test_disk
200 static void invalid_block(ext2_filsys fs
EXT2FS_ATTR((unused
)), blk_t blk
)
202 bb_error_msg("Bad block %u out of range; ignored", blk
);
208 static void mke2fs_error_msg_and_die(int retval
, const char *fmt
, ...) __attribute__ ((format (printf
, 2, 3)));
209 static void mke2fs_error_msg_and_die(int retval
, const char *fmt
, ...)
215 fprintf(stderr
, "\nCould not ");
216 vfprintf(stderr
, fmt
, ap
);
217 fprintf(stderr
, "\n");
223 static void mke2fs_verbose(const char *fmt
, ...) __attribute__ ((format (printf
, 1, 2)));
224 static void mke2fs_verbose(const char *fmt
, ...)
230 vfprintf(stdout
, fmt
, ap
);
236 static void mke2fs_verbose_done(void)
238 mke2fs_verbose("done\n");
241 static void mke2fs_warning_msg(int retval
, const char *fmt
, ... ) __attribute__ ((format (printf
, 2, 3)));
242 static void mke2fs_warning_msg(int retval
, const char *fmt
, ... )
248 fprintf(stderr
, "\nWarning: ");
249 vfprintf(stderr
, fmt
, ap
);
250 fprintf(stderr
, "\n");
256 * Reads the bad blocks list from a file
258 static void read_bb_file(ext2_filsys fs
, badblocks_list
*bb_list
,
259 const char *bad_blocks_file
)
264 f
= xfopen_for_read(bad_blocks_file
);
265 retval
= ext2fs_read_bb_FILE(fs
, f
, bb_list
, invalid_block
);
267 mke2fs_error_msg_and_die(retval
, "read bad blocks from list");
271 * Runs the badblocks program to test the disk
273 static void test_disk(ext2_filsys fs
, badblocks_list
*bb_list
)
279 sprintf(buf
, "badblocks -b %d %s%s%s %d", fs
->blocksize
,
280 quiet
? "" : "-s ", (cflag
> 1) ? "-w " : "",
281 fs
->device_name
, fs
->super
->s_blocks_count
);
282 mke2fs_verbose("Running command: %s\n", buf
);
285 bb_perror_msg_and_die("can't run '%s'", buf
);
287 retval
= ext2fs_read_bb_FILE(fs
, f
, bb_list
, invalid_block
);
289 mke2fs_error_msg_and_die(retval
, "read bad blocks from program");
292 static void handle_bad_blocks(ext2_filsys fs
, badblocks_list bb_list
)
296 unsigned must_be_good
;
298 badblocks_iterate bb_iter
;
308 * The primary superblock and group descriptors *must* be
309 * good; if not, abort.
311 must_be_good
= fs
->super
->s_first_data_block
+ 1 + fs
->desc_blocks
;
312 for (i
= fs
->super
->s_first_data_block
; i
<= must_be_good
; i
++) {
313 if (ext2fs_badblocks_list_test(bb_list
, i
)) {
314 bb_error_msg_and_die(
315 "Block %d in primary superblock/group descriptor area bad\n"
316 "Blocks %d through %d must be good in order to build a filesystem\n"
317 "Aborting ...", i
, fs
->super
->s_first_data_block
, must_be_good
);
322 * See if any of the bad blocks are showing up in the backup
323 * superblocks and/or group descriptors. If so, issue a
324 * warning and adjust the block counts appropriately.
326 group_block
= fs
->super
->s_first_data_block
+
327 fs
->super
->s_blocks_per_group
;
329 for (i
= 1; i
< fs
->group_desc_count
; i
++) {
331 for (j
=0; j
< fs
->desc_blocks
+1; j
++) {
332 if (ext2fs_badblocks_list_test(bb_list
,
334 mke2fs_warning_msg(!group_bad
,
335 "the backup superblock/group descriptors at block %d contain\n"
336 "bad blocks\n", group_block
);
338 group
= ext2fs_group_of_blk(fs
, group_block
+j
);
339 fs
->group_desc
[group
].bg_free_blocks_count
++;
340 fs
->super
->s_free_blocks_count
++;
343 group_block
+= fs
->super
->s_blocks_per_group
;
347 * Mark all the bad blocks as used...
349 retval
= ext2fs_badblocks_list_iterate_begin(bb_list
, &bb_iter
);
350 mke2fs_error_msg_and_die(retval
, "mark bad blocks as used");
352 while (ext2fs_badblocks_list_iterate(bb_iter
, &blk
))
353 ext2fs_mark_block_bitmap(fs
->block_map
, blk
);
354 ext2fs_badblocks_list_iterate_end(bb_iter
);
358 * These functions implement a generalized progress meter.
360 struct progress_struct
{
367 static void progress_init(struct progress_struct
*progress
,
368 const char *label
,__u32 max
)
372 memset(progress
, 0, sizeof(struct progress_struct
));
377 * Figure out how many digits we need
380 sprintf(progress
->format
, "%%%dd/%%%dld", i
, i
);
381 memset(progress
->backup
, '\b', sizeof(progress
->backup
)-1);
382 progress
->backup
[sizeof(progress
->backup
)-1] = 0;
383 if ((2*i
)+1 < (int) sizeof(progress
->backup
))
384 progress
->backup
[(2*i
)+1] = 0;
387 progress
->skip_progress
= 0;
388 if (getenv("MKE2FS_SKIP_PROGRESS"))
389 progress
->skip_progress
++;
391 fputs(label
, stdout
);
395 static void progress_update(struct progress_struct
*progress
, __u32 val
)
397 if ((progress
->format
[0] == 0) || progress
->skip_progress
)
399 printf(progress
->format
, val
, progress
->max
);
400 fputs(progress
->backup
, stdout
);
403 static void progress_close(struct progress_struct
*progress
)
405 if (progress
->format
[0] == 0)
407 printf("%-28s\n", "done");
412 * Helper function which zeros out _num_ blocks starting at _blk_. In
413 * case of an error, the details of the error is returned via _ret_blk_
414 * and _ret_count_ if they are non-NULL pointers. Returns 0 on
415 * success, and an error code on an error.
417 * As a special case, if the first argument is NULL, then it will
418 * attempt to free the static zeroizing buffer. (This is to keep
419 * programs that check for memory leaks happy.)
421 static errcode_t
zero_blocks(ext2_filsys fs
, blk_t blk
, int num
,
422 struct progress_struct
*progress
,
423 blk_t
*ret_blk
, int *ret_count
)
425 int j
, count
, next_update
, next_update_incr
;
429 /* If fs is null, clean up the static buffer and return */
437 /* Allocate the zeroizing buffer if necessary */
439 buf
= xzalloc(fs
->blocksize
* STRIDE_LENGTH
);
441 /* OK, do the write loop */
443 next_update_incr
= num
/ 100;
444 if (next_update_incr
< 1)
445 next_update_incr
= 1;
446 for (j
=0; j
< num
; j
+= STRIDE_LENGTH
, blk
+= STRIDE_LENGTH
) {
448 if (count
> STRIDE_LENGTH
)
449 count
= STRIDE_LENGTH
;
450 retval
= io_channel_write_blk(fs
->io
, blk
, count
, buf
);
458 if (progress
&& j
> next_update
) {
459 next_update
+= num
/ 100;
460 progress_update(progress
, blk
);
466 static void write_inode_tables(ext2_filsys fs
)
472 struct progress_struct progress
;
475 memset(&progress
, 0, sizeof(progress
));
477 progress_init(&progress
, "Writing inode tables: ",
478 fs
->group_desc_count
);
480 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
481 progress_update(&progress
, i
);
483 blk
= fs
->group_desc
[i
].bg_inode_table
;
484 num
= fs
->inode_blocks_per_group
;
486 retval
= zero_blocks(fs
, blk
, num
, 0, &blk
, &num
);
487 mke2fs_error_msg_and_die(retval
,
488 "write %d blocks in inode table starting at %d.",
491 if (sync_kludge
== 1)
493 else if ((i
% sync_kludge
) == 0)
497 zero_blocks(0, 0, 0, 0, 0, 0);
498 progress_close(&progress
);
501 static void create_root_dir(ext2_filsys fs
)
504 struct ext2_inode inode
;
506 retval
= ext2fs_mkdir(fs
, EXT2_ROOT_INO
, EXT2_ROOT_INO
, 0);
507 mke2fs_error_msg_and_die(retval
, "create root dir");
509 retval
= ext2fs_read_inode(fs
, EXT2_ROOT_INO
, &inode
);
510 mke2fs_error_msg_and_die(retval
, "read root inode");
511 inode
.i_uid
= getuid();
513 inode
.i_gid
= getgid();
514 retval
= ext2fs_write_new_inode(fs
, EXT2_ROOT_INO
, &inode
);
515 mke2fs_error_msg_and_die(retval
, "set root inode ownership");
519 static void create_lost_and_found(ext2_filsys fs
)
523 const char *name
= "lost+found";
525 const char *msg
= "create";
529 retval
= ext2fs_mkdir(fs
, EXT2_ROOT_INO
, 0, name
);
531 goto CREATE_LOST_AND_FOUND_ERROR
;
534 retval
= ext2fs_lookup(fs
, EXT2_ROOT_INO
, name
, strlen(name
), 0, &ino
);
537 goto CREATE_LOST_AND_FOUND_ERROR
;
540 for (; i
< EXT2_NDIR_BLOCKS
; i
++) {
541 if ((lpf_size
+= fs
->blocksize
) >= 16*1024)
543 retval
= ext2fs_expand_dir(fs
, ino
);
545 CREATE_LOST_AND_FOUND_ERROR
:
546 mke2fs_error_msg_and_die(retval
, "%s %s", msg
, name
);
550 static void create_bad_block_inode(ext2_filsys fs
, badblocks_list bb_list
)
554 ext2fs_mark_inode_bitmap(fs
->inode_map
, EXT2_BAD_INO
);
555 fs
->group_desc
[0].bg_free_inodes_count
--;
556 fs
->super
->s_free_inodes_count
--;
557 retval
= ext2fs_update_bb_inode(fs
, bb_list
);
558 mke2fs_error_msg_and_die(retval
, "set bad block inode");
561 static void reserve_inodes(ext2_filsys fs
)
566 for (i
= EXT2_ROOT_INO
+ 1; i
< EXT2_FIRST_INODE(fs
->super
); i
++) {
567 ext2fs_mark_inode_bitmap(fs
->inode_map
, i
);
568 group
= ext2fs_group_of_ino(fs
, i
);
569 fs
->group_desc
[group
].bg_free_inodes_count
--;
570 fs
->super
->s_free_inodes_count
--;
572 ext2fs_mark_ib_dirty(fs
);
575 #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */
576 #define BSD_MAGICDISK (0x57455682UL) /* The disk magic number reversed */
577 #define BSD_LABEL_OFFSET 64
579 static void zap_sector(ext2_filsys fs
, int sect
, int nsect
)
582 const char *fmt
= "could not %s %d";
586 buf
= xmalloc(512*nsect
);
589 /* Check for a BSD disklabel, and don't erase it if so */
590 retval
= io_channel_read_blk(fs
->io
, 0, -512, buf
);
592 mke2fs_warning_msg(retval
, fmt
, "read block", 0);
594 magic
= (unsigned int *) (buf
+ BSD_LABEL_OFFSET
);
595 if ((*magic
== BSD_DISKMAGIC
) ||
596 (*magic
== BSD_MAGICDISK
))
601 memset(buf
, 0, 512*nsect
);
602 io_channel_set_blksize(fs
->io
, 512);
603 retval
= io_channel_write_blk(fs
->io
, sect
, -512*nsect
, buf
);
604 io_channel_set_blksize(fs
->io
, fs
->blocksize
);
606 mke2fs_warning_msg(retval
, fmt
, "erase sector", sect
);
609 static void create_journal_dev(ext2_filsys fs
)
611 struct progress_struct progress
;
614 const char *fmt
= "%s journal superblock";
618 retval
= ext2fs_create_journal_superblock(fs
,
619 fs
->super
->s_blocks_count
, 0, &buf
);
620 mke2fs_error_msg_and_die(retval
, fmt
, "init");
622 memset(&progress
, 0, sizeof(progress
));
624 progress_init(&progress
, "Zeroing journal device: ",
625 fs
->super
->s_blocks_count
);
627 retval
= zero_blocks(fs
, 0, fs
->super
->s_blocks_count
,
628 &progress
, &blk
, &count
);
629 mke2fs_error_msg_and_die(retval
, "zero journal device (block %u, count %d)",
631 zero_blocks(0, 0, 0, 0, 0, 0);
633 retval
= io_channel_write_blk(fs
->io
,
634 fs
->super
->s_first_data_block
+1,
636 mke2fs_error_msg_and_die(retval
, fmt
, "write");
637 progress_close(&progress
);
640 static void show_stats(ext2_filsys fs
)
642 struct ext2_super_block
*s
= fs
->super
;
648 mke2fs_warning_msg((param
.s_blocks_count
!= s
->s_blocks_count
),
649 "%d blocks unused\n", param
.s_blocks_count
- s
->s_blocks_count
);
650 os
= e2p_os2string(fs
->super
->s_creator_os
);
651 printf( "Filesystem label=%.*s\n"
653 "Block size=%u (log=%u)\n"
654 "Fragment size=%u (log=%u)\n"
655 "%u inodes, %u blocks\n"
656 "%u blocks (%2.2f%%) reserved for the super user\n"
657 "First data block=%u\n",
658 (int) sizeof(s
->s_volume_name
),
661 fs
->blocksize
, s
->s_log_block_size
,
662 fs
->fragsize
, s
->s_log_frag_size
,
663 s
->s_inodes_count
, s
->s_blocks_count
,
664 s
->s_r_blocks_count
, 100.0 * s
->s_r_blocks_count
/ s
->s_blocks_count
,
665 s
->s_first_data_block
);
667 if (s
->s_reserved_gdt_blocks
) {
668 printf("Maximum filesystem blocks=%lu\n",
669 (s
->s_reserved_gdt_blocks
+ fs
->desc_blocks
) *
670 (fs
->blocksize
/ sizeof(struct ext2_group_desc
)) *
671 s
->s_blocks_per_group
);
673 printf( "%u block group%s\n"
674 "%u blocks per group, %u fragments per group\n"
675 "%u inodes per group\n",
676 fs
->group_desc_count
, (fs
->group_desc_count
> 1) ? "s" : "",
677 s
->s_blocks_per_group
, s
->s_frags_per_group
,
678 s
->s_inodes_per_group
);
679 if (fs
->group_desc_count
== 1) {
684 printf("Superblock backups stored on blocks: ");
685 group_block
= s
->s_first_data_block
;
687 for (i
= 1; i
< fs
->group_desc_count
; i
++) {
688 group_block
+= s
->s_blocks_per_group
;
689 if (!ext2fs_bg_has_super(fs
, i
))
693 need
= int_log10(group_block
) + 2;
694 if (need
> col_left
) {
699 printf("%u", group_block
);
705 * Set the S_CREATOR_OS field. Return true if OS is known,
708 static int set_os(struct ext2_super_block
*sb
, char *os
)
711 sb
->s_creator_os
= atoi(os
);
715 if ((sb
->s_creator_os
= e2p_string2os(os
)) >= 0) {
717 } else if (!strcasecmp("GNU", os
)) {
718 sb
->s_creator_os
= EXT2_OS_HURD
;
724 static void parse_extended_opts(struct ext2_super_block
*sb_param
,
727 char *buf
, *token
, *next
, *p
, *arg
;
731 for (token
= buf
; token
&& *token
; token
= next
) {
732 p
= strchr(token
, ',');
738 arg
= strchr(token
, '=');
743 if (strcmp(token
, "stride") == 0) {
748 fs_stride
= strtoul(arg
, &p
, 0);
749 if (*p
|| (fs_stride
== 0)) {
750 bb_error_msg("Invalid stride parameter: %s", arg
);
754 } else if (!strcmp(token
, "resize")) {
755 unsigned long resize
, bpg
, rsv_groups
;
756 unsigned long group_desc_count
, desc_blocks
;
757 unsigned int gdpb
, blocksize
;
765 resize
= parse_num_blocks(arg
,
766 sb_param
->s_log_block_size
);
769 bb_error_msg("Invalid resize parameter: %s", arg
);
773 if (resize
<= sb_param
->s_blocks_count
) {
774 bb_error_msg("The resize maximum must be greater "
775 "than the filesystem size");
780 blocksize
= EXT2_BLOCK_SIZE(sb_param
);
781 bpg
= sb_param
->s_blocks_per_group
;
784 gdpb
= blocksize
/ sizeof(struct ext2_group_desc
);
785 group_desc_count
= (sb_param
->s_blocks_count
+
787 desc_blocks
= (group_desc_count
+
789 rsv_groups
= (resize
+ bpg
- 1) / bpg
;
790 rsv_gdb
= (rsv_groups
+ gdpb
- 1) / gdpb
-
792 if (rsv_gdb
> EXT2_ADDR_PER_BLOCK(sb_param
))
793 rsv_gdb
= EXT2_ADDR_PER_BLOCK(sb_param
);
796 sb_param
->s_feature_compat
|=
797 EXT2_FEATURE_COMPAT_RESIZE_INODE
;
799 sb_param
->s_reserved_gdt_blocks
= rsv_gdb
;
805 bb_error_msg_and_die(
806 "\nBad options specified.\n\n"
807 "Extended options are separated by commas, "
808 "and may take an argument which\n"
809 "\tis set off by an equals ('=') sign.\n\n"
810 "Valid extended options are:\n"
811 "\tstride=<stride length in blocks>\n"
812 "\tresize=<resize maximum size in blocks>\n");
816 static __u32 ok_features
[3] = {
817 EXT3_FEATURE_COMPAT_HAS_JOURNAL
|
818 EXT2_FEATURE_COMPAT_RESIZE_INODE
|
819 EXT2_FEATURE_COMPAT_DIR_INDEX
, /* Compat */
820 EXT2_FEATURE_INCOMPAT_FILETYPE
| /* Incompat */
821 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
|
822 EXT2_FEATURE_INCOMPAT_META_BG
,
823 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
/* R/O compat */
826 static int PRS(int argc
, char **argv
)
834 int reserved_ratio
= 5;
836 int show_version_only
= 0;
837 ext2_ino_t num_inodes
= 0;
839 char * extended_opts
= NULL
;
840 const char * fs_type
= NULL
;
844 /* Update our PATH to include /sbin */
845 e2fs_set_sbin_path();
847 tmp
= getenv("MKE2FS_SYNC");
849 sync_kludge
= atoi(tmp
);
851 /* Determine the system page size if possible */
852 #if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE))
853 #define _SC_PAGESIZE _SC_PAGE_SIZE
856 sysval
= sysconf(_SC_PAGESIZE
);
858 sys_page_size
= sysval
;
859 #endif /* _SC_PAGESIZE */
861 setbuf(stdout
, NULL
);
862 setbuf(stderr
, NULL
);
863 memset(¶m
, 0, sizeof(struct ext2_super_block
));
864 param
.s_rev_level
= 1; /* Create revision 1 filesystems now */
865 param
.s_feature_incompat
|= EXT2_FEATURE_INCOMPAT_FILETYPE
;
866 param
.s_feature_ro_compat
|= EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
869 linux_version_code
= get_linux_version_code();
870 if (linux_version_code
&& linux_version_code
< KERNEL_VERSION(2,2,0)) {
871 param
.s_rev_level
= 0;
872 param
.s_feature_incompat
= 0;
873 param
.s_feature_compat
= 0;
874 param
.s_feature_ro_compat
= 0;
878 /* If called as mkfs.ext3, create a journal inode */
879 if (last_char_is(applet_name
, '3'))
882 while ((c
= getopt (argc
, argv
,
883 "b:cE:f:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF
) {
886 blocksize
= xatou_range(optarg
, EXT2_MIN_BLOCK_SIZE
, EXT2_MAX_BLOCK_SIZE
);
887 mke2fs_warning_msg((blocksize
> 4096),
888 "blocksize %d not usable on most systems",
890 param
.s_log_block_size
=
891 int_log2(blocksize
>> EXT2_MIN_BLOCK_LOG_SIZE
);
893 case 'c': /* Check for bad blocks */
894 case 't': /* deprecated */
898 size
= xatou_range(optarg
, EXT2_MIN_BLOCK_SIZE
, EXT2_MAX_BLOCK_SIZE
);
899 param
.s_log_frag_size
=
900 int_log2(size
>> EXT2_MIN_BLOCK_LOG_SIZE
);
901 mke2fs_warning_msg(1, "fragments not supported. Ignoring -f option");
904 param
.s_blocks_per_group
= xatou32(optarg
);
905 if ((param
.s_blocks_per_group
% 8) != 0) {
906 bb_error_msg_and_die("blocks per group must be multiple of 8");
910 /* Huh? is "* 1024" correct? */
911 inode_ratio
= xatou_range(optarg
, EXT2_MIN_BLOCK_SIZE
, EXT2_MAX_BLOCK_SIZE
* 1024);
914 parse_journal_opts(&journal_device
, &journal_flags
, &journal_size
, optarg
);
917 param
.s_feature_compat
|=
918 EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
923 bad_blocks_filename
= optarg
;
926 reserved_ratio
= xatou_range(optarg
, 0, 50);
935 param
.s_rev_level
= xatoi_positive(optarg
);
936 if (param
.s_rev_level
== EXT2_GOOD_OLD_REV
) {
937 param
.s_feature_incompat
= 0;
938 param
.s_feature_compat
= 0;
939 param
.s_feature_ro_compat
= 0;
942 case 's': /* deprecated */
944 param
.s_feature_ro_compat
|=
945 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
947 param
.s_feature_ro_compat
&=
948 ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
;
950 #ifdef EXT2_DYNAMIC_REV
952 inode_size
= xatoi_positive(optarg
);
956 num_inodes
= xatoi_positive(optarg
);
968 volume_label
= optarg
;
974 if (!strcmp(optarg
, "none")) {
975 param
.s_feature_compat
= 0;
976 param
.s_feature_incompat
= 0;
977 param
.s_feature_ro_compat
= 0;
980 if (e2p_edit_feature(optarg
,
981 ¶m
.s_feature_compat
,
983 bb_error_msg_and_die("Invalid filesystem option set: %s", optarg
);
988 extended_opts
= optarg
;
997 /* Print version number and exit */
998 show_version_only
= 1;
1005 if ((optind
== argc
) /*&& !show_version_only*/)
1007 device_name
= argv
[optind
++];
1009 mke2fs_verbose("mke2fs %s (%s)\n", E2FSPROGS_VERSION
, E2FSPROGS_DATE
);
1011 if (show_version_only
) {
1016 * If there's no blocksize specified and there is a journal
1017 * device, use it to figure out the blocksize
1019 if (blocksize
<= 0 && journal_device
) {
1023 #ifdef CONFIG_TESTIO_DEBUG
1024 io_ptr
= test_io_manager
;
1025 test_io_backing_manager
= unix_io_manager
;
1027 io_ptr
= unix_io_manager
;
1029 retval
= ext2fs_open(journal_device
,
1030 EXT2_FLAG_JOURNAL_DEV_OK
, 0,
1032 mke2fs_error_msg_and_die(retval
, "open journal device %s", journal_device
);
1033 if ((blocksize
< 0) && (jfs
->blocksize
< (unsigned) (-blocksize
))) {
1034 bb_error_msg_and_die(
1035 "Journal dev blocksize (%d) smaller than "
1036 "minimum blocksize %d\n", jfs
->blocksize
,
1039 blocksize
= jfs
->blocksize
;
1040 param
.s_log_block_size
=
1041 int_log2(blocksize
>> EXT2_MIN_BLOCK_LOG_SIZE
);
1045 if (blocksize
> sys_page_size
) {
1046 mke2fs_warning_msg(1, "%d-byte blocks too big for system (max %d)",
1047 blocksize
, sys_page_size
);
1051 bb_error_msg("Forced to continue");
1053 mke2fs_warning_msg(((blocksize
> 4096) &&
1054 (param
.s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
)),
1055 "some 2.4 kernels do not support "
1056 "blocksizes greater than 4096 using ext3.\n"
1057 "Use -b 4096 if this is an issue for you\n");
1059 if (optind
< argc
) {
1060 param
.s_blocks_count
= parse_num_blocks(argv
[optind
++],
1061 param
.s_log_block_size
);
1062 mke2fs_error_msg_and_die(!param
.s_blocks_count
, "invalid blocks count - %s", argv
[optind
- 1]);
1067 if (param
.s_feature_incompat
& EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
) {
1069 fs_type
= "journal";
1071 param
.s_feature_incompat
= EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
;
1072 param
.s_feature_compat
= 0;
1073 param
.s_feature_ro_compat
= 0;
1075 if (param
.s_rev_level
== EXT2_GOOD_OLD_REV
&&
1076 (param
.s_feature_compat
|| param
.s_feature_ro_compat
||
1077 param
.s_feature_incompat
))
1078 param
.s_rev_level
= 1; /* Create a revision 1 filesystem */
1080 check_plausibility(device_name
, force
);
1081 check_mount(device_name
, force
, "filesystem");
1083 param
.s_log_frag_size
= param
.s_log_block_size
;
1085 if (noaction
&& param
.s_blocks_count
) {
1086 dev_size
= param
.s_blocks_count
;
1090 retval
= ext2fs_get_device_size(device_name
,
1091 EXT2_BLOCK_SIZE(¶m
),
1093 if ((retval
== EFBIG
) &&
1095 (param
.s_log_block_size
== 0)) {
1096 param
.s_log_block_size
= 2;
1102 mke2fs_error_msg_and_die((retval
&& (retval
!= EXT2_ET_UNIMPLEMENTED
)),"determine filesystem size");
1104 if (!param
.s_blocks_count
) {
1105 if (retval
== EXT2_ET_UNIMPLEMENTED
) {
1106 mke2fs_error_msg_and_die(1,
1107 "determine device size; you "
1108 "must specify\nthe size of the "
1111 if (dev_size
== 0) {
1112 bb_error_msg_and_die(
1113 "Device size reported to be zero. "
1114 "Invalid partition specified, or\n\t"
1115 "partition table wasn't reread "
1116 "after running fdisk, due to\n\t"
1117 "a modified partition being busy "
1118 "and in use. You may need to reboot\n\t"
1119 "to re-read your partition table.\n"
1122 param
.s_blocks_count
= dev_size
;
1123 if (sys_page_size
> EXT2_BLOCK_SIZE(¶m
))
1124 param
.s_blocks_count
&= ~((sys_page_size
/
1125 EXT2_BLOCK_SIZE(¶m
))-1);
1128 } else if (!force
&& (param
.s_blocks_count
> dev_size
)) {
1129 bb_error_msg("Filesystem larger than apparent device size");
1134 * If the user asked for HAS_JOURNAL, then make sure a journal
1137 if ((param
.s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
) &&
1141 /* Set first meta blockgroup via an environment variable */
1142 /* (this is mostly for debugging purposes) */
1143 if ((param
.s_feature_incompat
& EXT2_FEATURE_INCOMPAT_META_BG
) &&
1144 ((tmp
= getenv("MKE2FS_FIRST_META_BG"))))
1145 param
.s_first_meta_bg
= atoi(tmp
);
1147 /* Get the hardware sector size, if available */
1148 retval
= ext2fs_get_device_sectsize(device_name
, §or_size
);
1149 mke2fs_error_msg_and_die(retval
, "determine hardware sector size");
1151 if ((tmp
= getenv("MKE2FS_DEVICE_SECTSIZE")) != NULL
)
1152 sector_size
= atoi(tmp
);
1154 set_fs_defaults(fs_type
, ¶m
, blocksize
, sector_size
, &inode_ratio
);
1155 blocksize
= EXT2_BLOCK_SIZE(¶m
);
1158 parse_extended_opts(¶m
, extended_opts
);
1160 /* Since sparse_super is the default, we would only have a problem
1161 * here if it was explicitly disabled.
1163 if ((param
.s_feature_compat
& EXT2_FEATURE_COMPAT_RESIZE_INODE
) &&
1164 !(param
.s_feature_ro_compat
&EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
)) {
1165 bb_error_msg_and_die("reserved online resize blocks not supported "
1166 "on non-sparse filesystem");
1169 if (param
.s_blocks_per_group
) {
1170 if (param
.s_blocks_per_group
< 256 ||
1171 param
.s_blocks_per_group
> 8 * (unsigned) blocksize
) {
1172 bb_error_msg_and_die("blocks per group count out of range");
1176 if (!force
&& param
.s_blocks_count
>= (1 << 31)) {
1177 bb_error_msg_and_die("Filesystem too large. No more than 2**31-1 blocks\n"
1178 "\t (8TB using a blocksize of 4k) are currently supported.");
1182 if (inode_size
< EXT2_GOOD_OLD_INODE_SIZE
||
1183 inode_size
> EXT2_BLOCK_SIZE(¶m
) ||
1184 inode_size
& (inode_size
- 1)) {
1185 bb_error_msg_and_die("invalid inode size %d (min %d/max %d)",
1186 inode_size
, EXT2_GOOD_OLD_INODE_SIZE
,
1189 mke2fs_warning_msg((inode_size
!= EXT2_GOOD_OLD_INODE_SIZE
),
1190 "%d-byte inodes not usable on most systems",
1192 param
.s_inode_size
= inode_size
;
1196 * Calculate number of inodes based on the inode ratio
1198 param
.s_inodes_count
= num_inodes
? num_inodes
:
1199 ((__u64
) param
.s_blocks_count
* blocksize
)
1203 * Calculate number of blocks to reserve
1205 param
.s_r_blocks_count
= (param
.s_blocks_count
* reserved_ratio
) / 100;
1209 static void mke2fs_clean_up(void)
1211 if (ENABLE_FEATURE_CLEAN_UP
&& journal_device
) free(journal_device
);
1214 int mke2fs_main (int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
1215 int mke2fs_main (int argc
, char **argv
)
1219 badblocks_list bb_list
= 0;
1224 if (ENABLE_FEATURE_CLEAN_UP
)
1225 atexit(mke2fs_clean_up
);
1226 if (!PRS(argc
, argv
))
1229 #ifdef CONFIG_TESTIO_DEBUG
1230 io_ptr
= test_io_manager
;
1231 test_io_backing_manager
= unix_io_manager
;
1233 io_ptr
= unix_io_manager
;
1237 * Initialize the superblock....
1239 retval
= ext2fs_initialize(device_name
, 0, ¶m
,
1241 mke2fs_error_msg_and_die(retval
, "set up superblock");
1244 * Wipe out the old on-disk superblock
1247 zap_sector(fs
, 2, 6);
1250 * Generate a UUID for it...
1252 generate_uuid(fs
->super
->s_uuid
);
1255 * Initialize the directory index variables
1257 fs
->super
->s_def_hash_version
= EXT2_HASH_TEA
;
1258 generate_uuid((uint8_t *) fs
->super
->s_hash_seed
);
1261 * Add "jitter" to the superblock's check interval so that we
1262 * don't check all the filesystems at the same time. We use a
1263 * kludgy hack of using the UUID to derive a random jitter value.
1265 for (i
= 0, val
= 0; i
< sizeof(fs
->super
->s_uuid
); i
++)
1266 val
+= fs
->super
->s_uuid
[i
];
1267 fs
->super
->s_max_mnt_count
+= val
% EXT2_DFL_MAX_MNT_COUNT
;
1270 * Override the creator OS, if applicable
1272 if (creator_os
&& !set_os(fs
->super
, creator_os
)) {
1273 bb_error_msg_and_die("unknown os - %s", creator_os
);
1277 * For the Hurd, we will turn off filetype since it doesn't
1280 if (fs
->super
->s_creator_os
== EXT2_OS_HURD
)
1281 fs
->super
->s_feature_incompat
&=
1282 ~EXT2_FEATURE_INCOMPAT_FILETYPE
;
1285 * Set the volume label...
1288 snprintf(fs
->super
->s_volume_name
, sizeof(fs
->super
->s_volume_name
), "%s", volume_label
);
1292 * Set the last mount directory
1295 snprintf(fs
->super
->s_last_mounted
, sizeof(fs
->super
->s_last_mounted
), "%s", mount_dir
);
1298 if (!quiet
|| noaction
)
1304 if (fs
->super
->s_feature_incompat
&
1305 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
) {
1306 create_journal_dev(fs
);
1307 return (ext2fs_close(fs
) ? 1 : 0);
1310 if (bad_blocks_filename
)
1311 read_bb_file(fs
, &bb_list
, bad_blocks_filename
);
1313 test_disk(fs
, &bb_list
);
1315 handle_bad_blocks(fs
, bb_list
);
1316 fs
->stride
= fs_stride
;
1317 retval
= ext2fs_allocate_tables(fs
);
1318 mke2fs_error_msg_and_die(retval
, "allocate filesystem tables");
1320 fs
->super
->s_state
|= EXT2_ERROR_FS
;
1321 fs
->flags
&= ~(EXT2_FLAG_IB_DIRTY
|EXT2_FLAG_BB_DIRTY
);
1323 /* rsv must be a power of two (64kB is MD RAID sb alignment) */
1324 unsigned int rsv
= 65536 / fs
->blocksize
;
1325 unsigned long blocks
= fs
->super
->s_blocks_count
;
1326 unsigned long start
;
1329 #ifdef ZAP_BOOTBLOCK
1330 zap_sector(fs
, 0, 2);
1334 * Wipe out any old MD RAID (or other) metadata at the end
1335 * of the device. This will also verify that the device is
1336 * as large as we think. Be careful with very small devices.
1338 start
= (blocks
& ~(rsv
- 1));
1342 retval
= zero_blocks(fs
, start
, blocks
- start
,
1343 NULL
, &ret_blk
, NULL
);
1345 mke2fs_warning_msg(retval
, "can't zero block %u at end of filesystem", ret_blk
);
1346 write_inode_tables(fs
);
1347 create_root_dir(fs
);
1348 create_lost_and_found(fs
);
1350 create_bad_block_inode(fs
, bb_list
);
1351 if (fs
->super
->s_feature_compat
&
1352 EXT2_FEATURE_COMPAT_RESIZE_INODE
) {
1353 retval
= ext2fs_create_resize_inode(fs
);
1354 mke2fs_error_msg_and_die(retval
, "reserve blocks for online resize");
1358 if (journal_device
) {
1359 make_journal_device(journal_device
, fs
, quiet
, force
);
1360 } else if (journal_size
) {
1361 make_journal_blocks(fs
, journal_size
, journal_flags
, quiet
);
1364 mke2fs_verbose("Writing superblocks and filesystem accounting information: ");
1365 retval
= ext2fs_flush(fs
);
1366 mke2fs_warning_msg(retval
, "had trouble writing out superblocks");
1367 mke2fs_verbose_done();
1368 if (!quiet
&& !getenv("MKE2FS_SKIP_CHECK_MSG"))
1369 print_check_message(fs
);
1370 val
= ext2fs_close(fs
);
1371 return (retval
|| val
) ? 1 : 0;