diff options
author | Theodore Ts'o <tytso@mit.edu> | 2005-01-06 00:04:24 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2005-01-06 00:04:24 -0500 |
commit | dc8ce3463791366ac844d3f0436709511fa09c49 (patch) | |
tree | adc61eb21232f5a6648a463508f365c417e2a175 /lib/ext2fs | |
parent | 2e6a9febb48ea0e57d32cacb5e67220443c0e059 (diff) | |
download | e2fsprogs-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/ChangeLog | 13 | ||||
-rw-r--r-- | lib/ext2fs/Makefile.in | 2 | ||||
-rw-r--r-- | lib/ext2fs/block.c | 99 | ||||
-rw-r--r-- | lib/ext2fs/ext2fs.h | 4 | ||||
-rw-r--r-- | lib/ext2fs/ind_block.c | 66 | ||||
-rw-r--r-- | lib/ext2fs/res_gdt.c | 8 |
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; } |