summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debugfs/ChangeLog6
-rw-r--r--debugfs/debugfs.8.in31
-rw-r--r--debugfs/debugfs.c49
-rw-r--r--lib/ext2fs/ChangeLog23
-rw-r--r--lib/ext2fs/block.c9
-rw-r--r--lib/ext2fs/ext2_err.et.in3
-rw-r--r--lib/ext2fs/ext2fs.h4
-rw-r--r--lib/ext2fs/freefs.c3
-rw-r--r--lib/ext2fs/initialize.c1
-rw-r--r--lib/ext2fs/inode.c7
-rw-r--r--lib/ext2fs/openfs.c34
-rw-r--r--lib/ext2fs/rw_bitmaps.c4
12 files changed, 148 insertions, 26 deletions
diff --git a/debugfs/ChangeLog b/debugfs/ChangeLog
index 4c969296..34e16c18 100644
--- a/debugfs/ChangeLog
+++ b/debugfs/ChangeLog
@@ -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
diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in
index d39bae9c..9bb33540 100644
--- a/debugfs/debugfs.8.in
+++ b/debugfs/debugfs.8.in
@@ -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.
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index e16ac84d..89b9d6c4 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -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);
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index 751aa9d4..9bbf393b 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -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
diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index f64c0af3..88ce2867 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -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
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index b9ad5f0f..b3ada297 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -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
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 2536c920..19be9c5f 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -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,
diff --git a/lib/ext2fs/freefs.c b/lib/ext2fs/freefs.c
index 78c64bf5..9dda403b 100644
--- a/lib/ext2fs/freefs.c
+++ b/lib/ext2fs/freefs.c
@@ -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);
}
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 74f20a70..2ee06b5c 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -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)
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 50420b76..a1179d27 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -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;
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index bc7c5bb3..dac8a38c 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -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;
+}
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
index ff3dd591..b67a9259 100644
--- a/lib/ext2fs/rw_bitmaps.c
+++ b/lib/ext2fs/rw_bitmaps.c
@@ -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)