Whamcloud - gitweb
Fix resize inode handling on big endian systems, by adding new routines
authorTheodore Ts'o <tytso@mit.edu>
Thu, 6 Jan 2005 05:04:24 +0000 (00:04 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 6 Jan 2005 05:04:24 +0000 (00:04 -0500)
that read/write indirect blocks, byte swapping them if necessary.

e2fsck/ChangeLog
e2fsck/super.c
lib/ext2fs/ChangeLog
lib/ext2fs/Makefile.in
lib/ext2fs/block.c
lib/ext2fs/ext2fs.h
lib/ext2fs/ind_block.c [new file with mode: 0644]
lib/ext2fs/res_gdt.c

index b843459..25a6780 100644 (file)
@@ -1,3 +1,8 @@
+2005-01-06  Theodore Ts'o  <tytso@mit.edu>
+
+       * super.c (check_resize_inode): Use ext2fs_{read,write}_ind_block
+               so that byte swapping is handled on big-endian systems.
+
 2004-12-24  Theodore Ts'o  <tytso@mit.edu>
 
        * pass1.c (e2fsck_pass1): At the end of the pass 1 processing, if
index 71968ea..ef799f9 100644 (file)
@@ -392,7 +392,7 @@ void check_resize_inode(e2fsck_t ctx)
                                                    "resize dind buffer");
        ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
 
-       retval = io_channel_read_blk(fs->io, blk, 1, dind_buf);
+       retval = ext2fs_read_ind_block(fs, blk, dind_buf);
        if (retval)
                goto resize_inode_invalid;
 
@@ -403,7 +403,7 @@ void check_resize_inode(e2fsck_t ctx)
                gdt_off %= fs->blocksize/4;
                if (dind_buf[gdt_off] != pblk)
                        goto resize_inode_invalid;
-               retval = io_channel_read_blk(fs->io, pblk, 1, ind_buf);
+               retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
                if (retval) 
                        goto resize_inode_invalid;
                ind_off = 0;
index 048bb4f..1eb5ed5 100644 (file)
@@ -1,5 +1,18 @@
 2005-01-05  Theodore Ts'o  <tytso@mit.edu>
 
+       * block.c (block_iterate_ind, block_iterate_dind,
+               block_iterate_tind): Move the code which byte swaps and
+               read/writes indirect blocks to ext2fs_{read,write}_ind_block.
+               This saves 400 bytes, and we need them for the
+               resize_inode handling. 
+
+       * ind_block.c (ext2fs_read_ind_block, ext2fs_write_ind_block): New
+               functions.
+
+       * res_gdt.c (ext2fs_create_resize_inode): Use 
+               ext2fs_{read,write}_ind_block so that byte swapping is
+               handled on big-endian systems.
+
        * dupfs.c (ext2fs_dup_handle): Make sure the new filesystem handle
                has its own copy of the orig_super data structure.  (This
                is a better way of fixing a double-free problem in
index 5929c70..931e9b0 100644 (file)
@@ -43,6 +43,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
        getsize.o \
        getsectsize.o \
        icount.o \
+       ind_block.o \
        initialize.o \
        inline.o \
        inode.o \
@@ -98,6 +99,7 @@ SRCS= ext2_err.c \
        $(srcdir)/getsize.c \
        $(srcdir)/getsectsize.c \
        $(srcdir)/icount.c \
+       $(srcdir)/ind_block.c \
        $(srcdir)/initialize.c \
        $(srcdir)/inline.c \
        $(srcdir)/inode.c \
index 88ce286..7685680 100644 (file)
@@ -59,25 +59,13 @@ static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
                ret |= BLOCK_ERROR;
                return ret;
        }
-       if ((ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-           (ctx->fs->io != ctx->fs->image_io)) {
-               ctx->errcode = 0;
-               memset(ctx->ind_buf, 0, ctx->fs->blocksize);
-       } else
-               ctx->errcode = io_channel_read_blk(ctx->fs->io, *ind_block,
-                                                  1, ctx->ind_buf);
+       ctx->errcode = ext2fs_read_ind_block(ctx->fs, *ind_block, 
+                                            ctx->ind_buf);
        if (ctx->errcode) {
                ret |= BLOCK_ERROR;
                return ret;
        }
-#ifdef EXT2FS_ENABLE_SWAPFS
-       if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
-                             EXT2_FLAG_SWAP_BYTES_READ)) {
-               block_nr = (blk_t *) ctx->ind_buf;
-               for (i = 0; i < limit; i++, block_nr++)
-                       *block_nr = ext2fs_swab32(*block_nr);
-       }
-#endif
+
        block_nr = (blk_t *) ctx->ind_buf;
        offset = 0;
        if (ctx->flags & BLOCK_FLAG_APPEND) {
@@ -107,18 +95,9 @@ static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
                        offset += sizeof(blk_t);
                }
        }
-       if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-           (changed & BLOCK_CHANGED)) {
-#ifdef EXT2FS_ENABLE_SWAPFS
-               if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
-                                     EXT2_FLAG_SWAP_BYTES_WRITE)) {
-                       block_nr = (blk_t *) ctx->ind_buf;
-                       for (i = 0; i < limit; i++, block_nr++)
-                               *block_nr = ext2fs_swab32(*block_nr);
-               }
-#endif
-               ctx->errcode = io_channel_write_blk(ctx->fs->io, *ind_block,
-                                                   1, ctx->ind_buf);
+       if (changed & BLOCK_CHANGED) {
+               ctx->errcode = ext2fs_write_ind_block(ctx->fs, *ind_block,
+                                                     ctx->ind_buf);
                if (ctx->errcode)
                        ret |= BLOCK_ERROR | BLOCK_ABORT;
        }
@@ -154,25 +133,13 @@ static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
                ret |= BLOCK_ERROR;
                return ret;
        }
-       if ((ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-           (ctx->fs->io != ctx->fs->image_io)) {
-               ctx->errcode = 0;
-               memset(ctx->dind_buf, 0, ctx->fs->blocksize);
-       } else
-               ctx->errcode = io_channel_read_blk(ctx->fs->io, *dind_block,
-                                                  1, ctx->dind_buf);
+       ctx->errcode = ext2fs_read_ind_block(ctx->fs, *dind_block, 
+                                            ctx->dind_buf);
        if (ctx->errcode) {
                ret |= BLOCK_ERROR;
                return ret;
        }
-#ifdef EXT2FS_ENABLE_SWAPFS
-       if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
-                             EXT2_FLAG_SWAP_BYTES_READ)) {
-               block_nr = (blk_t *) ctx->dind_buf;
-               for (i = 0; i < limit; i++, block_nr++)
-                       *block_nr = ext2fs_swab32(*block_nr);
-       }
-#endif
+
        block_nr = (blk_t *) ctx->dind_buf;
        offset = 0;
        if (ctx->flags & BLOCK_FLAG_APPEND) {
@@ -204,18 +171,9 @@ static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
                        offset += sizeof(blk_t);
                }
        }
-       if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-           (changed & BLOCK_CHANGED)) {
-#ifdef EXT2FS_ENABLE_SWAPFS
-               if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
-                                     EXT2_FLAG_SWAP_BYTES_WRITE)) {
-                       block_nr = (blk_t *) ctx->dind_buf;
-                       for (i = 0; i < limit; i++, block_nr++)
-                               *block_nr = ext2fs_swab32(*block_nr);
-               }
-#endif
-               ctx->errcode = io_channel_write_blk(ctx->fs->io, *dind_block,
-                                                   1, ctx->dind_buf);
+       if (changed & BLOCK_CHANGED) {
+               ctx->errcode = ext2fs_write_ind_block(ctx->fs, *dind_block,
+                                                     ctx->dind_buf);
                if (ctx->errcode)
                        ret |= BLOCK_ERROR | BLOCK_ABORT;
        }
@@ -251,25 +209,13 @@ static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
                ret |= BLOCK_ERROR;
                return ret;
        }
-       if ((ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-           (ctx->fs->io != ctx->fs->image_io)) {
-               ctx->errcode = 0;
-               memset(ctx->tind_buf, 0, ctx->fs->blocksize);
-       } else
-               ctx->errcode = io_channel_read_blk(ctx->fs->io, *tind_block,
-                                                  1, ctx->tind_buf);
+       ctx->errcode = ext2fs_read_ind_block(ctx->fs, *tind_block, 
+                                            ctx->tind_buf);
        if (ctx->errcode) {
                ret |= BLOCK_ERROR;
                return ret;
        }
-#ifdef EXT2FS_ENABLE_SWAPFS
-       if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
-                             EXT2_FLAG_SWAP_BYTES_READ)) {
-               block_nr = (blk_t *) ctx->tind_buf;
-               for (i = 0; i < limit; i++, block_nr++)
-                       *block_nr = ext2fs_swab32(*block_nr);
-       }
-#endif
+
        block_nr = (blk_t *) ctx->tind_buf;
        offset = 0;
        if (ctx->flags & BLOCK_FLAG_APPEND) {
@@ -301,18 +247,9 @@ static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
                        offset += sizeof(blk_t);
                }
        }
-       if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-           (changed & BLOCK_CHANGED)) {
-#ifdef EXT2FS_ENABLE_SWAPFS
-               if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
-                                     EXT2_FLAG_SWAP_BYTES_WRITE)) {
-                       block_nr = (blk_t *) ctx->tind_buf;
-                       for (i = 0; i < limit; i++, block_nr++)
-                               *block_nr = ext2fs_swab32(*block_nr);
-               }
-#endif
-               ctx->errcode = io_channel_write_blk(ctx->fs->io, *tind_block,
-                                                   1, ctx->tind_buf);
+       if (changed & BLOCK_CHANGED) {
+               ctx->errcode = ext2fs_write_ind_block(ctx->fs, *tind_block,
+                                                     ctx->tind_buf);
                if (ctx->errcode)
                        ret |= BLOCK_ERROR | BLOCK_ABORT;
        }
index 55bc547..1b7e1b0 100644 (file)
@@ -757,6 +757,10 @@ extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
 extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
 extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
 
+/* ind_block.c */
+errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
+errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
+
 /* initialize.c */
 extern errcode_t ext2fs_initialize(const char *name, int flags,
                                   struct ext2_super_block *param,
diff --git a/lib/ext2fs/ind_block.c b/lib/ext2fs/ind_block.c
new file mode 100644 (file)
index 0000000..9f77a07
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * ind_block.c --- indirect block I/O routines
+ * 
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 
+ *     2001, 2002, 2003, 2004, 2005 by  Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf)
+{
+       errcode_t       retval;
+       blk_t           *block_nr;
+       int             i;
+       int             limit = fs->blocksize >> 2;
+
+       if ((fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+           (fs->io != fs->image_io))
+               memset(buf, 0, fs->blocksize);
+       else {
+               retval = io_channel_read_blk(fs->io, blk, 1, buf);
+               if (retval)
+                       retval;
+       }
+#ifdef EXT2FS_ENABLE_SWAPFS
+       if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_READ)) {
+               block_nr = (blk_t *) buf;
+               for (i = 0; i < limit; i++, block_nr++)
+                       *block_nr = ext2fs_swab32(*block_nr);
+       }
+#endif
+       return 0;
+}
+
+errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf)
+{
+       blk_t           *block_nr;
+       int             i;
+       int             limit = fs->blocksize >> 2;
+
+       if (fs->flags & EXT2_FLAG_IMAGE_FILE)
+               return 0;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+       if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_WRITE)) {
+               block_nr = (blk_t *) buf;
+               for (i = 0; i < limit; i++, block_nr++)
+                       *block_nr = ext2fs_swab32(*block_nr);
+       }
+#endif
+       return io_channel_write_blk(fs->io, blk, 1, buf);
+}
+
+
index 4706589..1fdb1d4 100644 (file)
@@ -91,7 +91,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 #ifdef RES_GDT_DEBUG
                printf("reading GDT dindir %u\n", dindir_blk);
 #endif
-               retval = io_channel_read_blk(fs->io, dindir_blk, 1, dindir_buf);
+               retval = ext2fs_read_ind_block(fs, dindir_blk, dindir_buf);
                if (retval)
                        goto out_inode;
        } else {
@@ -154,7 +154,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 #ifdef RES_GDT_DEBUG
                        printf("reading primary GDT block %u\n", gdt_blk);
 #endif
-                       retval = io_channel_read_blk(fs->io,gdt_blk,1,gdt_buf);
+                       retval = ext2fs_read_ind_block(fs, gdt_blk, gdt_buf);
                        if (retval)
                                goto out_dindir;
                } else {
@@ -192,7 +192,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 #ifdef RES_GDT_DEBUG
                        printf("writing primary GDT block %u\n", gdt_blk);
 #endif
-                       retval = io_channel_write_blk(fs->io,gdt_blk,1,gdt_buf);
+                       retval = ext2fs_write_ind_block(fs, gdt_blk, gdt_buf);
                        if (retval)
                                goto out_dindir;
                }
@@ -200,7 +200,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 
 out_dindir:
        if (dindir_dirty) {
-               retval2 = io_channel_write_blk(fs->io, dindir_blk,1,dindir_buf);
+               retval2 = ext2fs_write_ind_block(fs, dindir_blk, dindir_buf);
                if (!retval)
                        retval = retval2;
        }