Blame SOURCES/0002-ext4-Fix-64bit-feature.patch

f7dd65
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
ecc4ed
From: Paulo Alcantara <pcacjr@zytor.com>
ecc4ed
Date: Wed, 11 Oct 2017 07:00:31 -0400
ecc4ed
Subject: [PATCH] ext4: Fix 64bit feature
ecc4ed
ecc4ed
As per ext4 specification:
ecc4ed
ecc4ed
> In ext2, ext3, and ext4 (when the 64bit feature is not enabled), the
ecc4ed
> block group descriptor was only 32 bytes long and therefore ends at
ecc4ed
> bg_checksum. On an ext4 filesystem with the 64bit feature enabled, the
ecc4ed
> block group descriptor expands to at least the 64 bytes described below;
ecc4ed
> the size is stored in the superblock.
ecc4ed
ecc4ed
Since block group descriptor has been expanded to 64 bytes long (when 64
ecc4ed
bit feature is enabled), we cannot index ext2_group_desc and return it
ecc4ed
*directly* -- as we did it in ext2_get_group_desc -- it's still 32 bytes
ecc4ed
long.
ecc4ed
ecc4ed
Instead, use s_desc_size field from superblock to correctly index and
ecc4ed
return block group descriptors.
ecc4ed
ecc4ed
Cc: H. Peter Anvin <hpa@zytor.com>
ecc4ed
Cc: Gene Cumm <gene.cumm@gmail.com>
ecc4ed
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
ecc4ed
---
ecc4ed
 core/fs/ext2/ext2.c    | 23 ++++++++++++++---------
ecc4ed
 core/fs/ext2/ext2_fs.h |  1 +
ecc4ed
 2 files changed, 15 insertions(+), 9 deletions(-)
ecc4ed
ecc4ed
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
f7dd65
index 76bd1d5a..4bc0a535 100644
ecc4ed
--- a/core/fs/ext2/ext2.c
ecc4ed
+++ b/core/fs/ext2/ext2.c
ecc4ed
@@ -25,22 +25,17 @@ static enum dirent_type ext2_cvt_type(unsigned int d_file_type)
ecc4ed
 	return inode_type[d_file_type];
ecc4ed
 }
ecc4ed
 
ecc4ed
-/*
ecc4ed
- * get the group's descriptor of group_num
ecc4ed
- */
ecc4ed
-static const struct ext2_group_desc *
ecc4ed
-ext2_get_group_desc(struct fs_info *fs, uint32_t group_num)
ecc4ed
+static const void *__ext2_get_group_desc(struct fs_info *fs, uint32_t group_num)
ecc4ed
 {
ecc4ed
     struct ext2_sb_info *sbi = EXT2_SB(fs);
ecc4ed
     uint32_t desc_block, desc_index;
ecc4ed
-    const struct ext2_group_desc *desc_data_block;
ecc4ed
+    uint8_t *p;
ecc4ed
 
ecc4ed
     if (group_num >= sbi->s_groups_count) {
ecc4ed
 	printf ("ext2_get_group_desc"
ecc4ed
 		"block_group >= groups_count - "
ecc4ed
 		"block_group = %d, groups_count = %d",
ecc4ed
 		group_num, sbi->s_groups_count);
ecc4ed
-
ecc4ed
 	return NULL;
ecc4ed
     }
ecc4ed
 
ecc4ed
@@ -49,8 +44,17 @@ ext2_get_group_desc(struct fs_info *fs, uint32_t group_num)
ecc4ed
 
ecc4ed
     desc_block += sbi->s_first_data_block + 1;
ecc4ed
 
ecc4ed
-    desc_data_block = get_cache(fs->fs_dev, desc_block);
ecc4ed
-    return &desc_data_block[desc_index];
ecc4ed
+    p = get_cache(fs->fs_dev, desc_block);
ecc4ed
+    return p + sbi->s_desc_size * desc_index;
ecc4ed
+}
ecc4ed
+
ecc4ed
+/*
ecc4ed
+ * get the group's descriptor of group_num
ecc4ed
+ */
ecc4ed
+static inline const struct ext2_group_desc *
ecc4ed
+ext2_get_group_desc(struct fs_info *fs, uint32_t group_num)
ecc4ed
+{
ecc4ed
+    return __ext2_get_group_desc(fs, group_num);
ecc4ed
 }
ecc4ed
 
ecc4ed
 /*
ecc4ed
@@ -306,6 +310,7 @@ static int ext2_fs_init(struct fs_info *fs)
ecc4ed
     if (sb.s_desc_size < sizeof(struct ext2_group_desc))
ecc4ed
 	sb.s_desc_size = sizeof(struct ext2_group_desc);
ecc4ed
     sbi->s_desc_per_block   = BLOCK_SIZE(fs) / sb.s_desc_size;
ecc4ed
+    sbi->s_desc_size = sb.s_desc_size;
ecc4ed
     sbi->s_groups_count     = (sb.s_blocks_count - sb.s_first_data_block
ecc4ed
 			       + EXT2_BLOCKS_PER_GROUP(fs) - 1)
ecc4ed
 	                      / EXT2_BLOCKS_PER_GROUP(fs);
ecc4ed
diff --git a/core/fs/ext2/ext2_fs.h b/core/fs/ext2/ext2_fs.h
f7dd65
index 803a9954..d8d07ebd 100644
ecc4ed
--- a/core/fs/ext2/ext2_fs.h
ecc4ed
+++ b/core/fs/ext2/ext2_fs.h
ecc4ed
@@ -278,6 +278,7 @@ struct ext2_sb_info {
ecc4ed
     uint32_t s_first_data_block;	/* First Data Block */
ecc4ed
     int      s_inode_size;
ecc4ed
     uint8_t  s_uuid[16];	/* 128-bit uuid for volume */
ecc4ed
+    int      s_desc_size;	/* size of group descriptor */
ecc4ed
 };
ecc4ed
 
ecc4ed
 static inline struct ext2_sb_info *EXT2_SB(struct fs_info *fs)