const char *src_root_dir; /* Copy files from the specified directory */
static char *undo_file;
+static int android_sparse_file; /* -E android_sparse */
+static char *android_sparse_params;
+
static profile_t profile;
static int sys_page_size = 4096;
"[-r fs-revision] [-E extended-option[,...]]\n"
"\t[-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior]"
"[-z undo_file]\n"
- "\t[-jnqvDFKSV] device [blocks-count]\n"),
+ "\t[-jnqvDFSV] device [blocks-count]\n"),
program_name);
exit(1);
}
_("done \n"));
/* Reserved inodes must always have correct checksums */
- if (fs->super->s_creator_os == EXT2_OS_LINUX &&
- ext2fs_has_feature_metadata_csum(fs->super))
+ if (ext2fs_has_feature_metadata_csum(fs->super))
write_reserved_inodes(fs);
}
int retval;
unsigned int *magic;
- buf = malloc(512*nsect);
+ buf = calloc(512, nsect);
if (!buf) {
printf(_("Out of memory erasing sectors %d-%d\n"),
sect, sect + nsect - 1);
retval = io_channel_write_blk64(fs->io,
fs->super->s_first_data_block+1,
1, buf);
+ (void) ext2fs_free_mem(&buf);
if (retval) {
com_err("create_journal_dev", retval, "%s",
_("while writing journal superblock"));
#define PATH_SET "PATH=/sbin"
-static int option_handle_function(char *token, void *data)
-{
- if (!strncmp(token, "usr", 3)) {
- quotatype_bits |= QUOTA_USR_BIT;
- } else if (!strncmp(token, "grp", 3)) {
- quotatype_bits |= QUOTA_GRP_BIT;
- } else if (!strncmp(token, "prj", 3)) {
- quotatype_bits |= QUOTA_PRJ_BIT;
- } else {
- fprintf(stderr, _("Invalid quotatype parameter: %s\n"),
- token);
- return 1;
- }
- return 0;
-
-}
-
static void parse_extended_opts(struct ext2_super_block *param,
const char *opts)
{
} else if (!strcmp(token, "nodiscard")) {
discard = 0;
} else if (!strcmp(token, "quotatype")) {
+ char *errtok = NULL;
+
if (!arg) {
r_usage++;
badopt = token;
continue;
}
- ret = parse_quota_opts(arg, option_handle_function,
- NULL);
+ quotatype_bits = 0;
+ ret = parse_quota_types(arg, "atype_bits, &errtok);
if (ret) {
+ if (errtok) {
+ fprintf(stderr,
+ "Failed to parse quota type at %s", errtok);
+ free(errtok);
+ } else
+ com_err(program_name, ret,
+ "while parsing quota type");
r_usage++;
+ badopt = token;
continue;
}
+ } else if (!strcmp(token, "android_sparse")) {
+ android_sparse_file = 1;
} else {
r_usage++;
badopt = token;
"\tpacked_meta_blocks=<0 to disable, 1 to enable>\n"
"\tlazy_itable_init=<0 to disable, 1 to enable>\n"
"\tlazy_journal_init=<0 to disable, 1 to enable>\n"
- "\troot_uid=<uid of root directory>\n"
- "\troot_gid=<gid of root directory>\n"
+ "\troot_owner=<uid of root dir>:<gid of root dir>\n"
"\ttest_fs\n"
"\tdiscard\n"
"\tnodiscard\n"
- "\tquotatype=<usr OR grp>\n\n"),
+ "\tquotatype=<quota type(s) to be enabled>\n\n"),
badopt ? badopt : "");
free(buf);
exit(1);
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
EXT2_FEATURE_INCOMPAT_META_BG|
EXT4_FEATURE_INCOMPAT_FLEX_BG|
+ EXT4_FEATURE_INCOMPAT_EA_INODE|
EXT4_FEATURE_INCOMPAT_MMP |
EXT4_FEATURE_INCOMPAT_64BIT|
EXT4_FEATURE_INCOMPAT_INLINE_DATA|
EXT4_FEATURE_INCOMPAT_ENCRYPT |
- EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+ EXT4_FEATURE_INCOMPAT_CSUM_SEED |
+ EXT4_FEATURE_INCOMPAT_LARGEDIR,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
static errcode_t init_list(struct str_list *sl)
{
sl->num = 0;
- sl->max = 0;
+ sl->max = 1;
sl->list = malloc((sl->max+1) * sizeof(char *));
if (!sl->list)
return ENOMEM;
int b, c, flags;
int cluster_size = 0;
char *tmp, **cpp;
+ int explicit_fssize = 0;
int blocksize = 0;
int inode_ratio = 0;
int inode_size = 0;
long sysval;
int s_opt = -1, r_opt = -1;
char *fs_features = 0;
+ int fs_features_size = 0;
int use_bsize;
char *newpath;
int pathlen = sizeof(PATH_SET) + 1;
break;
case 'L':
volume_label = optarg;
+ if (strlen(volume_label) > EXT2_LABEL_LEN) {
+ volume_label[EXT2_LABEL_LEN] = '\0';
+ fprintf(stderr, _("Warning: label too long; will be truncated to '%s'\n\n"),
+ volume_label);
+ }
break;
case 'm':
reserved_ratio = strtod(optarg, &tmp);
creator_os = optarg;
break;
case 'O':
- fs_features = optarg;
+ retval = ext2fs_resize_mem(fs_features_size,
+ fs_features_size + 1 + strlen(optarg),
+ &fs_features);
+ if (retval) {
+ com_err(program_name, retval,
+ _("while allocating fs_feature string"));
+ exit(1);
+ }
+ if (fs_features_size)
+ strcat(fs_features, ",");
+ else
+ fs_features[0] = 0;
+ strcat(fs_features, optarg);
+ fs_features_size += 1 + strlen(optarg);
break;
case 'q':
quiet = 1;
/* The isatty() test is so we don't break existing scripts */
flags = CREATE_FILE;
- if (isatty(0) && isatty(1))
+ if (isatty(0) && isatty(1) && !offset)
flags |= CHECK_FS_EXIST;
if (!quiet)
flags |= VERBOSE_CREATE;
if (fs_blocks_count == 0)
flags |= NO_SIZE;
+ else
+ explicit_fssize = 1;
if (!check_plausibility(device_name, flags, &is_device) && !force)
proceed_question(proceed_delay);
ext2fs_clear_feature_filetype(&fs_param);
ext2fs_clear_feature_huge_file(&fs_param);
ext2fs_clear_feature_metadata_csum(&fs_param);
+ ext2fs_clear_feature_ea_inode(&fs_param);
}
edit_feature(fs_features ? fs_features : tmp,
&fs_param.s_feature_compat);
if (tmp)
free(tmp);
+ (void) ext2fs_free_mem(&fs_features);
/*
* If the user specified features incompatible with the Hurd, complain
*/
"metadata_csum feature.\n"));
exit(1);
}
+ if (ext2fs_has_feature_ea_inode(&fs_param)) {
+ fprintf(stderr, "%s", _("The HURD does not support the "
+ "ea_inode feature.\n"));
+ exit(1);
+ }
}
/* Get the hardware sector sizes, if available */
EXT2_BLOCK_SIZE(&fs_param));
exit(1);
}
+ /*
+ * Guard against group descriptor count overflowing... Mostly to avoid
+ * strange results for absurdly large devices.
+ */
+ if (fs_blocks_count > ((1ULL << (fs_param.s_log_block_size + 3 + 32)) - 1)) {
+ fprintf(stderr, _("%s: Size of device (0x%llx blocks) %s "
+ "too big to create\n\t"
+ "a filesystem using a blocksize of %d.\n"),
+ program_name, fs_blocks_count, device_name,
+ EXT2_BLOCK_SIZE(&fs_param));
+ exit(1);
+ }
ext2fs_blocks_count_set(&fs_param, fs_blocks_count);
if (ext2fs_has_feature_journal_dev(&fs_param)) {
+ int i;
+
+ for (i=0; fs_types[i]; i++) {
+ free(fs_types[i]);
+ fs_types[i] = 0;
+ }
fs_types[0] = strdup("journal");
fs_types[1] = 0;
}
if (extended_opts)
parse_extended_opts(&fs_param, extended_opts);
+ if (explicit_fssize == 0 && offset > 0) {
+ fs_blocks_count -= offset / EXT2_BLOCK_SIZE(&fs_param);
+ ext2fs_blocks_count_set(&fs_param, fs_blocks_count);
+ fprintf(stderr,
+ _("\nWarning: offset specified without an "
+ "explicit file system size.\n"
+ "Creating a file system with %llu blocks "
+ "but this might\n"
+ "not be what you want.\n\n"),
+ (unsigned long long) fs_blocks_count);
+ }
+
+ if (quotatype_bits & QUOTA_PRJ_BIT)
+ ext2fs_set_feature_project(&fs_param);
+
+ if (ext2fs_has_feature_project(&fs_param)) {
+ quotatype_bits |= QUOTA_PRJ_BIT;
+ if (inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
+ com_err(program_name, 0,
+ _("%d byte inodes are too small for "
+ "project quota"),
+ inode_size);
+ exit(1);
+ }
+ if (inode_size == 0) {
+ inode_size = get_int_from_profile(fs_types,
+ "inode_size", 0);
+ if (inode_size <= EXT2_GOOD_OLD_INODE_SIZE*2)
+ inode_size = EXT2_GOOD_OLD_INODE_SIZE*2;
+ }
+ }
+
/* Don't allow user to set both metadata_csum and uninit_bg bits. */
if (ext2fs_has_feature_metadata_csum(&fs_param) &&
ext2fs_has_feature_gdt_csum(&fs_param))
exit(1);
}
- /*
- * If inode size is 128 and project quota is enabled, we need
- * to notify users that project ID will never be useful.
- */
- if (ext2fs_has_feature_project(&fs_param) &&
- fs_param.s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
- com_err(program_name, 0,
- _("%d byte inodes are too small for project quota; "
- "specify larger size"),
- fs_param.s_inode_size);
- exit(1);
- }
-
/* Make sure number of inodes specified will fit in 32 bits */
if (num_inodes == 0) {
unsigned long long n;
static int create_quota_inodes(ext2_filsys fs)
{
quota_ctx_t qctx;
+ errcode_t retval;
- quota_init_context(&qctx, fs, QUOTA_ALL_BIT);
+ retval = quota_init_context(&qctx, fs, quotatype_bits);
+ if (retval) {
+ com_err(program_name, retval,
+ _("while initializing quota context"));
+ exit(1);
+ }
quota_compute_usage(qctx);
- quota_write_inode(qctx, quotatype_bits);
+ retval = quota_write_inode(qctx, quotatype_bits);
+ if (retval) {
+ com_err(program_name, retval,
+ _("while writing quota inodes"));
+ exit(1);
+ }
quota_release_context(&qctx);
return 0;
*/
if (!quiet)
flags |= EXT2_FLAG_PRINT_PROGRESS;
- retval = ext2fs_initialize(device_name, flags, &fs_param, io_ptr, &fs);
+ if (android_sparse_file) {
+ android_sparse_params = malloc(PATH_MAX + 32);
+ if (!android_sparse_params) {
+ com_err(program_name, ENOMEM, "%s",
+ _("in malloc for android_sparse_params"));
+ exit(1);
+ }
+ snprintf(android_sparse_params, PATH_MAX + 32, "%s:%u:%u",
+ device_name, fs_param.s_blocks_count,
+ 1024 << fs_param.s_log_block_size);
+ retval = ext2fs_initialize(android_sparse_params, flags,
+ &fs_param, sparse_io_manager, &fs);
+ } else
+ retval = ext2fs_initialize(device_name, flags, &fs_param,
+ io_ptr, &fs);
if (retval) {
com_err(device_name, retval, "%s",
_("while setting up superblock"));
ext2fs_has_feature_journal(&fs_param)))
journal_blocks = figure_journal_size(journal_size, fs);
+ sprintf(opt_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
+ 32768 : fs->blocksize * 8);
+ io_channel_set_options(fs->io, opt_string);
+ if (offset) {
+ sprintf(opt_string, "offset=%llu", offset);
+ io_channel_set_options(fs->io, opt_string);
+ }
+
/* Can't undo discard ... */
if (!noaction && discard && dev_size && (io_ptr != undo_io_manager)) {
retval = mke2fs_discard_device(fs);
}
}
- sprintf(opt_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
- 32768 : fs->blocksize * 8);
- io_channel_set_options(fs->io, opt_string);
- if (offset) {
- sprintf(opt_string, "offset=%llu", offset);
- io_channel_set_options(fs->io, opt_string);
- }
-
if (fs_param.s_flags & EXT2_FLAGS_TEST_FILESYS)
fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS;
* Parse or generate a UUID for the filesystem
*/
if (fs_uuid) {
- if (uuid_parse(fs_uuid, fs->super->s_uuid) !=0) {
+ if ((strcasecmp(fs_uuid, "null") == 0) ||
+ (strcasecmp(fs_uuid, "clear") == 0)) {
+ uuid_clear(fs->super->s_uuid);
+ } else if (strcasecmp(fs_uuid, "time") == 0) {
+ uuid_generate_time(fs->super->s_uuid);
+ } else if (strcasecmp(fs_uuid, "random") == 0) {
+ uuid_generate(fs->super->s_uuid);
+ } else if (uuid_parse(fs_uuid, fs->super->s_uuid) != 0) {
com_err(device_name, 0, "could not parse UUID: %s\n",
fs_uuid);
exit(1);
if (ext2fs_has_feature_bigalloc(&fs_param))
fix_cluster_bg_counts(fs);
- if (ext2fs_has_feature_project(&fs_param))
- quotatype_bits |= QUOTA_PRJ_BIT;
if (ext2fs_has_feature_quota(&fs_param))
create_quota_inodes(fs);
retval = ext2fs_close_free(&fs);
if (retval) {
fprintf(stderr, "%s",
- _("\nWarning, had trouble writing out superblocks."));
+ _("\nWarning, had trouble writing out superblocks.\n"));
} else if (!quiet) {
printf("%s", _("done\n\n"));
if (!getenv("MKE2FS_SKIP_CHECK_MSG"))