[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1183099312.3043.2.camel@dhcp7.linsyssoft.com>
Date: Fri, 29 Jun 2007 12:11:52 +0530
From: Girish Shilamkar <girish@...sterfs.com>
To: Ext4 Mailing List <linux-ext4@...r.kernel.org>
Cc: Andreas Dilger <adilger@...sterfs.com>,
Theodore Tso <tytso@....edu>
Subject: [PATCH] Add in-inode extents swabbing.
Hi,
On big-endian machines the regressions tests for extents failed.
Upon further investigations I found that ext2fs_swap_inode_full() didn't
take into consideration whether extent map or block map is used hence even
if an inode contains extents, i_block was swabbed using ext2fs_swab32(),
without considering the extents format.
Even after this three tests failed:
f_extents_eh_magic:
In pass1 as magic is incorrect the extents flag in inode->i_flag is reset.
Hence when check_blocks calls *_ind_verify and as now i_blocks are interpreted
as u32 instead of extents format. and qsorts does a diff sort and hence
different output is generated by regression test.
f_extents_eh_max : Same as above.
f_extents :
Inode 13 has inode->i_flags not set for extents hence while swapping it
assumes
it to be block map.
The patch needs to be further improved by taking into consideration that
inode->i_flags might be corrupt.
Regards,
Girish
Signed-off-by: Girish Shilamkar <girish@...sterfs.com>
Index: e2fsprogs-1.39/lib/ext2fs/swapfs.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/swapfs.c
+++ e2fsprogs-1.39/lib/ext2fs/swapfs.c
@@ -168,7 +168,7 @@ void ext2fs_swap_inode_full(ext2_filsys
struct ext2_inode_large *f, int hostorder,
int bufsize)
{
- unsigned i, has_data_blocks, extra_isize;
+ unsigned i, has_data_blocks, extra_isize, has_extents;
int islnk = 0;
__u32 *eaf, *eat;
@@ -192,15 +192,44 @@ void ext2fs_swap_inode_full(ext2_filsys
if (!hostorder)
has_data_blocks = ext2fs_inode_data_blocks(fs,
(struct ext2_inode *) t);
+ if (hostorder)
+ has_extents = (f->i_flags & EXT4_EXTENTS_FL);
t->i_flags = ext2fs_swab32(f->i_flags);
+ if (!hostorder)
+ has_extents = (t->i_flags & EXT4_EXTENTS_FL);
t->i_file_acl = ext2fs_swab32(f->i_file_acl);
t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
- if (!islnk || has_data_blocks ) {
- for (i = 0; i < EXT2_N_BLOCKS; i++)
- t->i_block[i] = ext2fs_swab32(f->i_block[i]);
- } else if (t != f) {
- for (i = 0; i < EXT2_N_BLOCKS; i++)
- t->i_block[i] = f->i_block[i];
+ if (has_extents) {
+ struct ext3_extent_header *eh;
+ int max = ((EXT2_N_BLOCKS * sizeof(__u32)) - sizeof(*eh));
+
+ if (!islnk || has_data_blocks ) {
+ memcpy(t->i_block, f->i_block, sizeof(f->i_block));
+ eh = (struct ext3_extent_header *)t->i_block;
+ ext2fs_swap_extent_header(eh);
+
+ if (!eh->eh_depth) {
+ struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
+ max = max / sizeof(struct ext3_extent);
+ for (i = 0; i < max; i++, ex++)
+ ext2fs_swap_extent(ex);
+ } else {
+ struct ext3_extent_idx *ix =
+ EXT_FIRST_INDEX(eh);
+ max = max / sizeof(struct ext3_extent_idx);
+ for (i = 0; i < max; i++, ix++)
+ ext2fs_swap_extent_index(ix);
+ }
+ } else if (t != f)
+ memcpy(t->i_block, f->i_block, sizeof(f->i_block));
+ } else {
+ if (!islnk || has_data_blocks ) {
+ for (i = 0; i < EXT2_N_BLOCKS; i++)
+ t->i_block[i] = ext2fs_swab32(f->i_block[i]);
+ } else if (t != f) {
+ for (i = 0; i < EXT2_N_BLOCKS; i++)
+ t->i_block[i] = f->i_block[i];
+ }
}
t->i_generation = ext2fs_swab32(f->i_generation);
t->i_faddr = ext2fs_swab32(f->i_faddr);
-
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