diff options
Diffstat (limited to 'misc/mke2fs.c')
-rw-r--r-- | misc/mke2fs.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 4a9c1b0..58ade9d 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -90,6 +90,7 @@ static int force; static int noaction; static int num_backups = 2; /* number of backup bg's for sparse_super2 */ static uid_t root_uid; +static mode_t root_perms = (mode_t)-1; static gid_t root_gid; int journal_size; int journal_flags; @@ -117,7 +118,7 @@ static char *mount_dir; char *journal_device; static int sync_kludge; /* Set using the MKE2FS_SYNC env. option */ char **fs_types; -const char *src_root_dir; /* Copy files from the specified directory */ +const char *src_root; /* Copy files from the specified directory or tarball */ static char *undo_file; static int android_sparse_file; /* -E android_sparse */ @@ -134,7 +135,7 @@ static void usage(void) "[-C cluster-size]\n\t[-i bytes-per-inode] [-I inode-size] " "[-J journal-options]\n" "\t[-G flex-group-size] [-N number-of-inodes] " - "[-d root-directory]\n" + "[-d root-directory|tarball]\n" "\t[-m reserved-blocks-percentage] [-o creator-os]\n" "\t[-g blocks-per-group] [-L volume-label] " "[-M last-mounted-directory]\n\t[-O feature[,...]] " @@ -415,9 +416,9 @@ static errcode_t packed_allocate_tables(ext2_filsys fs) static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed) { errcode_t retval; - blk64_t blk; + blk64_t start = 0; dgrp_t i; - int num; + int len = 0; struct ext2fs_numeric_progress_struct progress; ext2fs_numeric_progress_init(fs, &progress, @@ -425,10 +426,10 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed) fs->group_desc_count); for (i = 0; i < fs->group_desc_count; i++) { - ext2fs_numeric_progress_update(fs, &progress, i); + blk64_t blk = ext2fs_inode_table_loc(fs, i); + int num = fs->inode_blocks_per_group; - blk = ext2fs_inode_table_loc(fs, i); - num = fs->inode_blocks_per_group; + ext2fs_numeric_progress_update(fs, &progress, i); if (lazy_flag) num = ext2fs_div_ceil((fs->super->s_inodes_per_group - @@ -441,14 +442,26 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed) ext2fs_group_desc_csum_set(fs, i); } if (!itable_zeroed) { - retval = ext2fs_zero_blocks2(fs, blk, num, &blk, &num); + if (len == 0) { + start = blk; + len = num; + continue; + } + /* 'len' must not overflow 2^31 blocks for ext2fs_zero_blocks2() */ + if (start + len == blk && len + num >= len) { + len += num; + continue; + } + retval = ext2fs_zero_blocks2(fs, start, len, &start, &len); if (retval) { fprintf(stderr, _("\nCould not write %d " "blocks in inode table starting at %llu: %s\n"), - num, (unsigned long long) blk, + len, (unsigned long long) start, error_message(retval)); exit(1); } + start = blk; + len = num; } if (sync_kludge) { if (sync_kludge == 1) @@ -457,6 +470,18 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed) io_channel_flush(fs->io); } } + if (len) { + retval = ext2fs_zero_blocks2(fs, start, len, &start, &len); + if (retval) { + fprintf(stderr, _("\nCould not write %d " + "blocks in inode table starting at %llu: %s\n"), + len, (unsigned long long) start, + error_message(retval)); + exit(1); + } + if (sync_kludge) + io_channel_flush(fs->io); + } ext2fs_numeric_progress_close(fs, &progress, _("done \n")); @@ -469,6 +494,7 @@ static void create_root_dir(ext2_filsys fs) { errcode_t retval; struct ext2_inode inode; + int need_inode_change; retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0); if (retval) { @@ -476,19 +502,30 @@ static void create_root_dir(ext2_filsys fs) _("while creating root dir")); exit(1); } - if (root_uid != 0 || root_gid != 0) { + + need_inode_change = (int)(root_uid != 0 || root_gid != 0 || root_perms != (mode_t)-1); + + if (need_inode_change) { retval = ext2fs_read_inode(fs, EXT2_ROOT_INO, &inode); if (retval) { com_err("ext2fs_read_inode", retval, "%s", _("while reading root inode")); exit(1); } + } + if (root_uid != 0 || root_gid != 0) { inode.i_uid = root_uid; ext2fs_set_i_uid_high(inode, root_uid >> 16); inode.i_gid = root_gid; ext2fs_set_i_gid_high(inode, root_gid >> 16); + } + + if (root_perms != (mode_t)-1) { + inode.i_mode = LINUX_S_IFDIR | root_perms; + } + if (need_inode_change) { retval = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode); if (retval) { com_err("ext2fs_write_inode", retval, "%s", @@ -1048,6 +1085,10 @@ static void parse_extended_opts(struct ext2_super_block *param, root_uid = getuid(); root_gid = getgid(); } + } else if (!strcmp(token, "root_perms")) { + if (arg) { + root_perms = strtoul(arg, &p, 8); + } } else if (!strcmp(token, "discard")) { discard = 1; } else if (!strcmp(token, "nodiscard")) { @@ -1132,6 +1173,7 @@ static void parse_extended_opts(struct ext2_super_block *param, "\tlazy_itable_init=<0 to disable, 1 to enable>\n" "\tlazy_journal_init=<0 to disable, 1 to enable>\n" "\troot_owner=<uid of root dir>:<gid of root dir>\n" + "\troot_perms=<octal root directory permissions>\n" "\ttest_fs\n" "\tdiscard\n" "\tnodiscard\n" @@ -1712,7 +1754,7 @@ profile_error: } break; case 'd': - src_root_dir = optarg; + src_root = optarg; break; case 'D': direct_io = 1; @@ -3522,7 +3564,7 @@ no_journal: fs->super->s_mmp_update_interval); } - overhead += fs->super->s_first_data_block; + overhead += EXT2FS_NUM_B2C(fs, fs->super->s_first_data_block); if (!super_only) fs->super->s_overhead_clusters = overhead; @@ -3551,12 +3593,12 @@ no_journal: retval = mk_hugefiles(fs, device_name); if (retval) com_err(program_name, retval, "while creating huge files"); - /* Copy files from the specified directory */ - if (src_root_dir) { + /* Copy files from the specified directory or tarball */ + if (src_root) { if (!quiet) printf("%s", _("Copying files into the device: ")); - retval = populate_fs(fs, EXT2_ROOT_INO, src_root_dir, + retval = populate_fs(fs, EXT2_ROOT_INO, src_root, EXT2_ROOT_INO); if (retval) { com_err(program_name, retval, "%s", |