Whamcloud - gitweb
libext2fs: find/alloc a range of empty blocks
[tools/e2fsprogs.git] / lib / ext2fs / swapfs.c
index c308095..ee7a455 100644 (file)
@@ -99,6 +99,8 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
        }
        for (; i < 17; i++)
                sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
+       sb->s_backup_bgs[0] = ext2fs_swab32(sb->s_backup_bgs[0]);
+       sb->s_backup_bgs[1] = ext2fs_swab32(sb->s_backup_bgs[1]);
 }
 
 void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
@@ -194,7 +196,9 @@ void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
                to_entry   = (struct ext2_ext_attr_entry *)to_header;
        }
 
-       while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
+       while ((char *)from_entry < from_end &&
+              (char *)EXT2_EXT_ATTR_NEXT(from_entry) <= from_end &&
+              *(__u32 *)from_entry) {
                ext2fs_swap_ext_attr_entry(to_entry, from_entry);
                from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
                to_entry   = EXT2_EXT_ATTR_NEXT(to_entry);
@@ -207,6 +211,7 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
 {
        unsigned i, has_data_blocks, extra_isize, attr_magic;
        int has_extents = 0;
+       int has_inline_data = 0;
        int islnk = 0;
        __u32 *eaf, *eat;
 
@@ -233,12 +238,18 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
                                           (struct ext2_inode *) t);
        if (hostorder && (f->i_flags & EXT4_EXTENTS_FL))
                has_extents = 1;
+       if (hostorder && (f->i_flags & EXT4_INLINE_DATA_FL))
+               has_inline_data = 1;
        t->i_flags = ext2fs_swab32(f->i_flags);
        if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
                has_extents = 1;
+       if (!hostorder && (t->i_flags & EXT4_INLINE_DATA_FL))
+               has_inline_data = 1;
        t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
-       /* extent data are swapped on access, not here */
-       if (!has_extents && (!islnk || has_data_blocks)) {
+       /*
+        * Extent data and inline data are swapped on access, not here
+        */
+       if (!has_extents && !has_inline_data && (!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) {
@@ -354,13 +365,19 @@ void ext2fs_swap_mmp(struct mmp_struct *mmp)
 
 errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags)
 {
+       return ext2fs_dirent_swab_in2(fs, buf, fs->blocksize, flags);
+}
+
+errcode_t ext2fs_dirent_swab_in2(ext2_filsys fs, char *buf,
+                                size_t size, int flags)
+{
        errcode_t       retval;
        char            *p, *end;
        struct ext2_dir_entry *dirent;
        unsigned int    name_len, rec_len;
 
        p = (char *) buf;
-       end = (char *) buf + fs->blocksize;
+       end = (char *) buf + size;
        while (p < end-8) {
                dirent = (struct ext2_dir_entry *) p;
                dirent->inode = ext2fs_swab32(dirent->inode);
@@ -385,13 +402,19 @@ errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags)
 
 errcode_t ext2fs_dirent_swab_out(ext2_filsys fs, char *buf, int flags)
 {
+       return ext2fs_dirent_swab_out2(fs, buf, fs->blocksize, flags);
+}
+
+errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf,
+                                 size_t size, int flags)
+{
        errcode_t       retval;
        char            *p, *end;
        unsigned int    rec_len;
        struct ext2_dir_entry *dirent;
 
        p = buf;
-       end = buf + fs->blocksize;
+       end = buf + size;
        while (p < end) {
                dirent = (struct ext2_dir_entry *) p;
                retval = ext2fs_get_rec_len(fs, dirent, &rec_len);