summaryrefslogtreecommitdiffstats
path: root/misc/mke2fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/mke2fs.c')
-rw-r--r--misc/mke2fs.c72
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",