linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add in-inode extents swabbing.
@ 2007-06-29  6:41 Girish Shilamkar
  0 siblings, 0 replies; only message in thread
From: Girish Shilamkar @ 2007-06-29  6:41 UTC (permalink / raw)
  To: Ext4 Mailing List; +Cc: Andreas Dilger, Theodore Tso

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@clusterfs.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);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-06-29  6:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-29  6:41 [PATCH] Add in-inode extents swabbing Girish Shilamkar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).