All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
  2016-09-17  0:10 ` [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature Stefan Brüns
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

Most importantly, the superblock provides the used group descriptor size,
which is required for the EXT4_FEATURE_INCOMPAT_64BIT.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 include/ext_common.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/include/ext_common.h b/include/ext_common.h
index 25216ca..07b61fa 100644
--- a/include/ext_common.h
+++ b/include/ext_common.h
@@ -99,6 +99,33 @@ struct ext2_sblock {
 	char volume_name[16];
 	char last_mounted_on[64];
 	__le32 compression_info;
+	uint8_t prealloc_blocks;
+	uint8_t prealloc_dir_blocks;
+	__le16 reserved_gdt_blocks;
+	uint8_t journal_uuid[16];
+	__le32 journal_inode;
+	__le32 journal_dev;
+	__le32 last_orphan;
+	__le32 hash_seed[4];
+	uint8_t default_hash_version;
+	uint8_t journal_backup_type;
+	__le16 descriptor_size;
+	__le32 default_mount_options;
+	__le32 first_meta_block_group;
+	__le32 mkfs_time;
+	__le32 journal_blocks[17];
+	__le32 total_blocks_high;
+	__le32 reserved_blocks_high;
+	__le32 free_blocks_high;
+	__le16 min_extra_inode_size;
+	__le16 want_extra_inode_size;
+	__le32 flags;
+	__le16 raid_stride;
+	__le16 mmp_interval;
+	__le64 mmp_block;
+	__le32 raid_stripe_width;
+	uint8_t log2_groups_per_flex;
+	uint8_t checksum_type;
 };
 
 struct ext2_block_group {
@@ -109,9 +136,23 @@ struct ext2_block_group {
 	__le16 free_inodes;	/* Free inodes count */
 	__le16 used_dir_cnt;	/* Directories count */
 	__le16 bg_flags;
-	__le32 bg_reserved[2];
+	__le32 bg_exclude_bitmap;
+	__le16 bg_block_id_csum;
+	__le16 bg_inode_id_csum;
 	__le16 bg_itable_unused; /* Unused inodes count */
-	__le16 bg_checksum;	/* crc16(s_uuid+grouo_num+group_desc)*/
+	__le16 bg_checksum;	/* crc16(s_uuid+group_num+group_desc)*/
+	/* following fields only exist if descriptor size is 64 */
+	__le32 block_id_high;
+	__le32 inode_id_high;
+	__le32 inode_table_id_high;
+	__le16 free_blocks_high;
+	__le16 free_inodes_high;
+	__le16 used_dir_cnt_high;
+	__le16 bg_itable_unused_high;
+	__le32 bg_exclude_bitmap_high;
+	__le16 bg_block_id_csum_high;
+	__le16 bg_inode_id_csum_high;
+	__le32 bg_reserved;
 };
 
 /* The ext2 inode. */
@@ -125,7 +166,7 @@ struct ext2_inode {
 	__le32 dtime;
 	__le16 gid;
 	__le16 nlinks;
-	__le32 blockcnt;	/* Blocks of 512 bytes!! */
+	__le32 blockcnt;	/* Blocks of either 512 or block_size bytes */
 	__le32 flags;
 	__le32 osd1;
 	union {
@@ -136,10 +177,11 @@ struct ext2_inode {
 			__le32 triple_indir_block;
 		} blocks;
 		char symlink[60];
+		char inline_data[60];
 	} b;
 	__le32 version;
 	__le32 acl;
-	__le32 dir_acl;
+	__le32 size_high;	/* previously dir_acl, but never used */
 	__le32 fragment_addr;
 	__le32 osd2[3];
 };
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
  2016-09-17  0:10 ` [U-Boot] [PATCH 1/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Stefan Brüns
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
  2016-12-26  8:23   ` [U-Boot] [PATCH " Kever Yang
  2016-09-17  0:10 ` [U-Boot] [PATCH 3/7] ext4: Add helper functions for block group descriptor field access Stefan Brüns
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

If EXT4_FEATURE_INCOMPAT_64BIT is set, the descriptor can be read from
the superblocks, otherwise it defaults to 32.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 fs/ext4/ext4_common.c | 18 ++++++++++++++----
 include/ext4fs.h      |  2 ++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index a78b0b8..416a9db 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -2233,13 +2233,23 @@ int ext4fs_mount(unsigned part_length)
 		goto fail;
 	}
 
-	if (le32_to_cpu(data->sblock.revision_level) == 0)
+	if (le32_to_cpu(data->sblock.revision_level) == 0) {
 		fs->inodesz = 128;
-	else
+	} else {
+		debug("EXT4 features COMPAT: %08x INCOMPAT: %08x RO_COMPAT: %08x\n",
+		      __le32_to_cpu(data->sblock.feature_compatibility),
+		      __le32_to_cpu(data->sblock.feature_incompat),
+		      __le32_to_cpu(data->sblock.feature_ro_compat));
+
 		fs->inodesz = le16_to_cpu(data->sblock.inode_size);
+		fs->gdsize = le32_to_cpu(data->sblock.feature_incompat) &
+			EXT4_FEATURE_INCOMPAT_64BIT ?
+			le16_to_cpu(data->sblock.descriptor_size) : 32;
+	}
 
-	debug("EXT2 rev %d, inode_size %d\n",
-	       le32_to_cpu(data->sblock.revision_level), fs->inodesz);
+	debug("EXT2 rev %d, inode_size %d, descriptor size %d\n",
+	      le32_to_cpu(data->sblock.revision_level),
+	      fs->inodesz, fs->gdsize);
 
 	data->diropen.data = data;
 	data->diropen.ino = 2;
diff --git a/include/ext4fs.h b/include/ext4fs.h
index 6e31c73..7e1ee6c 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -87,6 +87,8 @@ struct ext_filesystem {
 	uint32_t inodesz;
 	/* Sectors per Block */
 	uint32_t sect_perblk;
+	/* Group Descriptor size */
+	uint16_t gdsize;
 	/* Group Descriptor Block Number */
 	uint32_t gdtable_blkno;
 	/* Total block groups of partition */
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 3/7] ext4: Add helper functions for block group descriptor field access
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
  2016-09-17  0:10 ` [U-Boot] [PATCH 1/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Stefan Brüns
  2016-09-17  0:10 ` [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature Stefan Brüns
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-17  0:10 ` [U-Boot] [PATCH 4/7] ext4: Use correct descriptor size when reading the block group descriptor Stefan Brüns
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

The helper functions encapsulate access of the block group descriptors,
independent of group descriptor size. The helpers also deal with the
endianess of the fields, and with split fields like free_blocks/
free_blocks_high.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 fs/ext4/ext4_common.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ext4/ext4_common.h | 12 ++++++++
 2 files changed, 92 insertions(+)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 416a9db..9e5bca0 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -47,6 +47,12 @@ struct ext2_inode *g_parent_inode;
 static int symlinknest;
 
 #if defined(CONFIG_EXT4_WRITE)
+struct ext2_block_group *ext4fs_get_group_descriptor
+	(const struct ext_filesystem *fs, uint32_t bg_idx)
+{
+	return (struct ext2_block_group *)(fs->gdtable + (bg_idx * fs->gdsize));
+}
+
 static inline void ext4fs_sb_free_inodes_dec(struct ext2_sblock *sb)
 {
 	sb->free_inodes = cpu_to_le32(le32_to_cpu(sb->free_inodes) - 1);
@@ -72,6 +78,80 @@ static inline void ext4fs_bg_itable_unused_dec(struct ext2_block_group *bg)
 	bg->bg_itable_unused = cpu_to_le16(le16_to_cpu(bg->bg_itable_unused) - 1);
 }
 
+uint64_t ext4fs_sb_get_free_blocks(const struct ext2_sblock *sb)
+{
+	uint64_t free_blocks = le32_to_cpu(sb->free_blocks);
+	free_blocks += (uint64_t)le32_to_cpu(sb->free_blocks_high) << 32;
+	return free_blocks;
+}
+
+void ext4fs_sb_set_free_blocks(struct ext2_sblock *sb, uint64_t free_blocks)
+{
+	sb->free_blocks = cpu_to_le32(free_blocks & 0xffffffff);
+	sb->free_blocks_high = cpu_to_le16(free_blocks >> 32);
+}
+
+uint32_t ext4fs_bg_get_free_blocks(const struct ext2_block_group *bg,
+				   const struct ext_filesystem *fs)
+{
+	uint32_t free_blocks = le16_to_cpu(bg->free_blocks);
+	if (fs->gdsize == 64)
+		free_blocks += le16_to_cpu(bg->free_blocks_high) << 16;
+	return free_blocks;
+}
+
+static inline
+uint32_t ext4fs_bg_get_free_inodes(const struct ext2_block_group *bg,
+				   const struct ext_filesystem *fs)
+{
+	uint32_t free_inodes = le16_to_cpu(bg->free_inodes);
+	if (fs->gdsize == 64)
+		free_inodes += le16_to_cpu(bg->free_inodes_high) << 16;
+	return free_inodes;
+}
+
+static inline uint16_t ext4fs_bg_get_flags(const struct ext2_block_group *bg)
+{
+	return le16_to_cpu(bg->bg_flags);
+}
+
+static inline void ext4fs_bg_set_flags(struct ext2_block_group *bg,
+				       uint16_t flags)
+{
+	bg->bg_flags = cpu_to_le16(flags);
+}
+
+/* Block number of the block bitmap */
+uint64_t ext4fs_bg_get_block_id(const struct ext2_block_group *bg,
+				const struct ext_filesystem *fs)
+{
+	uint64_t block_nr = le32_to_cpu(bg->block_id);
+	if (fs->gdsize == 64)
+		block_nr += (uint64_t)le32_to_cpu(bg->block_id_high) << 32;
+	return block_nr;
+}
+
+/* Block number of the inode bitmap */
+uint64_t ext4fs_bg_get_inode_id(const struct ext2_block_group *bg,
+				const struct ext_filesystem *fs)
+{
+	uint64_t block_nr = le32_to_cpu(bg->inode_id);
+	if (fs->gdsize == 64)
+		block_nr += (uint64_t)le32_to_cpu(bg->inode_id_high) << 32;
+	return block_nr;
+}
+
+/* Block number of the inode table */
+uint64_t ext4fs_bg_get_inode_table_id(const struct ext2_block_group *bg,
+				      const struct ext_filesystem *fs)
+{
+	uint64_t block_nr = le32_to_cpu(bg->inode_table_id);
+	if (fs->gdsize == 64)
+		block_nr +=
+			(uint64_t)le32_to_cpu(bg->inode_table_id_high) << 32;
+	return block_nr;
+}
+
 uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n)
 {
 	uint32_t res = size / n;
diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h
index cc9d0c5..99d49e6 100644
--- a/fs/ext4/ext4_common.h
+++ b/fs/ext4/ext4_common.h
@@ -74,5 +74,17 @@ void ext4fs_allocate_blocks(struct ext2_inode *file_inode,
 				unsigned int total_remaining_blocks,
 				unsigned int *total_no_of_block);
 void put_ext4(uint64_t off, void *buf, uint32_t size);
+struct ext2_block_group *ext4fs_get_group_descriptor
+	(const struct ext_filesystem *fs, uint32_t bg_idx);
+uint64_t ext4fs_bg_get_block_id(const struct ext2_block_group *bg,
+	const struct ext_filesystem *fs);
+uint64_t ext4fs_bg_get_inode_id(const struct ext2_block_group *bg,
+	const struct ext_filesystem *fs);
+uint64_t ext4fs_bg_get_inode_table_id(const struct ext2_block_group *bg,
+	const struct ext_filesystem *fs);
+uint64_t ext4fs_sb_get_free_blocks(const struct ext2_sblock *sb);
+void ext4fs_sb_set_free_blocks(struct ext2_sblock *sb, uint64_t free_blocks);
+uint32_t ext4fs_bg_get_free_blocks(const struct ext2_block_group *bg,
+	const struct ext_filesystem *fs);
 #endif
 #endif
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 4/7] ext4: Use correct descriptor size when reading the block group descriptor
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
                   ` (2 preceding siblings ...)
  2016-09-17  0:10 ` [U-Boot] [PATCH 3/7] ext4: Add helper functions for block group descriptor field access Stefan Brüns
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
  2016-09-17  0:10 ` [U-Boot] [PATCH 5/7] ext4: Use helper function to access group descriptor and its fields Stefan Brüns
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

The correct descriptor size must be used when calculating offsets, and
also to read the correct amount of data.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 fs/ext4/ext4_common.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 9e5bca0..24610ca 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -1525,20 +1525,20 @@ static int ext4fs_blockgroup
 	long int blkno;
 	unsigned int blkoff, desc_per_blk;
 	int log2blksz = get_fs()->dev_desc->log2blksz;
+	int desc_size = get_fs()->gdsize;
 
-	desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group);
+	desc_per_blk = EXT2_BLOCK_SIZE(data) / desc_size;
 
 	blkno = le32_to_cpu(data->sblock.first_data_block) + 1 +
 			group / desc_per_blk;
-	blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group);
+	blkoff = (group % desc_per_blk) * desc_size;
 
 	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
 	      group, blkno, blkoff);
 
 	return ext4fs_devread((lbaint_t)blkno <<
 			      (LOG2_BLOCK_SIZE(data) - log2blksz),
-			      blkoff, sizeof(struct ext2_block_group),
-			      (char *)blkgrp);
+			      blkoff, desc_size, (char *)blkgrp);
 }
 
 int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 5/7] ext4: Use helper function to access group descriptor and its fields
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
                   ` (3 preceding siblings ...)
  2016-09-17  0:10 ` [U-Boot] [PATCH 4/7] ext4: Use correct descriptor size when reading the block group descriptor Stefan Brüns
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
  2016-09-17  0:10 ` [U-Boot] [PATCH 6/7] ext4: Respect group descriptor size when adjusting free counts Stefan Brüns
  2016-09-17  0:10 ` [U-Boot] [PATCH 7/7] ext4: Revert rejection of 64bit enabled ext4 fs Stefan Brüns
  6 siblings, 1 reply; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

The descriptor size is variable, thus array indices are not generically
applicable. The larger group descriptors also contain e.g. high parts
of block numbers, which have to be read and written.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 fs/ext4/ext4_common.c | 125 ++++++++++++++++++++------------------
 fs/ext4/ext4_write.c  | 165 +++++++++++++++++++++++++++-----------------------
 include/ext4fs.h      |   1 -
 3 files changed, 154 insertions(+), 137 deletions(-)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 24610ca..0c2ac47 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -391,7 +391,7 @@ uint16_t ext4fs_checksum_update(uint32_t i)
 	uint16_t crc = 0;
 	__le32 le32_i = cpu_to_le32(i);
 
-	desc = (struct ext2_block_group *)&fs->bgd[i];
+	desc = ext4fs_get_group_descriptor(fs, i);
 	if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
 		int offset = offsetof(struct ext2_block_group, bg_checksum);
 
@@ -931,39 +931,41 @@ uint32_t ext4fs_get_new_blk_no(void)
 	char *zero_buffer = zalloc(fs->blksz);
 	if (!journal_buffer || !zero_buffer)
 		goto fail;
-	struct ext2_block_group *bgd = (struct ext2_block_group *)fs->gdtable;
 
 	if (fs->first_pass_bbmap == 0) {
 		for (i = 0; i < fs->no_blkgrp; i++) {
-			if (le16_to_cpu(bgd[i].free_blocks)) {
-				if (le16_to_cpu(bgd[i].bg_flags) & EXT4_BG_BLOCK_UNINIT) {
-					uint16_t new_flags;
-					put_ext4((uint64_t)le32_to_cpu(bgd[i].block_id) * fs->blksz,
-						 zero_buffer, fs->blksz);
-					new_flags = le16_to_cpu(bgd[i].bg_flags) & ~EXT4_BG_BLOCK_UNINIT;
-					bgd[i].bg_flags = cpu_to_le16(new_flags);
+			struct ext2_block_group *bgd = NULL;
+			bgd = ext4fs_get_group_descriptor(fs, i);
+			if (ext4fs_bg_get_free_blocks(bgd, fs)) {
+				uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+				uint64_t b_bitmap_blk =
+					ext4fs_bg_get_block_id(bgd, fs);
+				if (bg_flags & EXT4_BG_BLOCK_UNINIT) {
 					memcpy(fs->blk_bmaps[i], zero_buffer,
 					       fs->blksz);
+					put_ext4(b_bitmap_blk * fs->blksz,
+						 fs->blk_bmaps[i], fs->blksz);
+					bg_flags &= ~EXT4_BG_BLOCK_UNINIT;
+					ext4fs_bg_set_flags(bgd, bg_flags);
 				}
 				fs->curr_blkno =
 				    _get_new_blk_no(fs->blk_bmaps[i]);
 				if (fs->curr_blkno == -1)
-					/* if block bitmap is completely fill */
+					/* block bitmap is completely filled */
 					continue;
 				fs->curr_blkno = fs->curr_blkno +
 						(i * fs->blksz * 8);
 				fs->first_pass_bbmap++;
-				ext4fs_bg_free_blocks_dec(&bgd[i]);
+				ext4fs_bg_free_blocks_dec(bgd);
 				ext4fs_sb_free_blocks_dec(fs->sb);
-				status = ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[i].block_id) *
-							fs->sect_perblk, 0,
-							fs->blksz,
+				status = ext4fs_devread(b_bitmap_blk *
+							fs->sect_perblk,
+							0, fs->blksz,
 							journal_buffer);
 				if (status == 0)
 					goto fail;
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[i].block_id)))
+						       b_bitmap_blk))
 					goto fail;
 				goto success;
 			} else {
@@ -990,7 +992,9 @@ restart:
 		if (bg_idx >= fs->no_blkgrp)
 			goto fail;
 
-		if (bgd[bg_idx].free_blocks == 0) {
+		struct ext2_block_group *bgd = NULL;
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		if (ext4fs_bg_get_free_blocks(bgd, fs) == 0) {
 			debug("block group %u is full. Skipping\n", bg_idx);
 			fs->curr_blkno = (bg_idx + 1) * blk_per_grp;
 			if (fs->blksz == 1024)
@@ -998,13 +1002,14 @@ restart:
 			goto restart;
 		}
 
-		if (le16_to_cpu(bgd[bg_idx].bg_flags) & EXT4_BG_BLOCK_UNINIT) {
-			uint16_t new_flags;
-			put_ext4((uint64_t)le32_to_cpu(bgd[bg_idx].block_id) * fs->blksz,
-				 zero_buffer, fs->blksz);
+		uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+		uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+		if (bg_flags & EXT4_BG_BLOCK_UNINIT) {
 			memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
-			new_flags = le16_to_cpu(bgd[bg_idx].bg_flags) & ~EXT4_BG_BLOCK_UNINIT;
-			bgd[bg_idx].bg_flags = cpu_to_le16(new_flags);
+			put_ext4(b_bitmap_blk * fs->blksz,
+				 zero_buffer, fs->blksz);
+			bg_flags &= ~EXT4_BG_BLOCK_UNINIT;
+			ext4fs_bg_set_flags(bgd, bg_flags);
 		}
 
 		if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx],
@@ -1017,19 +1022,16 @@ restart:
 
 		/* journal backup */
 		if (prev_bg_bitmap_index != bg_idx) {
-			status = ext4fs_devread(
-						(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id)
-						* fs->sect_perblk,
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
 				goto fail;
-			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 
 			prev_bg_bitmap_index = bg_idx;
 		}
-		ext4fs_bg_free_blocks_dec(&bgd[bg_idx]);
+		ext4fs_bg_free_blocks_dec(bgd);
 		ext4fs_sb_free_blocks_dec(fs->sb);
 		goto success;
 	}
@@ -1057,46 +1059,49 @@ int ext4fs_get_new_inode_no(void)
 	char *zero_buffer = zalloc(fs->blksz);
 	if (!journal_buffer || !zero_buffer)
 		goto fail;
-	struct ext2_block_group *bgd = (struct ext2_block_group *)fs->gdtable;
 	int has_gdt_chksum = le32_to_cpu(fs->sb->feature_ro_compat) &
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM ? 1 : 0;
 
 	if (fs->first_pass_ibmap == 0) {
 		for (i = 0; i < fs->no_blkgrp; i++) {
-			if (bgd[i].free_inodes) {
+			uint32_t free_inodes;
+			struct ext2_block_group *bgd = NULL;
+			bgd = ext4fs_get_group_descriptor(fs, i);
+			free_inodes = ext4fs_bg_get_free_inodes(bgd, fs);
+			if (free_inodes) {
+				uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+				uint64_t i_bitmap_blk =
+					ext4fs_bg_get_inode_id(bgd, fs);
 				if (has_gdt_chksum)
-					bgd[i].bg_itable_unused =
-						bgd[i].free_inodes;
-				if (le16_to_cpu(bgd[i].bg_flags) & EXT4_BG_INODE_UNINIT) {
-					int new_flags;
-					put_ext4((uint64_t)le32_to_cpu(bgd[i].inode_id) * fs->blksz,
+					bgd->bg_itable_unused = free_inodes;
+				if (bg_flags & EXT4_BG_INODE_UNINIT) {
+					put_ext4(i_bitmap_blk * fs->blksz,
 						 zero_buffer, fs->blksz);
-					new_flags = le16_to_cpu(bgd[i].bg_flags) & ~EXT4_BG_INODE_UNINIT;
-					bgd[i].bg_flags = cpu_to_le16(new_flags);
+					bg_flags &= ~EXT4_BG_INODE_UNINIT;
+					ext4fs_bg_set_flags(bgd, bg_flags);
 					memcpy(fs->inode_bmaps[i],
 					       zero_buffer, fs->blksz);
 				}
 				fs->curr_inode_no =
 				    _get_new_inode_no(fs->inode_bmaps[i]);
 				if (fs->curr_inode_no == -1)
-					/* if block bitmap is completely fill */
+					/* inode bitmap is completely filled */
 					continue;
 				fs->curr_inode_no = fs->curr_inode_no +
 							(i * inodes_per_grp);
 				fs->first_pass_ibmap++;
-				ext4fs_bg_free_inodes_dec(&bgd[i]);
+				ext4fs_bg_free_inodes_dec(bgd);
 				if (has_gdt_chksum)
-					ext4fs_bg_itable_unused_dec(&bgd[i]);
+					ext4fs_bg_itable_unused_dec(bgd);
 				ext4fs_sb_free_inodes_dec(fs->sb);
-				status = ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[i].inode_id) *
-							fs->sect_perblk, 0,
-							fs->blksz,
+				status = ext4fs_devread(i_bitmap_blk *
+							fs->sect_perblk,
+							0, fs->blksz,
 							journal_buffer);
 				if (status == 0)
 					goto fail;
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[i].inode_id)))
+						       i_bitmap_blk))
 					goto fail;
 				goto success;
 			} else
@@ -1108,12 +1113,16 @@ restart:
 		fs->curr_inode_no++;
 		/* get the blockbitmap index respective to blockno */
 		ibmap_idx = fs->curr_inode_no / inodes_per_grp;
-		if (le16_to_cpu(bgd[ibmap_idx].bg_flags) & EXT4_BG_INODE_UNINIT) {
-			int new_flags;
-			put_ext4((uint64_t)le32_to_cpu(bgd[ibmap_idx].inode_id) * fs->blksz,
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, ibmap_idx);
+		uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+		uint64_t i_bitmap_blk = ext4fs_bg_get_inode_id(bgd, fs);
+
+		if (bg_flags & EXT4_BG_INODE_UNINIT) {
+			put_ext4(i_bitmap_blk * fs->blksz,
 				 zero_buffer, fs->blksz);
-			new_flags = le16_to_cpu(bgd[ibmap_idx].bg_flags) & ~EXT4_BG_INODE_UNINIT;
-			bgd[ibmap_idx].bg_flags = cpu_to_le16(new_flags);
+			bg_flags &= ~EXT4_BG_INODE_UNINIT;
+			ext4fs_bg_set_flags(bgd, bg_flags);
 			memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer,
 				fs->blksz);
 		}
@@ -1128,22 +1137,18 @@ restart:
 
 		/* journal backup */
 		if (prev_inode_bitmap_index != ibmap_idx) {
-			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(
-						(lbaint_t)le32_to_cpu(bgd[ibmap_idx].inode_id)
-						* fs->sect_perblk,
+			status = ext4fs_devread(i_bitmap_blk * fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
 				goto fail;
 			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[ibmap_idx].inode_id)))
+						le32_to_cpu(bgd->inode_id)))
 				goto fail;
 			prev_inode_bitmap_index = ibmap_idx;
 		}
-		ext4fs_bg_free_inodes_dec(&bgd[ibmap_idx]);
+		ext4fs_bg_free_inodes_dec(bgd);
 		if (has_gdt_chksum)
-			bgd[ibmap_idx].bg_itable_unused =
-					bgd[ibmap_idx].free_inodes;
+			bgd->bg_itable_unused = bgd->free_inodes;
 		ext4fs_sb_free_inodes_dec(fs->sb);
 		goto success;
 	}
@@ -1559,7 +1564,7 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
 		return 0;
 
 	inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz;
-	blkno = le32_to_cpu(blkgrp.inode_table_id) +
+	blkno = ext4fs_bg_get_inode_table_id(&blkgrp, fs) +
 	    (ino % le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	/* Read the inode. */
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index b3ea07b..1015669 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -53,21 +53,26 @@ static void ext4fs_update(void)
 	short i;
 	ext4fs_update_journal();
 	struct ext_filesystem *fs = get_fs();
+	struct ext2_block_group *bgd = NULL;
 
 	/* update  super block */
 	put_ext4((uint64_t)(SUPERBLOCK_SIZE),
 		 (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE);
 
-	/* update block groups */
+	/* update block bitmaps */
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		fs->bgd[i].bg_checksum = cpu_to_le16(ext4fs_checksum_update(i));
-		put_ext4((uint64_t)le32_to_cpu(fs->bgd[i].block_id) * fs->blksz,
+		bgd = ext4fs_get_group_descriptor(fs, i);
+		bgd->bg_checksum = cpu_to_le16(ext4fs_checksum_update(i));
+		uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+		put_ext4(b_bitmap_blk * fs->blksz,
 			 fs->blk_bmaps[i], fs->blksz);
 	}
 
-	/* update inode table groups */
+	/* update inode bitmaps */
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		put_ext4((uint64_t)le32_to_cpu(fs->bgd[i].inode_id) * fs->blksz,
+		bgd = ext4fs_get_group_descriptor(fs, i);
+		uint64_t i_bitmap_blk = ext4fs_bg_get_inode_id(bgd, fs);
+		put_ext4(i_bitmap_blk * fs->blksz,
 			 fs->inode_bmaps[i], fs->blksz);
 	}
 
@@ -85,15 +90,12 @@ static void ext4fs_update(void)
 int ext4fs_get_bgdtable(void)
 {
 	int status;
-	int grp_desc_size;
 	struct ext_filesystem *fs = get_fs();
-	grp_desc_size = sizeof(struct ext2_block_group);
-	fs->no_blk_pergdt = (fs->no_blkgrp * grp_desc_size) / fs->blksz;
-	if ((fs->no_blkgrp * grp_desc_size) % fs->blksz)
-		fs->no_blk_pergdt++;
+	int gdsize_total = ROUND(fs->no_blkgrp * fs->gdsize, fs->blksz);
+	fs->no_blk_pergdt = gdsize_total / fs->blksz;
 
 	/* allocate memory for gdtable */
-	fs->gdtable = zalloc(fs->blksz * fs->no_blk_pergdt);
+	fs->gdtable = zalloc(gdsize_total);
 	if (!fs->gdtable)
 		return -ENOMEM;
 	/* read the group descriptor table */
@@ -130,8 +132,6 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 		printf("No memory\n");
 		return;
 	}
-	/* get  block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 
 	/* deleting the single indirect block associated with inode */
 	if (inode->b.blocks.indir_block != 0) {
@@ -144,18 +144,19 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 				bg_idx--;
 		}
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
 			status = ext4fs_devread(
-					   (lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-					   fs->sect_perblk, 0, fs->blksz,
-					   journal_buffer);
+					   b_bitmap_blk * fs->sect_perblk,
+					   0, fs->blksz, journal_buffer);
 			if (status == 0)
 				goto fail;
-			if (ext4fs_log_journal
-			    (journal_buffer, le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 		}
@@ -182,8 +183,6 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		printf("No memory\n");
 		return;
 	}
-	/* get the block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 
 	if (inode->b.blocks.double_indir_block != 0) {
 		di_buffer = zalloc(fs->blksz);
@@ -206,15 +205,18 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 				if (!remainder)
 					bg_idx--;
 			}
+			/* get  block group descriptor table */
+			bgd = ext4fs_get_group_descriptor(fs, bg_idx);
 			ext4fs_reset_block_bmap(*di_buffer,
 					fs->blk_bmaps[bg_idx], bg_idx);
 			di_buffer++;
-			ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+			ext4fs_bg_free_blocks_inc(bgd);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
-				status = ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id)
+				uint64_t b_bitmap_blk =
+					ext4fs_bg_get_block_id(bgd, fs);
+				status = ext4fs_devread(b_bitmap_blk
 							* fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -222,7 +224,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 					goto fail;
 
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[bg_idx].block_id)))
+						       b_bitmap_blk))
 					goto fail;
 				prev_bg_bmap_idx = bg_idx;
 			}
@@ -236,20 +238,20 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 			if (!remainder)
 				bg_idx--;
 		}
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
-			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread((lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-						fs->sect_perblk, 0, fs->blksz,
-						journal_buffer);
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
+						0, fs->blksz, journal_buffer);
 			if (status == 0)
 				goto fail;
 
-			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 		}
@@ -280,8 +282,6 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		printf("No memory\n");
 		return;
 	}
-	/* get block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 
 	if (inode->b.blocks.triple_indir_block != 0) {
 		tigp_buffer = zalloc(fs->blksz);
@@ -320,13 +320,17 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 							bg_idx);
 
 				tip_buffer++;
-				ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+				/* get  block group descriptor table */
+				bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+				ext4fs_bg_free_blocks_inc(bgd);
 				ext4fs_sb_free_blocks_inc(fs->sb);
 				/* journal backup */
 				if (prev_bg_bmap_idx != bg_idx) {
+					uint64_t b_bitmap_blk =
+						ext4fs_bg_get_block_id(bgd, fs);
 					status =
 					    ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
+							b_bitmap_blk *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -334,7 +338,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 						goto fail;
 
 					if (ext4fs_log_journal(journal_buffer,
-							       le32_to_cpu(bgd[bg_idx].block_id)))
+							       b_bitmap_blk))
 						goto fail;
 					prev_bg_bmap_idx = bg_idx;
 				}
@@ -356,21 +360,24 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 						fs->blk_bmaps[bg_idx], bg_idx);
 
 			tigp_buffer++;
-			ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+			/* get  block group descriptor table */
+			bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+			ext4fs_bg_free_blocks_inc(bgd);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
+				uint64_t b_bitmap_blk =
+					ext4fs_bg_get_block_id(bgd, fs);
 				memset(journal_buffer, '\0', fs->blksz);
-				status =
-				    ext4fs_devread(
-						   (lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-						   fs->sect_perblk, 0,
-						   fs->blksz, journal_buffer);
+				status = ext4fs_devread(b_bitmap_blk *
+							fs->sect_perblk, 0,
+							fs->blksz,
+							journal_buffer);
 				if (status == 0)
 					goto fail;
 
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[bg_idx].block_id)))
+						       b_bitmap_blk))
 					goto fail;
 				prev_bg_bmap_idx = bg_idx;
 			}
@@ -385,20 +392,19 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 				bg_idx--;
 		}
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
-			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(
-						(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-						fs->sect_perblk, 0, fs->blksz,
-						journal_buffer);
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
+						0, fs->blksz, journal_buffer);
 			if (status == 0)
 				goto fail;
 
-			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 		}
@@ -435,8 +441,6 @@ static int ext4fs_delete_file(int inodeno)
 	char *journal_buffer = zalloc(fs->blksz);
 	if (!journal_buffer)
 		return -ENOMEM;
-	/* get the block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 	status = ext4fs_read_inode(ext4fs_root, inodeno, &inode);
 	if (status == 0)
 		goto fail;
@@ -475,18 +479,19 @@ static int ext4fs_delete_file(int inodeno)
 					bg_idx);
 		debug("EXT4 Block releasing %ld: %d\n", blknr, bg_idx);
 
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
-			uint32_t bgd_blknr = le32_to_cpu(bgd[bg_idx].block_id);
-			status = ext4fs_devread((lbaint_t)bgd_blknr *
-						fs->sect_perblk,
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
 						0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
 				goto fail;
-			if (ext4fs_log_journal(journal_buffer, bgd_blknr))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 		}
@@ -499,7 +504,9 @@ static int ext4fs_delete_file(int inodeno)
 
 	/* get the block no */
 	inodeno--;
-	blkno = le32_to_cpu(bgd[ibmap_idx].inode_table_id) +
+	/* get  block group descriptor table */
+	bgd = ext4fs_get_group_descriptor(fs, ibmap_idx);
+	blkno = ext4fs_bg_get_inode_table_id(bgd, fs) +
 		(inodeno % inode_per_grp) / inodes_per_block;
 
 	/* get the offset of the inode */
@@ -529,15 +536,15 @@ static int ext4fs_delete_file(int inodeno)
 	/* update the respective inode bitmaps */
 	inodeno++;
 	ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx);
-	ext4fs_bg_free_inodes_inc(&bgd[ibmap_idx]);
+	ext4fs_bg_free_inodes_inc(bgd);
 	ext4fs_sb_free_inodes_inc(fs->sb);
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
-	status = ext4fs_devread((lbaint_t)le32_to_cpu(bgd[ibmap_idx].inode_id) *
+	status = ext4fs_devread(ext4fs_bg_get_inode_id(bgd, fs) *
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 	if (status == 0)
 		goto fail;
-	if (ext4fs_log_journal(journal_buffer, le32_to_cpu(bgd[ibmap_idx].inode_id)))
+	if (ext4fs_log_journal(journal_buffer, ext4fs_bg_get_inode_id(bgd, fs)))
 		goto fail;
 
 	ext4fs_update();
@@ -594,7 +601,6 @@ int ext4fs_init(void)
 		printf("Error in getting the block group descriptor table\n");
 		goto fail;
 	}
-	fs->bgd = (struct ext2_block_group *)fs->gdtable;
 
 	/* load all the available bitmap block of the partition */
 	fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *));
@@ -607,9 +613,9 @@ int ext4fs_init(void)
 	}
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status =
-		    ext4fs_devread(
-				   (lbaint_t)le32_to_cpu(fs->bgd[i].block_id) *
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, i);
+		status = ext4fs_devread(ext4fs_bg_get_block_id(bgd, fs) *
 				   fs->sect_perblk, 0,
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 		if (status == 0)
@@ -627,8 +633,9 @@ int ext4fs_init(void)
 	}
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status = ext4fs_devread(
-					(lbaint_t)le32_to_cpu(fs->bgd[i].inode_id) *
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, i);
+		status = ext4fs_devread(ext4fs_bg_get_inode_id(bgd, fs) *
 					fs->sect_perblk,
 					0, fs->blksz,
 					(char *)fs->inode_bmaps[i]);
@@ -642,10 +649,14 @@ int ext4fs_init(void)
 	 * with the  blockgroups freeblocks when improper
 	 * reboot of a linux kernel
 	 */
-	for (i = 0; i < fs->no_blkgrp; i++)
-		real_free_blocks = real_free_blocks + le16_to_cpu(fs->bgd[i].free_blocks);
-	if (real_free_blocks != le32_to_cpu(fs->sb->free_blocks))
-		fs->sb->free_blocks = cpu_to_le32(real_free_blocks);
+	for (i = 0; i < fs->no_blkgrp; i++) {
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, i);
+		real_free_blocks = real_free_blocks +
+			ext4fs_bg_get_free_blocks(bgd, fs);
+	}
+	if (real_free_blocks != ext4fs_sb_get_free_blocks(fs->sb))
+		ext4fs_sb_set_free_blocks(fs->sb, real_free_blocks);
 
 	return 0;
 fail:
@@ -711,7 +722,6 @@ void ext4fs_deinit(void)
 
 	free(fs->gdtable);
 	fs->gdtable = NULL;
-	fs->bgd = NULL;
 	/*
 	 * reinitiliazed the global inode and
 	 * block bitmap first execution check variables
@@ -826,6 +836,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	struct ext2_sblock *sblock = &(ext4fs_root->sblock);
 	unsigned int inodes_per_block;
 	unsigned int ibmap_idx;
+	struct ext2_block_group *bgd = NULL;
 	struct ext_filesystem *fs = get_fs();
 	ALLOC_CACHE_ALIGN_BUFFER(char, filename, 256);
 	memset(filename, 0x00, 256);
@@ -903,7 +914,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 		goto fail;
 	ibmap_idx = inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
 	inodeno--;
-	itable_blkno = le32_to_cpu(fs->bgd[ibmap_idx].inode_table_id) +
+	bgd = ext4fs_get_group_descriptor(fs, ibmap_idx);
+	itable_blkno = ext4fs_bg_get_inode_table_id(bgd, fs) +
 			(inodeno % le32_to_cpu(sblock->inodes_per_group)) /
 			inodes_per_block;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
@@ -923,7 +935,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	}
 	ibmap_idx = parent_inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
 	parent_inodeno--;
-	parent_itable_blkno = le32_to_cpu(fs->bgd[ibmap_idx].inode_table_id) +
+	bgd = ext4fs_get_group_descriptor(fs, ibmap_idx);
+	parent_itable_blkno = ext4fs_bg_get_inode_table_id(bgd, fs) +
 	    (parent_inodeno %
 	     le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
diff --git a/include/ext4fs.h b/include/ext4fs.h
index 7e1ee6c..965cd9e 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -98,7 +98,6 @@ struct ext_filesystem {
 	/* Superblock */
 	struct ext2_sblock *sb;
 	/* Block group descritpor table */
-	struct ext2_block_group *bgd;
 	char *gdtable;
 
 	/* Block Bitmap Related */
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 6/7] ext4: Respect group descriptor size when adjusting free counts
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
                   ` (4 preceding siblings ...)
  2016-09-17  0:10 ` [U-Boot] [PATCH 5/7] ext4: Use helper function to access group descriptor and its fields Stefan Brüns
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-17  0:10 ` [U-Boot] [PATCH 7/7] ext4: Revert rejection of 64bit enabled ext4 fs Stefan Brüns
  6 siblings, 0 replies; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

Also adjust high 16/32 bits when free inode/block counts are modified.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 fs/ext4/ext4_common.c | 53 +++++++++++++++++++++++++++++++++++++++------------
 fs/ext4/ext4_write.c  | 40 ++++++++++++++++++++++++++------------
 2 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 0c2ac47..61c4d19 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -58,24 +58,53 @@ static inline void ext4fs_sb_free_inodes_dec(struct ext2_sblock *sb)
 	sb->free_inodes = cpu_to_le32(le32_to_cpu(sb->free_inodes) - 1);
 }
 
-static inline void ext4fs_bg_free_inodes_dec(struct ext2_block_group *bg)
+static inline void ext4fs_bg_free_inodes_dec
+	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
 {
-	bg->free_inodes = cpu_to_le16(le16_to_cpu(bg->free_inodes) - 1);
+	uint32_t free_inodes = le16_to_cpu(bg->free_inodes);
+	if (fs->gdsize == 64)
+		free_inodes += le16_to_cpu(bg->free_inodes_high) << 16;
+	free_inodes--;
+
+	bg->free_inodes = cpu_to_le16(free_inodes & 0xffff);
+	if (fs->gdsize == 64)
+		bg->free_inodes_high = cpu_to_le16(free_inodes >> 16);
 }
 
-static inline void ext4fs_bg_free_blocks_dec(struct ext2_block_group *bg)
+static inline void ext4fs_bg_free_blocks_dec
+	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
 {
-	bg->free_blocks = cpu_to_le16(le16_to_cpu(bg->free_blocks) - 1);
+	uint32_t free_blocks = le16_to_cpu(bg->free_blocks);
+	if (fs->gdsize == 64)
+		free_blocks += le16_to_cpu(bg->free_blocks_high) << 16;
+	free_blocks--;
+
+	bg->free_blocks = cpu_to_le16(free_blocks & 0xffff);
+	if (fs->gdsize == 64)
+		bg->free_blocks_high = cpu_to_le16(free_blocks >> 16);
 }
 
 static inline void ext4fs_sb_free_blocks_dec(struct ext2_sblock *sb)
 {
-	sb->free_blocks = cpu_to_le32(le32_to_cpu(sb->free_blocks) - 1);
+	uint64_t free_blocks = le32_to_cpu(sb->free_blocks);
+	free_blocks += (uint64_t)le32_to_cpu(sb->free_blocks_high) << 32;
+	free_blocks--;
+
+	sb->free_blocks = cpu_to_le32(free_blocks & 0xffffffff);
+	sb->free_blocks_high = cpu_to_le16(free_blocks >> 32);
 }
 
-static inline void ext4fs_bg_itable_unused_dec(struct ext2_block_group *bg)
+static inline void ext4fs_bg_itable_unused_dec
+	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
 {
-	bg->bg_itable_unused = cpu_to_le16(le16_to_cpu(bg->bg_itable_unused) - 1);
+	uint32_t free_inodes = le16_to_cpu(bg->bg_itable_unused);
+	if (fs->gdsize == 64)
+		free_inodes += le16_to_cpu(bg->bg_itable_unused_high) << 16;
+	free_inodes--;
+
+	bg->bg_itable_unused = cpu_to_le16(free_inodes & 0xffff);
+	if (fs->gdsize == 64)
+		bg->bg_itable_unused_high = cpu_to_le16(free_inodes >> 16);
 }
 
 uint64_t ext4fs_sb_get_free_blocks(const struct ext2_sblock *sb)
@@ -956,7 +985,7 @@ uint32_t ext4fs_get_new_blk_no(void)
 				fs->curr_blkno = fs->curr_blkno +
 						(i * fs->blksz * 8);
 				fs->first_pass_bbmap++;
-				ext4fs_bg_free_blocks_dec(bgd);
+				ext4fs_bg_free_blocks_dec(bgd, fs);
 				ext4fs_sb_free_blocks_dec(fs->sb);
 				status = ext4fs_devread(b_bitmap_blk *
 							fs->sect_perblk,
@@ -1031,7 +1060,7 @@ restart:
 
 			prev_bg_bitmap_index = bg_idx;
 		}
-		ext4fs_bg_free_blocks_dec(bgd);
+		ext4fs_bg_free_blocks_dec(bgd, fs);
 		ext4fs_sb_free_blocks_dec(fs->sb);
 		goto success;
 	}
@@ -1090,9 +1119,9 @@ int ext4fs_get_new_inode_no(void)
 				fs->curr_inode_no = fs->curr_inode_no +
 							(i * inodes_per_grp);
 				fs->first_pass_ibmap++;
-				ext4fs_bg_free_inodes_dec(bgd);
+				ext4fs_bg_free_inodes_dec(bgd, fs);
 				if (has_gdt_chksum)
-					ext4fs_bg_itable_unused_dec(bgd);
+					ext4fs_bg_itable_unused_dec(bgd, fs);
 				ext4fs_sb_free_inodes_dec(fs->sb);
 				status = ext4fs_devread(i_bitmap_blk *
 							fs->sect_perblk,
@@ -1146,7 +1175,7 @@ restart:
 				goto fail;
 			prev_inode_bitmap_index = ibmap_idx;
 		}
-		ext4fs_bg_free_inodes_dec(bgd);
+		ext4fs_bg_free_inodes_dec(bgd, fs);
 		if (has_gdt_chksum)
 			bgd->bg_itable_unused = bgd->free_inodes;
 		ext4fs_sb_free_inodes_dec(fs->sb);
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 1015669..3ce5946 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -38,14 +38,30 @@ static inline void ext4fs_sb_free_blocks_inc(struct ext2_sblock *sb)
 	sb->free_blocks = cpu_to_le32(le32_to_cpu(sb->free_blocks) + 1);
 }
 
-static inline void ext4fs_bg_free_inodes_inc(struct ext2_block_group *bg)
+static inline void ext4fs_bg_free_inodes_inc
+	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
 {
-	bg->free_inodes = cpu_to_le16(le16_to_cpu(bg->free_inodes) + 1);
+	uint32_t free_inodes = le16_to_cpu(bg->free_inodes);
+	if (fs->gdsize == 64)
+		free_inodes += le16_to_cpu(bg->free_inodes_high) << 16;
+	free_inodes++;
+
+	bg->free_inodes = cpu_to_le16(free_inodes & 0xffff);
+	if (fs->gdsize == 64)
+		bg->free_inodes_high = cpu_to_le16(free_inodes >> 16);
 }
 
-static inline void ext4fs_bg_free_blocks_inc(struct ext2_block_group *bg)
+static inline void ext4fs_bg_free_blocks_inc
+	(struct ext2_block_group *bg, const struct ext_filesystem *fs)
 {
-	bg->free_blocks = cpu_to_le16(le16_to_cpu(bg->free_blocks) + 1);
+	uint32_t free_blocks = le16_to_cpu(bg->free_blocks);
+	if (fs->gdsize == 64)
+		free_blocks += le16_to_cpu(bg->free_blocks_high) << 16;
+	free_blocks++;
+
+	bg->free_blocks = cpu_to_le16(free_blocks & 0xffff);
+	if (fs->gdsize == 64)
+		bg->free_blocks_high = cpu_to_le16(free_blocks >> 16);
 }
 
 static void ext4fs_update(void)
@@ -146,7 +162,7 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
 		/* get  block group descriptor table */
 		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
-		ext4fs_bg_free_blocks_inc(bgd);
+		ext4fs_bg_free_blocks_inc(bgd, fs);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
@@ -210,7 +226,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 			ext4fs_reset_block_bmap(*di_buffer,
 					fs->blk_bmaps[bg_idx], bg_idx);
 			di_buffer++;
-			ext4fs_bg_free_blocks_inc(bgd);
+			ext4fs_bg_free_blocks_inc(bgd, fs);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
@@ -241,7 +257,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		/* get  block group descriptor table */
 		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(bgd);
+		ext4fs_bg_free_blocks_inc(bgd, fs);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
@@ -322,7 +338,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 				tip_buffer++;
 				/* get  block group descriptor table */
 				bgd = ext4fs_get_group_descriptor(fs, bg_idx);
-				ext4fs_bg_free_blocks_inc(bgd);
+				ext4fs_bg_free_blocks_inc(bgd, fs);
 				ext4fs_sb_free_blocks_inc(fs->sb);
 				/* journal backup */
 				if (prev_bg_bmap_idx != bg_idx) {
@@ -362,7 +378,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			tigp_buffer++;
 			/* get  block group descriptor table */
 			bgd = ext4fs_get_group_descriptor(fs, bg_idx);
-			ext4fs_bg_free_blocks_inc(bgd);
+			ext4fs_bg_free_blocks_inc(bgd, fs);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
@@ -394,7 +410,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
 		/* get  block group descriptor table */
 		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
-		ext4fs_bg_free_blocks_inc(bgd);
+		ext4fs_bg_free_blocks_inc(bgd, fs);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
@@ -481,7 +497,7 @@ static int ext4fs_delete_file(int inodeno)
 
 		/* get  block group descriptor table */
 		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
-		ext4fs_bg_free_blocks_inc(bgd);
+		ext4fs_bg_free_blocks_inc(bgd, fs);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
@@ -536,7 +552,7 @@ static int ext4fs_delete_file(int inodeno)
 	/* update the respective inode bitmaps */
 	inodeno++;
 	ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx);
-	ext4fs_bg_free_inodes_inc(bgd);
+	ext4fs_bg_free_inodes_inc(bgd, fs);
 	ext4fs_sb_free_inodes_inc(fs->sb);
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 7/7] ext4: Revert rejection of 64bit enabled ext4 fs
       [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
                   ` (5 preceding siblings ...)
  2016-09-17  0:10 ` [U-Boot] [PATCH 6/7] ext4: Respect group descriptor size when adjusting free counts Stefan Brüns
@ 2016-09-17  0:10 ` Stefan Brüns
  2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
  6 siblings, 1 reply; 14+ messages in thread
From: Stefan Brüns @ 2016-09-17  0:10 UTC (permalink / raw)
  To: u-boot

Enable mounting of ext4 fs with 64bit feature, as it is supported now.
These had been disabled in 6f94ab6656ceffb3f2a972c8de4c554502b6f2b7.

Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
---
 fs/ext4/ext4_common.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 61c4d19..bd81744 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -2337,15 +2337,6 @@ int ext4fs_mount(unsigned part_length)
 	if (le16_to_cpu(data->sblock.magic) != EXT2_MAGIC)
 		goto fail;
 
-	/*
-	 * The 64bit feature was enabled when metadata_csum was enabled
-	 * and we do not support metadata_csum (and cannot reliably find
-	 * files when it is set.  Refuse to mount.
-	 */
-	if (le32_to_cpu(data->sblock.feature_incompat) & EXT4_FEATURE_INCOMPAT_64BIT) {
-		printf("Unsupported feature found (64bit, possibly metadata_csum), not mounting\n");
-		goto fail;
-	}
 
 	if (le32_to_cpu(data->sblock.revision_level) == 0) {
 		fs->inodesz = 128;
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [U-Boot] [U-Boot, 1/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures
  2016-09-17  0:10 ` [U-Boot] [PATCH 1/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Stefan Brüns
@ 2016-09-23 19:56   ` Tom Rini
  0 siblings, 0 replies; 14+ messages in thread
From: Tom Rini @ 2016-09-23 19:56 UTC (permalink / raw)
  To: u-boot

On Sat, Sep 17, 2016 at 02:10:06AM +0200, Stefan Br?ns wrote:

> Most importantly, the superblock provides the used group descriptor size,
> which is required for the EXT4_FEATURE_INCOMPAT_64BIT.
> 
> Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160923/55390174/attachment.sig>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [U-Boot, 2/7] ext4: determine group descriptor size for 64bit feature
  2016-09-17  0:10 ` [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature Stefan Brüns
@ 2016-09-23 19:56   ` Tom Rini
  2016-12-26  8:23   ` [U-Boot] [PATCH " Kever Yang
  1 sibling, 0 replies; 14+ messages in thread
From: Tom Rini @ 2016-09-23 19:56 UTC (permalink / raw)
  To: u-boot

On Sat, Sep 17, 2016 at 02:10:07AM +0200, Stefan Br?ns wrote:

> If EXT4_FEATURE_INCOMPAT_64BIT is set, the descriptor can be read from
> the superblocks, otherwise it defaults to 32.
> 
> Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160923/914a74ba/attachment.sig>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [U-Boot, 4/7] ext4: Use correct descriptor size when reading the block group descriptor
  2016-09-17  0:10 ` [U-Boot] [PATCH 4/7] ext4: Use correct descriptor size when reading the block group descriptor Stefan Brüns
@ 2016-09-23 19:56   ` Tom Rini
  0 siblings, 0 replies; 14+ messages in thread
From: Tom Rini @ 2016-09-23 19:56 UTC (permalink / raw)
  To: u-boot

On Sat, Sep 17, 2016 at 02:10:09AM +0200, Stefan Br?ns wrote:

> The correct descriptor size must be used when calculating offsets, and
> also to read the correct amount of data.
> 
> Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160923/ff1098e7/attachment.sig>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [U-Boot, 5/7] ext4: Use helper function to access group descriptor and its fields
  2016-09-17  0:10 ` [U-Boot] [PATCH 5/7] ext4: Use helper function to access group descriptor and its fields Stefan Brüns
@ 2016-09-23 19:56   ` Tom Rini
  0 siblings, 0 replies; 14+ messages in thread
From: Tom Rini @ 2016-09-23 19:56 UTC (permalink / raw)
  To: u-boot

On Sat, Sep 17, 2016 at 02:10:10AM +0200, Stefan Br?ns wrote:

> The descriptor size is variable, thus array indices are not generically
> applicable. The larger group descriptors also contain e.g. high parts
> of block numbers, which have to be read and written.
> 
> Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160923/c45393a0/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [U-Boot, 7/7] ext4: Revert rejection of 64bit enabled ext4 fs
  2016-09-17  0:10 ` [U-Boot] [PATCH 7/7] ext4: Revert rejection of 64bit enabled ext4 fs Stefan Brüns
@ 2016-09-23 19:56   ` Tom Rini
  0 siblings, 0 replies; 14+ messages in thread
From: Tom Rini @ 2016-09-23 19:56 UTC (permalink / raw)
  To: u-boot

On Sat, Sep 17, 2016 at 02:10:12AM +0200, Stefan Br?ns wrote:

> Enable mounting of ext4 fs with 64bit feature, as it is supported now.
> These had been disabled in 6f94ab6656ceffb3f2a972c8de4c554502b6f2b7.
> 
> Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160923/cccc8bb6/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature
  2016-09-17  0:10 ` [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature Stefan Brüns
  2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
@ 2016-12-26  8:23   ` Kever Yang
  2016-12-27  1:37     ` Stefan Bruens
  1 sibling, 1 reply; 14+ messages in thread
From: Kever Yang @ 2016-12-26  8:23 UTC (permalink / raw)
  To: u-boot

Hi Stefan, Tom,

     I'm using genext2fs command in Linux to generate my boot image for
kernel and its dtb, my command is like this:
     $ genext2fs -b 32768 -B $((32*1024*1024/32768)) -d boot/ -i 8192 -U 
boot.img

     In the latest version of U-Boot, the image from above command is 
not able
to be mount. After debug, I found out that the root cause is that the 
genext2fs
does not have a initial value for revision_level in super block. After I 
do the mount
and umount for the image in Linux, the U-Boot then can mount the image.

     Is it possible to still support the ext2 image generated by 
genext2fs command in U-Boot?

Thanks,
- Kever
On 09/17/2016 08:10 AM, Stefan Br?ns wrote:
> If EXT4_FEATURE_INCOMPAT_64BIT is set, the descriptor can be read from
> the superblocks, otherwise it defaults to 32.
>
> Signed-off-by: Stefan Br?ns <stefan.bruens@rwth-aachen.de>
> ---
>   fs/ext4/ext4_common.c | 18 ++++++++++++++----
>   include/ext4fs.h      |  2 ++
>   2 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
> index a78b0b8..416a9db 100644
> --- a/fs/ext4/ext4_common.c
> +++ b/fs/ext4/ext4_common.c
> @@ -2233,13 +2233,23 @@ int ext4fs_mount(unsigned part_length)
>   		goto fail;
>   	}
>   
> -	if (le32_to_cpu(data->sblock.revision_level) == 0)
> +	if (le32_to_cpu(data->sblock.revision_level) == 0) {
>   		fs->inodesz = 128;
> -	else
> +	} else {
> +		debug("EXT4 features COMPAT: %08x INCOMPAT: %08x RO_COMPAT: %08x\n",
> +		      __le32_to_cpu(data->sblock.feature_compatibility),
> +		      __le32_to_cpu(data->sblock.feature_incompat),
> +		      __le32_to_cpu(data->sblock.feature_ro_compat));
> +
>   		fs->inodesz = le16_to_cpu(data->sblock.inode_size);
> +		fs->gdsize = le32_to_cpu(data->sblock.feature_incompat) &
> +			EXT4_FEATURE_INCOMPAT_64BIT ?
> +			le16_to_cpu(data->sblock.descriptor_size) : 32;
> +	}
>   
> -	debug("EXT2 rev %d, inode_size %d\n",
> -	       le32_to_cpu(data->sblock.revision_level), fs->inodesz);
> +	debug("EXT2 rev %d, inode_size %d, descriptor size %d\n",
> +	      le32_to_cpu(data->sblock.revision_level),
> +	      fs->inodesz, fs->gdsize);
>   
>   	data->diropen.data = data;
>   	data->diropen.ino = 2;
> diff --git a/include/ext4fs.h b/include/ext4fs.h
> index 6e31c73..7e1ee6c 100644
> --- a/include/ext4fs.h
> +++ b/include/ext4fs.h
> @@ -87,6 +87,8 @@ struct ext_filesystem {
>   	uint32_t inodesz;
>   	/* Sectors per Block */
>   	uint32_t sect_perblk;
> +	/* Group Descriptor size */
> +	uint16_t gdsize;
>   	/* Group Descriptor Block Number */
>   	uint32_t gdtable_blkno;
>   	/* Total block groups of partition */

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature
  2016-12-26  8:23   ` [U-Boot] [PATCH " Kever Yang
@ 2016-12-27  1:37     ` Stefan Bruens
  0 siblings, 0 replies; 14+ messages in thread
From: Stefan Bruens @ 2016-12-27  1:37 UTC (permalink / raw)
  To: u-boot

Hi Kever,

can you test the ext4 patch I just posted?

Kind regards,

Stefan

-- 
Stefan Br?ns  /  Bergstra?e 21  /  52062 Aachen
home: +49 241 53809034     mobile: +49 151 50412019
work: +49 2405 49936-424

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-12-27  1:37 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20160917001012.10498-1-stefan.bruens@rwth-aachen.de>
2016-09-17  0:10 ` [U-Boot] [PATCH 1/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Stefan Brüns
2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
2016-09-17  0:10 ` [U-Boot] [PATCH 2/7] ext4: determine group descriptor size for 64bit feature Stefan Brüns
2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
2016-12-26  8:23   ` [U-Boot] [PATCH " Kever Yang
2016-12-27  1:37     ` Stefan Bruens
2016-09-17  0:10 ` [U-Boot] [PATCH 3/7] ext4: Add helper functions for block group descriptor field access Stefan Brüns
2016-09-17  0:10 ` [U-Boot] [PATCH 4/7] ext4: Use correct descriptor size when reading the block group descriptor Stefan Brüns
2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
2016-09-17  0:10 ` [U-Boot] [PATCH 5/7] ext4: Use helper function to access group descriptor and its fields Stefan Brüns
2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini
2016-09-17  0:10 ` [U-Boot] [PATCH 6/7] ext4: Respect group descriptor size when adjusting free counts Stefan Brüns
2016-09-17  0:10 ` [U-Boot] [PATCH 7/7] ext4: Revert rejection of 64bit enabled ext4 fs Stefan Brüns
2016-09-23 19:56   ` [U-Boot] [U-Boot, " Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.