Whamcloud - gitweb
Add ability for debugfs to use a separate source of data blocks when
authorTheodore Ts'o <tytso@mit.edu>
Thu, 29 Jul 2004 01:11:48 +0000 (21:11 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 29 Jul 2004 01:11:48 +0000 (21:11 -0400)
reading from an e2image file.  (New -d option)

Add new functions ext2fs_get_data_io, ext2fs_set_data_io,
ext2fs_rewrite_to_io to libext2fs library.

12 files changed:
debugfs/ChangeLog
debugfs/debugfs.8.in
debugfs/debugfs.c
lib/ext2fs/ChangeLog
lib/ext2fs/block.c
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext2fs.h
lib/ext2fs/freefs.c
lib/ext2fs/initialize.c
lib/ext2fs/inode.c
lib/ext2fs/openfs.c
lib/ext2fs/rw_bitmaps.c

index 4c96929..34e16c1 100644 (file)
@@ -1,3 +1,9 @@
+2004-07-28  Theodore Ts'o  <tytso@mit.edu>
+
+       * debugfs.c, debugfs.8.in: Add new option -d which allows the
+               system administrator to specify data source of a
+               filesystem being opened via an e2image file.
+
 2004-04-11  Theodore Ts'o  <tytso@mit.edu>
 
        * util.c (open_pager): Use DEBUGFS_PAGER in preference to PAGER
index d39bae9..9bb3354 100644 (file)
@@ -8,6 +8,9 @@ debugfs \- ext2/ext3 file system debugger
 .SH SYNOPSIS
 .B debugfs
 [
+.B \-Vwci
+]
+[
 .B \-b
 blocksize
 ]
@@ -24,22 +27,12 @@ cmd_file
 request
 ]
 [
-.B \-V
-]
-[
-[
-.B \-w
-]
-[
-.B \-c
-]
-[
-.B \-i
+.B \-d
+data_source_device
 ]
 [
 device
 ]
-]
 .SH DESCRIPTION
 The 
 .B debugfs 
@@ -76,10 +69,22 @@ no safety checks are in place, and
 .B debugfs 
 may fail in interesting ways if commands such as
 .IR ls ", " dump ", " 
-etc. are tried.  
+etc. are tried without specifying the 
+.I data_source_device
+using the 
+.I \-d
+option.
 .B debugfs 
 is a debugging tool.  It has rough edges!
 .TP
+.I -d data_source_device
+Used with the 
+.I \-i
+option, specifies that
+.I data_source_device
+should be used when reading blocks not found in the ext2 image file.
+This includes data, directory, and indirect blocks.
+.TP
 .I -b blocksize
 Forces the use of the given block size for the file system, rather than
 detecting the correct block size as normal.
index e16ac84..89b9d6c 100644 (file)
@@ -41,9 +41,11 @@ ext2_filsys  current_fs = NULL;
 ext2_ino_t     root, cwd;
 
 static void open_filesystem(char *device, int open_flags, blk_t superblock,
-                           blk_t blocksize, int catastrophic)
+                           blk_t blocksize, int catastrophic, 
+                           char *data_filename)
 {
        int     retval;
+       io_channel data_io = 0;
 
        if (superblock != 0 && blocksize == 0) {
                com_err(device, 0, "if you specify the superblock, you must also specify the block size");
@@ -51,6 +53,21 @@ static void open_filesystem(char *device, int open_flags, blk_t superblock,
                return;
        }
 
+       if (data_filename) {
+               if ((open_flags & EXT2_FLAG_IMAGE_FILE) == 0) {
+                       com_err(device, 0, 
+                               "The -d option is only valid when reading an e2image file");
+                       current_fs = NULL;
+                       return;
+               }
+               retval = unix_io_manager->open(data_filename, 0, &data_io);
+               if (retval) {
+                       com_err(data_filename, 0, "while opening data source");
+                       current_fs = NULL;
+                       return;
+               }
+       }
+
        if (catastrophic && (open_flags & EXT2_FLAG_RW)) {
                com_err(device, 0,
                        "opening read-only because of catastrophic mode");
@@ -79,6 +96,16 @@ static void open_filesystem(char *device, int open_flags, blk_t superblock,
                        goto errout;
                }
        }
+
+       if (data_io) {
+               retval = ext2fs_set_data_io(current_fs, data_io);
+               if (retval) {
+                       com_err(device, retval, 
+                               "while setting data source");
+                       goto errout;
+               }
+       }
+
        root = cwd = EXT2_ROOT_INO;
        return;
 
@@ -96,10 +123,11 @@ void do_open_filesys(int argc, char **argv)
        int     catastrophic = 0;
        blk_t   superblock = 0;
        blk_t   blocksize = 0;
-       int open_flags = 0;
+       int     open_flags = 0;
+       char    *data_filename;
        
        reset_getopt();
-       while ((c = getopt (argc, argv, "iwfcb:s:")) != EOF) {
+       while ((c = getopt (argc, argv, "iwfcb:s:d:")) != EOF) {
                switch (c) {
                case 'i':
                        open_flags |= EXT2_FLAG_IMAGE_FILE;
@@ -113,6 +141,9 @@ void do_open_filesys(int argc, char **argv)
                case 'c':
                        catastrophic = 1;
                        break;
+               case 'd':
+                       data_filename = optarg;
+                       break;
                case 'b':
                        blocksize = parse_ulong(optarg, argv[0],
                                                "block size", &err);
@@ -137,7 +168,8 @@ void do_open_filesys(int argc, char **argv)
        if (check_fs_not_open(argv[0]))
                return;
        open_filesystem(argv[optind], open_flags,
-                       superblock, blocksize, catastrophic);
+                       superblock, blocksize, catastrophic, 
+                       data_filename);
 }
 
 void do_lcd(int argc, char **argv)
@@ -1631,12 +1663,13 @@ int main(int argc, char **argv)
        blk_t           superblock = 0;
        blk_t           blocksize = 0;
        int             catastrophic = 0;
+       char            *data_filename = 0;
        
        initialize_ext2_error_table();
        fprintf (stderr, "debugfs %s (%s)\n", E2FSPROGS_VERSION,
                 E2FSPROGS_DATE);
 
-       while ((c = getopt (argc, argv, "iwcR:f:b:s:V")) != EOF) {
+       while ((c = getopt (argc, argv, "iwcR:f:b:s:Vd:")) != EOF) {
                switch (c) {
                case 'R':
                        request = optarg;
@@ -1644,6 +1677,9 @@ int main(int argc, char **argv)
                case 'f':
                        cmd_file = optarg;
                        break;
+               case 'd':
+                       data_filename = optarg;
+                       break;
                case 'i':
                        open_flags |= EXT2_FLAG_IMAGE_FILE;
                        break;
@@ -1673,7 +1709,8 @@ int main(int argc, char **argv)
        }
        if (optind < argc)
                open_filesystem(argv[optind], open_flags,
-                               superblock, blocksize, catastrophic);
+                               superblock, blocksize, catastrophic,
+                               data_filename);
        
        sci_idx = ss_create_invocation("debugfs", "0.0", (char *) NULL,
                                       &debug_cmds, &retval);
index 751aa9d..9bbf393 100644 (file)
@@ -1,3 +1,26 @@
+2004-07-28  Theodore Ts'o  <tytso@mit.edu>
+
+       * rw_bitmaps.c (read_bitmaps), block.c (block_iterate_ind,
+               block_iterate_dind, block_iterate_tind), inode.c
+               (ext2fs_read_inode): If EXT2_FLAG_IMAGE_FILE is set, so
+               read the metadata from fs->image_io instead of fs->io.
+
+       * initialize.c (ext2fs_initialize), openfs.c (ext2fs_open):
+               Initialize fs->image_io to be the same as fs->io.
+       
+       * ext2_err.et.in (EXT2_ET_NOT_IMAGE_FILE): Add new error code. 
+
+       * openfs.c (ext2fs_get_data_io, ext2fs_set_data_io,
+               ext2fs_rewrite_to_io): New functions that allow
+               applications to manipulate fs->image_io and fs->io safely.
+
+       * freefs.c (ext2fs_free): If fs->image_io is different fs->io,
+               then call io_channel_close on fs->image_io.
+
+       * ext2fs.h: Add image_io element to the ext2_filsys data
+               structure.  Add ext2fs_get_data_io() ext2fs_set_data_io(),
+               and ext2fs_rewrite_to_io() prototypes.
+
 2004-05-26  Theodore Ts'o  <tytso@mit.edu>
 
        * closefs.c (ext2fs_flush): Make sure the master superblock is
index f64c0af..88ce286 100644 (file)
@@ -59,7 +59,8 @@ 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) {
+       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
@@ -153,7 +154,8 @@ 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) {
+       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
@@ -249,7 +251,8 @@ 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) {
+       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
index b9ad5f0..b3ada29 100644 (file)
@@ -284,5 +284,8 @@ ec  EXT2_ET_BAD_EA_BLOCK_NUM,
 ec     EXT2_ET_TOO_MANY_INODES,
        "Cannot create filesystem with requested number of inodes"
 
+ec     EXT2_ET_NOT_IMAGE_FILE,
+       "E2image snapshot not in use"
+
        end
 
index 2536c92..19be9c5 100644 (file)
@@ -242,6 +242,7 @@ struct struct_ext2_filsys {
         * Inode cache
         */
        struct ext2_inode_cache         *icache;
+       io_channel                      image_io;
 };
 
 #if EXT2_FLAT_INCLUDES
@@ -852,6 +853,9 @@ extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
                             ext2_filsys *ret_fs);
 extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, 
                                         dgrp_t i);
+errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
+errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
+errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
 
 /* get_pathname.c */
 extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
index 78c64bf..9dda403 100644 (file)
@@ -23,6 +23,9 @@ void ext2fs_free(ext2_filsys fs)
 {
        if (!fs || (fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS))
                return;
+       if (fs->image_io != fs->io) {
+               io_channel_close(fs->image_io);
+       }
        if (fs->io) {
                io_channel_close(fs->io);
        }
index 74f20a7..2ee06b5 100644 (file)
@@ -91,6 +91,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        retval = manager->open(name, IO_FLAG_RW, &fs->io);
        if (retval)
                goto cleanup;
+       fs->image_io = fs->io;
        fs->io->app_data = fs;
        retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
        if (retval)
index 50420b7..a1179d2 100644 (file)
@@ -485,6 +485,7 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
        errcode_t       retval;
        int             clen, i, inodes_per_block;
        unsigned int    length;
+       io_channel      io;
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -515,6 +516,7 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
                block_nr += (ino - 1) / inodes_per_block;
                offset = ((ino - 1) % inodes_per_block) *
                        EXT2_INODE_SIZE(fs->super);
+               io = fs->image_io;
        } else {
                group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
                offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
@@ -524,9 +526,10 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
                        return EXT2_ET_MISSING_INODE_TABLE;
                block_nr = fs->group_desc[(unsigned)group].bg_inode_table + 
                        block;
+               io = fs->io;
        }
        if (block_nr != fs->icache->buffer_blk) {
-               retval = io_channel_read_blk(fs->io, block_nr, 1,
+               retval = io_channel_read_blk(io, block_nr, 1,
                                             fs->icache->buffer);
                if (retval)
                        return retval;
@@ -545,7 +548,7 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
                memcpy((char *) inode, ptr, clen);
                length -= clen;
                
-               retval = io_channel_read_blk(fs->io, block_nr+1, 1,
+               retval = io_channel_read_blk(io, block_nr+1, 1,
                                             fs->icache->buffer);
                if (retval) {
                        fs->icache->buffer_blk = 0;
index bc7c5bb..dac8a38 100644 (file)
@@ -96,6 +96,7 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
                               &fs->io);
        if (retval)
                goto cleanup;
+       fs->image_io = fs->io;
        fs->io->app_data = fs;
        retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
        if (retval)
@@ -271,3 +272,36 @@ cleanup:
        return retval;
 }
 
+/*
+ * Set/get the filesystem data I/O channel.
+ * 
+ * These functions are only valid if EXT2_FLAG_IMAGE_FILE is true.
+ */
+errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io)
+{
+       if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
+               return EXT2_ET_NOT_IMAGE_FILE;
+       if (old_io) {
+               *old_io = (fs->image_io == fs->io) ? 0 : fs->io;
+       }
+       return 0;
+}
+
+errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io)
+{
+       if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
+               return EXT2_ET_NOT_IMAGE_FILE;
+       fs->io = new_io ? new_io : fs->image_io;
+       return 0;
+}
+
+errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io)
+{
+       if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
+               return EXT2_ET_NOT_IMAGE_FILE;
+       fs->io = fs->image_io = new_io;
+       fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_RW | 
+               EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
+       fs->flags &= ~EXT2_FLAG_IMAGE_FILE;
+       return 0;
+}
index ff3dd59..b67a925 100644 (file)
@@ -186,7 +186,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
                if (inode_bitmap) {
                        blk = (fs->image_header->offset_inodemap /
                               fs->blocksize);
-                       retval = io_channel_read_blk(fs->io, blk,
+                       retval = io_channel_read_blk(fs->image_io, blk,
                             -(inode_nbytes * fs->group_desc_count),
                             inode_bitmap);
                        if (retval)
@@ -195,7 +195,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
                if (block_bitmap) {
                        blk = (fs->image_header->offset_blockmap /
                               fs->blocksize);
-                       retval = io_channel_read_blk(fs->io, blk, 
+                       retval = io_channel_read_blk(fs->image_io, blk, 
                             -(block_nbytes * fs->group_desc_count),
                             block_bitmap);
                        if (retval)