static gid_t root_gid;
int journal_size;
int journal_flags;
+int journal_fc_size;
static int lazy_itable_init;
static int packed_meta_blocks;
int no_copy_xattrs;
char *buf;
blk64_t blk, err_blk;
int c, count, err_count;
+ struct ext2fs_journal_params jparams;
- retval = ext2fs_create_journal_superblock(fs,
- ext2fs_blocks_count(fs->super), 0, &buf);
+ retval = ext2fs_get_journal_params(&jparams, fs);
+ if (retval) {
+ com_err("create_journal_dev", retval, "%s",
+ _("while splitting the journal size"));
+ exit(1);
+ }
+
+ retval = ext2fs_create_journal_superblock2(fs, &jparams, 0, &buf);
if (retval) {
com_err("create_journal_dev", retval, "%s",
_("while initializing journal superblock"));
EXT2_FEATURE_COMPAT_RESIZE_INODE |
EXT2_FEATURE_COMPAT_DIR_INDEX |
EXT2_FEATURE_COMPAT_EXT_ATTR |
- EXT4_FEATURE_COMPAT_SPARSE_SUPER2,
+ EXT4_FEATURE_COMPAT_SPARSE_SUPER2 |
+ EXT4_FEATURE_COMPAT_FAST_COMMIT |
+ EXT4_FEATURE_COMPAT_STABLE_INODES,
/* Incompat */
EXT2_FEATURE_INCOMPAT_FILETYPE|
EXT3_FEATURE_INCOMPAT_EXTENTS|
extern const char *mke2fs_default_profile;
static const char *default_files[] = { "<default>", 0 };
+struct device_param {
+ unsigned long min_io; /* prefered minimum IO size */
+ unsigned long opt_io; /* optimal IO size */
+ unsigned long alignment_offset; /* alignment offset wrt physical block size */
+ unsigned int dax:1; /* supports dax? */
+};
+
#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
/*
* Sets the geometry of a device (stripe/stride), and returns the
* device's alignment offset, if any, or a negative error.
*/
static int get_device_geometry(const char *file,
- struct ext2_super_block *param,
- unsigned int psector_size)
+ unsigned int blocksize,
+ unsigned int psector_size,
+ struct device_param *dev_param)
{
int rc = -1;
- unsigned int blocksize;
blkid_probe pr;
blkid_topology tp;
- unsigned long min_io;
- unsigned long opt_io;
struct stat statbuf;
+ memset(dev_param, 0, sizeof(*dev_param));
+
/* Nothing to do for a regular file */
if (!stat(file, &statbuf) && S_ISREG(statbuf.st_mode))
return 0;
if (!tp)
goto out;
- min_io = blkid_topology_get_minimum_io_size(tp);
- opt_io = blkid_topology_get_optimal_io_size(tp);
- blocksize = EXT2_BLOCK_SIZE(param);
- if ((min_io == 0) && (psector_size > blocksize))
- min_io = psector_size;
- if ((opt_io == 0) && min_io)
- opt_io = min_io;
- if ((opt_io == 0) && (psector_size > blocksize))
- opt_io = psector_size;
-
- /* setting stripe/stride to blocksize is pointless */
- if (min_io > blocksize)
- param->s_raid_stride = min_io / blocksize;
- if (opt_io > blocksize)
- param->s_raid_stripe_width = opt_io / blocksize;
-
- rc = blkid_topology_get_alignment_offset(tp);
+ dev_param->min_io = blkid_topology_get_minimum_io_size(tp);
+ dev_param->opt_io = blkid_topology_get_optimal_io_size(tp);
+ if ((dev_param->min_io == 0) && (psector_size > blocksize))
+ dev_param->min_io = psector_size;
+ if ((dev_param->opt_io == 0) && dev_param->min_io > 0)
+ dev_param->opt_io = dev_param->min_io;
+ if ((dev_param->opt_io == 0) && (psector_size > blocksize))
+ dev_param->opt_io = psector_size;
+
+ dev_param->alignment_offset = blkid_topology_get_alignment_offset(tp);
+#ifdef HAVE_BLKID_TOPOLOGY_GET_DAX
+ dev_param->dax = blkid_topology_get_dax(tp);
+#endif
+ rc = 0;
out:
blkid_free_probe(pr);
return rc;
int use_bsize;
char *newpath;
int pathlen = sizeof(PATH_SET) + 1;
+ struct device_param dev_param;
if (oldpath)
pathlen += strlen(oldpath);
case 'j':
if (!journal_size)
journal_size = -1;
+ if (!journal_fc_size)
+ journal_fc_size = -1;
break;
case 'J':
parse_journal_opts(optarg);
}
#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
- retval = get_device_geometry(device_name, &fs_param,
- (unsigned int) psector_size);
+ retval = get_device_geometry(device_name, blocksize,
+ psector_size, &dev_param);
if (retval < 0) {
fprintf(stderr,
_("warning: Unable to get device geometry for %s\n"),
device_name);
- } else if (retval) {
- printf(_("%s alignment is offset by %lu bytes.\n"),
- device_name, retval);
- printf(_("This may result in very poor performance, "
- "(re)-partitioning suggested.\n"));
+ } else {
+ /* setting stripe/stride to blocksize is pointless */
+ if (dev_param.min_io > blocksize)
+ fs_param.s_raid_stride = dev_param.min_io / blocksize;
+ if (dev_param.opt_io > blocksize) {
+ fs_param.s_raid_stripe_width =
+ dev_param.opt_io / blocksize;
+ }
+
+ if (dev_param.alignment_offset) {
+ printf(_("%s alignment is offset by %lu bytes.\n"),
+ device_name, dev_param.alignment_offset);
+ printf(_("This may result in very poor performance, "
+ "(re)-partitioning suggested.\n"));
+ }
+
+ if (dev_param.dax && blocksize != sys_page_size) {
+ fprintf(stderr,
+ _("%s is capable of DAX but current block size "
+ "%u is different from system page size %u so "
+ "filesystem will not support DAX.\n"),
+ device_name, blocksize, sys_page_size);
+ }
}
#endif
errcode_t retval = 0;
ext2_filsys fs;
badblocks_list bb_list = 0;
- unsigned int journal_blocks = 0;
+ badblocks_iterate bb_iter;
+ blk_t blk;
+ struct ext2fs_journal_params jparams = {0};
unsigned int i, checkinterval;
int max_mnt_count;
int val, hash_alg;
char opt_string[40];
char *hash_alg_str;
int itable_zeroed = 0;
+ blk64_t overhead;
#ifdef ENABLE_NLS
setlocale(LC_MESSAGES, "");
/* Calculate journal blocks */
if (!journal_device && ((journal_size) ||
ext2fs_has_feature_journal(&fs_param)))
- journal_blocks = figure_journal_size(journal_size, fs);
+ figure_journal_size(&jparams, journal_size, journal_fc_size, fs);
sprintf(opt_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
32768 : fs->blocksize * 8);
if (volume_label) {
memset(fs->super->s_volume_name, 0,
sizeof(fs->super->s_volume_name));
- strncpy(fs->super->s_volume_name, volume_label,
+ strncpy((char *) fs->super->s_volume_name, volume_label,
sizeof(fs->super->s_volume_name));
}
if (mount_dir) {
memset(fs->super->s_last_mounted, 0,
sizeof(fs->super->s_last_mounted));
- strncpy(fs->super->s_last_mounted, mount_dir,
+ strncpy((char *) fs->super->s_last_mounted, mount_dir,
sizeof(fs->super->s_last_mounted));
}
if (!quiet)
printf("%s", _("done \n"));
+ /*
+ * Unmark bad blocks to calculate overhead, because metadata
+ * blocks and bad blocks can land on the same allocation cluster.
+ */
+ if (bb_list) {
+ retval = ext2fs_badblocks_list_iterate_begin(bb_list,
+ &bb_iter);
+ if (retval) {
+ com_err("ext2fs_badblocks_list_iterate_begin", retval,
+ "%s", _("while unmarking bad blocks"));
+ exit(1);
+ }
+ while (ext2fs_badblocks_list_iterate(bb_iter, &blk))
+ ext2fs_unmark_block_bitmap2(fs->block_map, blk);
+ ext2fs_badblocks_list_iterate_end(bb_iter);
+ }
+
retval = ext2fs_convert_subcluster_bitmap(fs, &fs->block_map);
if (retval) {
com_err(program_name, retval, "%s",
exit(1);
}
+ retval = ext2fs_count_used_clusters(fs, fs->super->s_first_data_block,
+ ext2fs_blocks_count(fs->super) - 1,
+ &overhead);
+ if (retval) {
+ com_err(program_name, retval, "%s",
+ _("while calculating overhead"));
+ exit(1);
+ }
+
+ if (bb_list) {
+ retval = ext2fs_badblocks_list_iterate_begin(bb_list,
+ &bb_iter);
+ if (retval) {
+ com_err("ext2fs_badblocks_list_iterate_begin", retval,
+ "%s", _("while marking bad blocks as used"));
+ exit(1);
+ }
+ while (ext2fs_badblocks_list_iterate(bb_iter, &blk))
+ ext2fs_mark_block_bitmap2(fs->block_map, blk);
+ ext2fs_badblocks_list_iterate_end(bb_iter);
+ }
+
if (super_only) {
check_plausibility(device_name, CHECK_FS_EXIST, NULL);
printf(_("%s may be further corrupted by superblock rewrite\n"),
free(journal_device);
} else if ((journal_size) ||
ext2fs_has_feature_journal(&fs_param)) {
+ overhead += EXT2FS_NUM_B2C(fs, jparams.num_journal_blocks + jparams.num_fc_blocks);
if (super_only) {
printf("%s", _("Skipping journal creation in super-only mode\n"));
fs->super->s_journal_inum = EXT2_JOURNAL_INO;
goto no_journal;
}
- if (!journal_blocks) {
+ if (!jparams.num_journal_blocks) {
ext2fs_clear_feature_journal(fs->super);
goto no_journal;
}
if (!quiet) {
printf(_("Creating journal (%u blocks): "),
- journal_blocks);
+ jparams.num_journal_blocks + jparams.num_fc_blocks);
fflush(stdout);
}
- retval = ext2fs_add_journal_inode2(fs, journal_blocks,
+ retval = ext2fs_add_journal_inode3(fs, &jparams,
journal_location,
journal_flags);
if (retval) {
fs->super->s_mmp_update_interval);
}
+ overhead += fs->super->s_first_data_block;
+ if (!super_only)
+ fs->super->s_overhead_clusters = overhead;
+
if (ext2fs_has_feature_bigalloc(&fs_param))
fix_cluster_bg_counts(fs);
if (ext2fs_has_feature_quota(&fs_param))