+2001-05-02 Theodore Tso <tytso@valinux.com>
+
+ * ext2fs.h (EXT2_FLAG_IMAGE_FILE): Add new flag, and add
+ image_header field in the ext2_filsys structure
+
+ * block.c (block_iterate_ind, block_iterate_dind, block_iterate_tind):
+ * inode.c (ext2fs_read_inode):
+ * rw_bitmaps.c (read_bitmaps):
+ * openfs.c (ext2fs_open): Add support for EXT2_FLAG_IMAGE_FILE
+
+ * imager.c (ext2fs_image_bitmap_read): Fix bug in imager to make
+ sure the full bitmap is saved.
+
2001-05-01 Theodore Tso <tytso@valinux.com>
+ * e2image.h (struct ext2_image_hdr): Add space for the device name
+ in the image header.
+
* dir_iterate.c (ext2fs_process_dir_block): Add a double-check to
make sure the rec_len is a multiple of 4, to prevent
bus-errors on architectures which care about mis-aligned
ret |= BLOCK_ERROR;
return ret;
}
- ctx->errcode = io_channel_read_blk(ctx->fs->io, *ind_block,
- 1, ctx->ind_buf);
+ if (ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ 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);
if (ctx->errcode) {
ret |= BLOCK_ERROR;
return ret;
offset += sizeof(blk_t);
}
}
- if (changed & BLOCK_CHANGED) {
+ if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+ (changed & BLOCK_CHANGED)) {
if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
EXT2_FLAG_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->ind_buf;
ret |= BLOCK_ERROR;
return ret;
}
- ctx->errcode = io_channel_read_blk(ctx->fs->io, *dind_block,
- 1, ctx->dind_buf);
+ if (ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ 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);
if (ctx->errcode) {
ret |= BLOCK_ERROR;
return ret;
offset += sizeof(blk_t);
}
}
- if (changed & BLOCK_CHANGED) {
+ if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+ (changed & BLOCK_CHANGED)) {
if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
EXT2_FLAG_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->dind_buf;
ret |= BLOCK_ERROR;
return ret;
}
- ctx->errcode = io_channel_read_blk(ctx->fs->io, *tind_block,
- 1, ctx->tind_buf);
+ if (ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ 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);
if (ctx->errcode) {
ret |= BLOCK_ERROR;
return ret;
offset += sizeof(blk_t);
}
}
- if (changed & BLOCK_CHANGED) {
+ if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+ (changed & BLOCK_CHANGED)) {
if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
EXT2_FLAG_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->tind_buf;
char fs_netaddr[32]; /* Network address */
__u32 fs_netaddr_type;/* 0 = IPV4, 1 = IPV6, etc. */
__u32 fs_device; /* Device number of image */
+ char fs_device_name[64]; /* Device name */
char fs_uuid[16]; /* UUID of filesystem */
+ __u32 fs_blocksize; /* Block size of the filesystem */
__u32 fs_reserved[8];
__u32 image_device; /* Device number of image file */
#define EXT2_FLAG_FORCE 0x400
#define EXT2_FLAG_SUPER_ONLY 0x800
#define EXT2_FLAG_JOURNAL_DEV_OK 0x1000
+#define EXT2_FLAG_IMAGE_FILE 0x2000
/*
* Special flag in the ext2 inode i_flag field that means that this is
ext2_dblist dblist;
__u32 stride; /* for mke2fs */
struct ext2_super_block * orig_super;
+ struct ext2_image_hdr * image_header;
/*
* Reserved for future expansion
*/
- __u32 reserved[10];
+ __u32 reserved[9];
/*
* Reserved for the use of the calling application.
return retval;
}
ptr = fs->inode_map->bitmap;
- size = ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
+ size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
} else {
if (!fs->block_map) {
retval = ext2fs_read_block_bitmap(fs);
ptr = fs->block_map->bitmap;
size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
}
+ size = size * fs->group_desc_count;
actual = write(fd, ptr, size);
if (actual == -1) {
return retval;
}
ptr = fs->inode_map->bitmap;
- size = ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
+ size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
} else {
if (!fs->block_map) {
retval = ext2fs_read_block_bitmap(fs);
ptr = fs->block_map->bitmap;
size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
}
+ size = size * fs->group_desc_count;
buf = malloc(size);
if (!buf)
#endif
#include "ext2fsP.h"
+#include "e2image.h"
struct ext2_struct_inode_scan {
errcode_t magic;
unsigned long group, block, block_nr, offset;
char *ptr;
errcode_t retval;
- int clen, length, i;
+ int clen, length, i, inodes_per_block;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
}
if ((ino == 0) || (ino > fs->super->s_inodes_count))
return EXT2_ET_BAD_INODE_NUM;
- group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
- offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
- EXT2_INODE_SIZE(fs->super);
- block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
- if (!fs->group_desc[(unsigned)group].bg_inode_table)
- return EXT2_ET_MISSING_INODE_TABLE;
- block_nr = fs->group_desc[(unsigned)group].bg_inode_table + block;
+ if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
+ block_nr = fs->image_header->offset_inode / fs->blocksize;
+ block_nr += (ino - 1) / inodes_per_block;
+ offset = ((ino - 1) % inodes_per_block) *
+ EXT2_INODE_SIZE(fs->super);
+ } else {
+ group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
+ offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+ EXT2_INODE_SIZE(fs->super);
+ block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+ if (!fs->group_desc[(unsigned)group].bg_inode_table)
+ return EXT2_ET_MISSING_INODE_TABLE;
+ block_nr = fs->group_desc[(unsigned)group].bg_inode_table +
+ block;
+ }
if (block_nr != fs->icache->buffer_blk) {
retval = io_channel_read_blk(fs->io, block_nr, 1,
fs->icache->buffer);
#endif
#include "ext2fs.h"
+#include "e2image.h"
/*
* Note: if superblock is non-zero, block-size must also be non-zero.
retval = ext2fs_get_mem(SUPERBLOCK_SIZE, (void **) &fs->super);
if (retval)
goto cleanup;
+ if (flags & EXT2_FLAG_IMAGE_FILE) {
+ retval = ext2fs_get_mem(sizeof(struct ext2_image_hdr),
+ (void **) &fs->image_header);
+ if (retval)
+ goto cleanup;
+ retval = io_channel_read_blk(fs->io, 0,
+ -sizeof(struct ext2_image_hdr),
+ fs->image_header);
+ if (retval)
+ goto cleanup;
+ if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE)
+ return EXT2_ET_MAGIC_E2IMAGE;
+ superblock = 1;
+ block_size = fs->image_header->fs_blocksize;
+ }
/*
* If the user specifies a specific block # for the
#endif
#include "ext2fs.h"
+#include "e2image.h"
#ifdef __powerpc__
/*
}
ext2fs_free_mem((void **) &buf);
+ if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ if (inode_bitmap) {
+ blk = (fs->image_header->offset_inodemap /
+ fs->blocksize);
+ retval = io_channel_read_blk(fs->io, blk,
+ -(inode_nbytes * fs->group_desc_count),
+ inode_bitmap);
+ if (retval)
+ goto cleanup;
+ }
+ if (block_bitmap) {
+ blk = (fs->image_header->offset_blockmap /
+ fs->blocksize);
+ retval = io_channel_read_blk(fs->io, blk,
+ -(block_nbytes * fs->group_desc_count),
+ block_bitmap);
+ if (retval)
+ goto cleanup;
+ }
+ return 0;
+ }
+
for (i = 0; i < fs->group_desc_count; i++) {
if (block_bitmap) {
blk = fs->group_desc[i].bg_block_bitmap;