that read/write indirect blocks, byte swapping them if necessary.
+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
"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;
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;
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
getsize.o \
getsectsize.o \
icount.o \
+ ind_block.o \
initialize.o \
inline.o \
inode.o \
$(srcdir)/getsize.c \
$(srcdir)/getsectsize.c \
$(srcdir)/icount.c \
+ $(srcdir)/ind_block.c \
$(srcdir)/initialize.c \
$(srcdir)/inline.c \
$(srcdir)/inode.c \
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) {
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;
}
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) {
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;
}
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) {
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;
}
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,
--- /dev/null
+/*
+ * 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);
+}
+
+
#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 {
#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 {
#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;
}
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;
}