[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20140816234616.11171.78225.stgit@birch.djwong.org>
Date: Sat, 16 Aug 2014 16:46:16 -0700
From: "Darrick J. Wong" <darrick.wong@...cle.com>
To: tytso@....edu, darrick.wong@...cle.com
Cc: linux-ext4@...r.kernel.org
Subject: [PATCH 04/27] libext2fs: fix problems with LE<->BE conversions on
BE platforms
Fix more problems that I found when testing on ppc64:
- Inode swap cut and paste error leads to immutable inodes being
detected as inlinedata inodes, leading to e2fsck incorrectly barfing
on i_block[] contents.
- Superblock csum/verify must be aware of the fs->super byte order
when checking for metadata_csum feature flag. (Hint: in _openfs(),
fs->super is in LE order for the first csum verification)
Signed-off-by: Darrick J. Wong <darrick.wong@...cle.com>
---
lib/ext2fs/csum.c | 26 ++++++++++++++++++--------
lib/ext2fs/swapfs.c | 2 +-
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index d7dbca8..12f6fe9 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -81,12 +81,17 @@ static __u32 ext2fs_superblock_csum(ext2_filsys fs EXT2FS_ATTR((unused)),
return ext2fs_crc32c_le(~0, (unsigned char *)sb, offset);
}
+/* NOTE: The input to this function MUST be in LE order */
int ext2fs_superblock_csum_verify(ext2_filsys fs, struct ext2_super_block *sb)
{
- __u32 calculated;
+ __u32 flag, calculated;
- if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ flag = EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
+ else
+ flag = ext2fs_cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
+
+ if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, flag))
return 1;
calculated = ext2fs_superblock_csum(fs, sb);
@@ -94,13 +99,18 @@ int ext2fs_superblock_csum_verify(ext2_filsys fs, struct ext2_super_block *sb)
return ext2fs_le32_to_cpu(sb->s_checksum) == calculated;
}
+/* NOTE: The input to this function MUST be in LE order */
errcode_t ext2fs_superblock_csum_set(ext2_filsys fs,
struct ext2_super_block *sb)
{
- __u32 crc;
+ __u32 flag, crc;
- if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ flag = EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
+ else
+ flag = ext2fs_cpu_to_le32(EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
+
+ if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, flag))
return 0;
crc = ext2fs_superblock_csum(fs, sb);
@@ -756,8 +766,8 @@ __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
#ifdef WORDS_BIGENDIAN
if (save_size > ext4_bg_size)
crc32 = ext2fs_crc32c_le(crc32,
- (char *)save_desc + ext4_bg_size,
- save_size - ext4_bg_size);
+ (unsigned char *)save_desc + ext4_bg_size,
+ save_size - ext4_bg_size);
#endif
crc = crc32 & 0xFFFF;
goto out;
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index e2aa41d..ee7a455 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -243,7 +243,7 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
t->i_flags = ext2fs_swab32(f->i_flags);
if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
has_extents = 1;
- if (!hostorder && (f->i_flags & EXT4_INLINE_DATA_FL))
+ if (!hostorder && (t->i_flags & EXT4_INLINE_DATA_FL))
has_inline_data = 1;
t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
/*
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists