shithub: lwext4

Download patch

ref: eb3371b48e3aeae4a4053a8d71c651443101eb14
parent: 3617716d33737c103e81870132c28a699170752e
author: gkostka <kostka.grzegorz@gmail.com>
date: Tue Nov 17 18:25:29 EST 2015

Add to mkfs tool multiple features

1. Filesystem type selection from cli: ext2, ext3, ext4
2. Limit block sizes to: 1024, 2048, 4096
3. Free block calculation fix

--- a/fs_test/lwext4_mkfs.c
+++ b/fs_test/lwext4_mkfs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,9 +51,11 @@
 /**@brief   Indicates that input is windows partition.*/
 static bool winpart = false;
 
+static int fs_type = F_SET_EXT4;
+
 static struct ext4_fs fs;
 static struct ext4_mkfs_info info = {
-	.block_size = 4096,
+	.block_size = 1024,
 };
 
 static bool verbose = false;
@@ -65,7 +67,8 @@
 [-i] --input   - input file name (or blockdevice)               \n\
 [-w] --wpart   - windows partition mode                         \n\
 [-v] --verbose - verbose mode		                        \n\
-[-b] --block   - block size: 1024, 2048 ... 65536 (default 4096)\n\
+[-b] --block   - block size: 1024, 2048, 4096 (default 1024)    \n\
+[-e] --ext     - fs type (ext2: 2, ext3: 3 ext4: 4))  	        \n\
 \n";
 
 
@@ -118,11 +121,12 @@
 	static struct option long_options[] = {
 	    {"input", required_argument, 0, 'i'},
 	    {"block", required_argument, 0, 'b'},
+	    {"ext", required_argument, 0, 'e'},
 	    {"wpart", no_argument, 0, 'w'},
 	    {"verbose", no_argument, 0, 'v'},
 	    {0, 0, 0, 0}};
 
-	while (-1 != (c = getopt_long(argc, argv, "i:b:wv",
+	while (-1 != (c = getopt_long(argc, argv, "i:b:e:wv",
 				      long_options, &option_index))) {
 
 		switch (c) {
@@ -132,6 +136,9 @@
 		case 'b':
 			info.block_size = atoi(optarg);
 			break;
+		case 'e':
+			fs_type = atoi(optarg);
+			break;
 		case 'w':
 			winpart = true;
 			break;
@@ -143,6 +150,28 @@
 			return false;
 		}
 	}
+
+	switch (info.block_size) {
+	case 1024:
+	case 2048:
+	case 4096:
+		break;
+	default:
+		printf("parse_opt: block_size = %"PRIu32" unsupported\n",
+				info.block_size);
+		return false;
+	}
+
+	switch (fs_type) {
+	case F_SET_EXT2:
+	case F_SET_EXT3:
+	case F_SET_EXT4:
+		break;
+	default:
+		printf("parse_opt: fs_type = %"PRIu32" unsupported\n", fs_type);
+		return false;
+	}
+
 	return true;
 }
 
@@ -162,13 +191,14 @@
 	if (verbose)
 		ext4_dmask_set(DEBUG_ALL);
 
-	printf("ext4_mkfs\n");
-	r = ext4_mkfs(&fs, bd, &info);
+	printf("ext4_mkfs: ext%d\n", fs_type);
+	r = ext4_mkfs(&fs, bd, &info, fs_type);
 	if (r != EOK) {
 		printf("ext4_mkfs error: %d\n", r);
 		return EXIT_FAILURE;
 	}
 
+	memset(&info, 0, sizeof(struct ext4_mkfs_info));
 	r = ext4_mkfs_read_info(bd, &info);
 	if (r != EOK) {
 		printf("ext4_mkfs_read_info error: %d\n", r);
@@ -188,7 +218,6 @@
 	printf("Features incompat: 0x%x\n", info.feat_incompat);
 	printf("BG desc reserve: %"PRIu32"\n", info.bg_desc_reserve_blocks);
 	printf("Descriptor size: %"PRIu32"\n",info.dsc_size);
-	printf("journal: %s\n",	!info.no_journal ? "yes" : "no");
 	printf("Label: %s\n", info.label);
 
 	printf("\nDone ...\n");
--- a/lwext4/ext4_mkfs.c
+++ b/lwext4/ext4_mkfs.c
@@ -93,6 +93,7 @@
 	info->bg_desc_reserve_blocks = to_le16(sb->s_reserved_gdt_blocks);
 	info->label = sb->volume_name;
 	info->len = (uint64_t)info->block_size * ext4_sb_get_blocks_cnt(sb);
+	info->dsc_size = to_le16(sb->desc_size);
 
 	return EOK;
 }
@@ -311,6 +312,9 @@
 		bg_free_blk -= 2;
 		blk_off += aux_info->bg_desc_blocks;
 
+		if (i == (aux_info->groups - 1))
+			bg_free_blk -= aux_info->first_data_block;
+
 		if (has_superblock(info, i)) {
 			bg_start_block++;
 			blk_off += info->bg_desc_reserve_blocks;
@@ -385,6 +389,9 @@
 
 				dsc_pos += dsc_size;
 				dsc_id++;
+
+				if (dsc_id == aux_info->groups)
+					break;
 			}
 
 			b.dirty = true;
@@ -391,6 +398,9 @@
 			r = ext4_block_set(bd, &b);
 			if (r != EOK)
 				return r;
+
+			if (dsc_id == aux_info->groups)
+				break;
 		}
 
 		r = ext4_block_get_noread(bd, &b, bg_start_block + blk_off + 1);
@@ -428,7 +438,7 @@
 			offset = info->block_size * (aux_info->first_data_block
 				+ i * info->blocks_per_group);
 
-			aux_info->sb->block_group_index = i;
+			aux_info->sb->block_group_index = to_le16(i);
 			r = ext4_block_writebytes(bd, offset, aux_info->sb,
 						  EXT4_SUPERBLOCK_SIZE);
 			if (r != EOK)
@@ -437,7 +447,7 @@
 	}
 
 	/* write out the primary superblock */
-	aux_info->sb->block_group_index = 0;
+	aux_info->sb->block_group_index = to_le16(0);
 	return ext4_block_writebytes(bd, 1024, aux_info->sb,
 			EXT4_SUPERBLOCK_SIZE);
 }
@@ -608,7 +618,7 @@
 }
 
 int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd,
-	      struct ext4_mkfs_info *info)
+	      struct ext4_mkfs_info *info, int fs_type)
 {
 	int r;
 
@@ -642,9 +652,23 @@
 
 	info->inodes_per_group = compute_inodes_per_group(info);
 
-	info->feat_compat = EXT4_SUPPORTED_FCOM;
-	info->feat_ro_compat = EXT4_SUPPORTED_FRO_COM;
-	info->feat_incompat = EXT4_SUPPORTED_FINCOM;
+	switch (fs_type) {
+	case F_SET_EXT2:
+		info->feat_compat = EXT2_SUPPORTED_FCOM;
+		info->feat_ro_compat = EXT2_SUPPORTED_FRO_COM;
+		info->feat_incompat = EXT2_SUPPORTED_FINCOM;
+		break;
+	case F_SET_EXT3:
+		info->feat_compat = EXT3_SUPPORTED_FCOM;
+		info->feat_ro_compat = EXT3_SUPPORTED_FRO_COM;
+		info->feat_incompat = EXT3_SUPPORTED_FINCOM;
+		break;
+	case F_SET_EXT4:
+		info->feat_compat = EXT4_SUPPORTED_FCOM;
+		info->feat_ro_compat = EXT4_SUPPORTED_FRO_COM;
+		info->feat_incompat = EXT4_SUPPORTED_FINCOM;
+		break;
+	}
 
 	/*TODO: handle this features*/
 	info->feat_incompat &= ~EXT4_FINCOM_META_BG;
@@ -651,7 +675,8 @@
 	info->feat_incompat &= ~EXT4_FINCOM_FLEX_BG;
 	info->feat_ro_compat &= ~EXT4_FRO_COM_METADATA_CSUM;
 
-	if (info->no_journal == 0)
+	/*TODO: handle journal feature & inode*/
+	if (info->journal == 0)
 		info->feat_compat |= 0;
 
 	if (info->dsc_size == 0) {
@@ -686,9 +711,9 @@
 	ext4_dbg(DEBUG_MKFS, DBG_NONE "BG desc reserve: %"PRIu32"\n",
 			info->bg_desc_reserve_blocks);
 	ext4_dbg(DEBUG_MKFS, DBG_NONE "Descriptor size: %"PRIu32"\n",
-				info->dsc_size);
+			info->dsc_size);
 	ext4_dbg(DEBUG_MKFS, DBG_NONE "journal: %s\n",
-			!info->no_journal ? "yes" : "no");
+			info->journal ? "yes" : "no");
 	ext4_dbg(DEBUG_MKFS, DBG_NONE "Label: %s\n", info->label);
 
 	struct ext4_bcache bc;
@@ -704,7 +729,7 @@
 	if (r != EOK)
 		goto cache_fini;
 
-	r = ext4_block_cache_write_back(bd, 0);
+	r = ext4_block_cache_write_back(bd, 1);
 	if (r != EOK)
 		goto cache_fini;
 
@@ -732,6 +757,7 @@
 	ext4_fs_fini(fs);
 
 	cache_fini:
+	ext4_block_cache_write_back(bd, 0);
 	ext4_bcache_fini_dynamic(&bc);
 
 	block_fini:
--- a/lwext4/ext4_mkfs.h
+++ b/lwext4/ext4_mkfs.h
@@ -58,7 +58,7 @@
 	uint16_t feat_incompat;
 	uint32_t bg_desc_reserve_blocks;
 	uint16_t dsc_size;
-	uint8_t no_journal;
+	uint8_t journal;
 	const char *label;
 };
 
@@ -65,7 +65,7 @@
 int ext4_mkfs_read_info(struct ext4_blockdev *bd, struct ext4_mkfs_info *info);
 
 int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd,
-	      struct ext4_mkfs_info *info);
+	      struct ext4_mkfs_info *info, int fs_type);
 
 #endif /* EXT4_MKFS_H_ */