summaryrefslogtreecommitdiff
path: root/lib/ext2fs
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2005-01-06 00:04:24 -0500
committerTheodore Ts'o <tytso@mit.edu>2005-01-06 00:04:24 -0500
commitdc8ce3463791366ac844d3f0436709511fa09c49 (patch)
treeadc61eb21232f5a6648a463508f365c417e2a175 /lib/ext2fs
parent2e6a9febb48ea0e57d32cacb5e67220443c0e059 (diff)
downloade2fsprogs-dc8ce3463791366ac844d3f0436709511fa09c49.tar.gz
Fix resize inode handling on big endian systems, by adding new routines
that read/write indirect blocks, byte swapping them if necessary.
Diffstat (limited to 'lib/ext2fs')
-rw-r--r--lib/ext2fs/ChangeLog13
-rw-r--r--lib/ext2fs/Makefile.in2
-rw-r--r--lib/ext2fs/block.c99
-rw-r--r--lib/ext2fs/ext2fs.h4
-rw-r--r--lib/ext2fs/ind_block.c66
-rw-r--r--lib/ext2fs/res_gdt.c8
6 files changed, 107 insertions, 85 deletions
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index 048bb4ff..1eb5ed57 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -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
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 5929c704..931e9b07 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -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 \
diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index 88ce2867..7685680d 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -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;
}
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 55bc5473..1b7e1b0c 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -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
index 00000000..9f77a079
--- /dev/null
+++ b/lib/ext2fs/ind_block.c
@@ -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);
+}
+
+
diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c
index 4706589d..1fdb1d45 100644
--- a/lib/ext2fs/res_gdt.c
+++ b/lib/ext2fs/res_gdt.c
@@ -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;
}