Whamcloud - gitweb
Many files:
authorTheodore Ts'o <tytso@mit.edu>
Thu, 3 May 2001 04:02:29 +0000 (04:02 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 3 May 2001 04:02:29 +0000 (04:02 +0000)
  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.

lib/ext2fs/ChangeLog
lib/ext2fs/block.c
lib/ext2fs/e2image.h
lib/ext2fs/ext2fs.h
lib/ext2fs/imager.c
lib/ext2fs/inode.c
lib/ext2fs/openfs.c
lib/ext2fs/rw_bitmaps.c

index 26bde10..13d7299 100644 (file)
@@ -1,5 +1,21 @@
+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
index 621e850..bd07023 100644 (file)
@@ -64,8 +64,12 @@ static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
                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;
@@ -105,7 +109,8 @@ static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
                        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;
@@ -149,8 +154,12 @@ static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
                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;
@@ -192,7 +201,8 @@ static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
                        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;
@@ -236,8 +246,12 @@ static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
                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;
@@ -279,7 +293,8 @@ static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
                        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;
index 75d7c04..e12b7d6 100644 (file)
@@ -20,7 +20,9 @@ struct ext2_image_hdr {
        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 */
index 74bcb5d..f1a5e22 100644 (file)
@@ -174,6 +174,7 @@ typedef struct ext2_file *ext2_file_t;
 #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
@@ -213,10 +214,11 @@ struct struct_ext2_filsys {
        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.
index 38dc7d8..f59541e 100644 (file)
@@ -286,7 +286,7 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
                                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);
@@ -296,6 +296,7 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
                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) {
@@ -349,7 +350,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
                                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);
@@ -359,6 +360,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
                ptr = fs->block_map->bitmap;
                size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
        }
+       size = size * fs->group_desc_count;
 
        buf = malloc(size);
        if (!buf)
index b09331c..9912a98 100644 (file)
@@ -28,6 +28,7 @@
 #endif
 
 #include "ext2fsP.h"
+#include "e2image.h"
 
 struct ext2_struct_inode_scan {
        errcode_t               magic;
@@ -486,7 +487,7 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
        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);
 
@@ -511,13 +512,22 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
        }
        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);
index 3b9531a..f444524 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 
 #include "ext2fs.h"
+#include "e2image.h"
 
 /*
  *  Note: if superblock is non-zero, block-size must also be non-zero.
@@ -73,6 +74,21 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
        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
index 73979fd..093dddf 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 
 #include "ext2fs.h"
+#include "e2image.h"
 
 #ifdef __powerpc__
 /*
@@ -188,6 +189,28 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
        }
        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;