[Ocfs2-tools-devel] [PATCH 6/6] debugfs.ocfs2: Print dirblocks as a whole.
Joel Becker
Joel.Becker at oracle.com
Fri Jan 9 16:18:20 PST 2009
Let's print whole dirblocks, not just trailers. The 'dir_trailers'
command becomes 'dirblocks'. As a bonus, 'logdump' can now dump
dirblocks it detects via the trailer.
Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
debugfs.ocfs2/commands.c | 71 ++++++++++++++++++++++++++----------------
debugfs.ocfs2/dump.c | 65 ++++++++++++++++++++++++++++++--------
debugfs.ocfs2/include/dump.h | 8 +++--
debugfs.ocfs2/journal.c | 20 ++++++++---
4 files changed, 114 insertions(+), 50 deletions(-)
diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index 7aaa840..7f2e4bc 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -73,7 +73,7 @@ static void do_bmap (char **args);
static void do_icheck (char **args);
static void do_dlm_locks (char **args);
static void do_controld(char **args);
-static void do_dir_trailers(char **args);
+static void do_dirblocks(char **args);
dbgfs_gbls gbls;
@@ -109,7 +109,7 @@ static Command commands[] = {
{ "stats", do_stats },
{ "encode", do_encode_lockres },
{ "decode", do_decode_lockres },
- { "dir_trailers", do_dir_trailers },
+ { "dirblocks", do_dirblocks },
};
/*
@@ -835,7 +835,7 @@ static void do_help (char **args)
printf ("decode <lockname#> ...\t\t\tDecode block#(s) from the lockname(s)\n");
printf ("dlm_locks [-f <file>] [-l] lockname\t\t\tShow live dlm locking state\n");
printf ("dump [-p] <filespec> <outfile>\t\tDumps file to outfile on a mounted fs\n");
- printf ("dir_trailers <filespec>\t\t\tDump directory block trailers\n");
+ printf ("dirblocks <filespec>\t\t\tDump directory blocks\n");
printf ("encode <filespec>\t\t\tShow lock name\n");
printf ("extent <block#>\t\t\t\tShow extent block\n");
printf ("findpath <block#>\t\t\tList one pathname of the inode/lockname\n");
@@ -1239,53 +1239,70 @@ static void do_group (char **args)
return ;
}
+static int dirblocks_proxy(ocfs2_filesys *fs, uint64_t blkno,
+ uint64_t bcount, uint16_t ext_flags,
+ void *priv_data)
+{
+ errcode_t ret;
+ struct dirblocks_walk *ctxt = priv_data;
+
+ ret = ocfs2_read_dir_block(fs, ctxt->di, blkno, ctxt->buf);
+ if (!ret) {
+ fprintf(ctxt->out, "\tDirbloc: %"PRIu64"\n", blkno);
+ dump_dir_block(ctxt->out, ctxt->buf);
+ } else
+ com_err(gbls.cmd, ret,
+ "while reading dirblock %"PRIu64" on inode "
+ "%"PRIu64"\n",
+ blkno, ctxt->di->i_blkno);
+ return 0;
+}
+
/*
- * do_dir_trailers()
+ * do_dirblocks()
*
*/
-static void do_dir_trailers (char **args)
+static void do_dirblocks (char **args)
{
- struct ocfs2_dinode *inode;
uint64_t ino_blkno;
- char *buf = NULL;
- FILE *out;
errcode_t ret = 0;
- struct dir_trailer_walk ctxt;
+ struct dirblocks_walk ctxt = {
+ .fs = gbls.fs,
+ };
if (process_inode_args(args, &ino_blkno))
return;
- out = open_pager(gbls.interactive);
-
- ctxt.fs = gbls.fs;
- ctxt.out = out;
+ ret = ocfs2_check_directory(gbls.fs, ino_blkno);
+ if (ret) {
+ com_err(args[0], ret, "while checking directory at "
+ "block %"PRIu64"", ino_blkno);
+ return;
+ }
- buf = gbls.blockbuf;
- ret = ocfs2_read_inode(gbls.fs, ino_blkno, buf);
+ ret = ocfs2_read_inode(gbls.fs, ino_blkno, gbls.blockbuf);
if (ret) {
com_err(args[0], ret, "while reading inode %"PRIu64"",
ino_blkno);
- close_pager (out);
- return ;
+ return;
}
+ ctxt.di = (struct ocfs2_dinode *)gbls.blockbuf;
- inode = (struct ocfs2_dinode *)buf;
- if (!ocfs2_dir_has_trailer(gbls.fs, inode)) {
- fprintf(out, "Inode %"PRIu64" has no trailers\n", ino_blkno);
- close_pager (out);
+ ret = ocfs2_malloc_block(ctxt.fs->fs_io, &ctxt.buf);
+ if (ret) {
+ com_err(gbls.cmd, ret, "while allocating a block");
return;
}
- ret = ocfs2_dir_iterate(gbls.fs, ino_blkno,
- OCFS2_DIRENT_FLAG_INCLUDE_TRAILER, NULL,
- dump_dir_trailers, (void *)&ctxt);
+ ctxt.out = open_pager(gbls.interactive);
+ ret = ocfs2_block_iterate_inode(gbls.fs, ctxt.di, 0,
+ dirblocks_proxy, &ctxt);
if (ret)
com_err(args[0], ret, "while iterating directory at "
"block %"PRIu64"", ino_blkno);
+ close_pager(ctxt.out);
- close_pager(out);
-
- return;
+ ocfs2_free(&ctxt.buf);
}
/*
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
index f1a2560..c2af958 100644
--- a/debugfs.ocfs2/dump.c
+++ b/debugfs.ocfs2/dump.c
@@ -467,26 +467,48 @@ int dump_dir_entry (struct ocfs2_dir_entry *rec, int offset, int blocksize,
}
/*
- * dump_dir_entry()
+ * dump_dir_block()
*
*/
-int dump_dir_trailers(struct ocfs2_dir_entry *rec, int offset, int blocksize,
- char *buf, void *priv_data)
+void dump_dir_block(FILE *out, char *buf)
{
- struct dir_trailer_walk *ctxt = priv_data;
- struct ocfs2_dir_block_trailer *trailer =
- (struct ocfs2_dir_block_trailer *)rec;
- if (ocfs2_dir_trailer_blk_off(ctxt->fs) != offset)
- return 0;
+ struct ocfs2_dir_entry *dirent;
+ int offset = 0;
+ int end = ocfs2_dir_trailer_blk_off(gbls.fs);
+ struct ocfs2_dir_block_trailer *trailer =
+ ocfs2_dir_trailer_from_block(gbls.fs, buf);
+ list_dir_opts ls_opts = {
+ .fs = gbls.fs,
+ .out = out,
+ };
+
+ if (!strncmp((char *)trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE,
+ sizeof(trailer->db_signature))) {
+ fprintf(out,
+ "\tTrailer Block: %-15"PRIu64" Inode: %-15"PRIu64" rec_len: %-4u\n",
+ trailer->db_blkno, trailer->db_parent_dinode,
+ trailer->db_compat_rec_len);
+ dump_block_check(out, &trailer->db_check);
+ } else
+ end = gbls.fs->fs_blocksize;
+
+ fprintf(out, "\tEntries:\n");
+ while (offset < end) {
+ dirent = (struct ocfs2_dir_entry *) (buf + offset);
+ if (((offset + dirent->rec_len) > end) ||
+ (dirent->rec_len < 8) ||
+ ((dirent->rec_len % 4) != 0) ||
+ (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
+ /* Corrupted */
+ return;
+ }
- fprintf(ctxt->out,
- "\tDirblock: %-15"PRIu64" Inode: %-15"PRIu64" rec_len: %-4u\n",
- trailer->db_blkno, trailer->db_parent_dinode,
- trailer->db_compat_rec_len);
- dump_block_check(ctxt->out, &trailer->db_check);
+ dump_dir_entry(dirent, offset, gbls.fs->fs_blocksize, NULL,
+ &ls_opts);
+ offset += dirent->rec_len;
+ }
- return 0;
}
/*
@@ -645,6 +667,8 @@ void dump_jbd_block (FILE *out, journal_superblock_t *jsb,
void dump_jbd_metadata (FILE *out, enum dump_block_type type, char *buf,
uint64_t blknum)
{
+ struct ocfs2_dir_block_trailer *trailer;
+
fprintf (out, "\tBlock %"PRIu64": ", blknum);
switch (type) {
case DUMP_BLOCK_INODE:
@@ -665,6 +689,19 @@ void dump_jbd_metadata (FILE *out, enum dump_block_type type, char *buf,
dump_group_descriptor (out, (struct ocfs2_group_desc *)buf, 0);
fprintf (out, "\n");
break;
+ case DUMP_BLOCK_DIR_BLOCK:
+ fprintf(out, "Dirblock\n");
+ /*
+ * We know there's a trailer, because that's how it
+ * was detected
+ */
+ ocfs2_swap_dir_entries_to_cpu(buf,
+ ocfs2_dir_trailer_blk_off(gbls.fs));
+ trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf);
+ ocfs2_swap_dir_trailer(trailer);
+ dump_dir_block(out, buf);
+ fprintf (out, "\n");
+ break;
default:
fprintf (out, "TODO\n\n");
break;
diff --git a/debugfs.ocfs2/include/dump.h b/debugfs.ocfs2/include/dump.h
index db49dfb..f9ccb27 100644
--- a/debugfs.ocfs2/include/dump.h
+++ b/debugfs.ocfs2/include/dump.h
@@ -25,6 +25,7 @@ enum dump_block_type {
DUMP_BLOCK_INODE,
DUMP_BLOCK_EXTENT_BLOCK,
DUMP_BLOCK_GROUP_DESCRIPTOR,
+ DUMP_BLOCK_DIR_BLOCK,
};
typedef struct _list_dir_opts {
@@ -34,9 +35,11 @@ typedef struct _list_dir_opts {
char *buf;
} list_dir_opts;
-struct dir_trailer_walk {
+struct dirblocks_walk {
ocfs2_filesys *fs;
FILE *out;
+ struct ocfs2_dinode *di;
+ char *buf;
};
void dump_super_block (FILE *out, struct ocfs2_super_block *sb);
@@ -49,8 +52,7 @@ void dump_extent_block (FILE *out, struct ocfs2_extent_block *blk);
void dump_group_descriptor (FILE *out, struct ocfs2_group_desc *grp, int index);
int dump_dir_entry (struct ocfs2_dir_entry *rec, int offset, int blocksize,
char *buf, void *priv_data);
-int dump_dir_trailers(struct ocfs2_dir_entry *rec, int offset, int blocksize,
- char *buf, void *priv_data);
+void dump_dir_block(FILE *out, char *buf);
void dump_jbd_header (FILE *out, journal_header_t *header);
void dump_jbd_superblock (FILE *out, journal_superblock_t *jsb);
void dump_jbd_block (FILE *out, journal_superblock_t *jsb,
diff --git a/debugfs.ocfs2/journal.c b/debugfs.ocfs2/journal.c
index 4b447fd..0343d77 100644
--- a/debugfs.ocfs2/journal.c
+++ b/debugfs.ocfs2/journal.c
@@ -166,29 +166,37 @@ static enum dump_block_type detect_block (char *buf)
struct ocfs2_dinode *inode;
struct ocfs2_extent_block *extent;
struct ocfs2_group_desc *group;
+ struct ocfs2_dir_block_trailer *trailer;
enum dump_block_type ret = DUMP_BLOCK_UNKNOWN;
inode = (struct ocfs2_dinode *)buf;
- if (!memcmp(inode->i_signature, OCFS2_INODE_SIGNATURE,
- sizeof(OCFS2_INODE_SIGNATURE))) {
+ if (!strncmp((char *)inode->i_signature, OCFS2_INODE_SIGNATURE,
+ sizeof(inode->i_signature))) {
ret = DUMP_BLOCK_INODE;
goto bail;
}
extent = (struct ocfs2_extent_block *)buf;
- if (!memcmp(extent->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
- sizeof(OCFS2_EXTENT_BLOCK_SIGNATURE))) {
+ if (!strncmp((char *)extent->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
+ sizeof(extent->h_signature))) {
ret = DUMP_BLOCK_EXTENT_BLOCK;
goto bail;
}
group = (struct ocfs2_group_desc *)buf;
- if (!memcmp(group->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
- sizeof(OCFS2_GROUP_DESC_SIGNATURE))) {
+ if (!strncmp((char *)group->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
+ sizeof(group->bg_signature))) {
ret = DUMP_BLOCK_GROUP_DESCRIPTOR;
goto bail;
}
+ trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf);
+ if (!strncmp((char *)trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE,
+ sizeof(trailer->db_signature))) {
+ ret = DUMP_BLOCK_DIR_BLOCK;
+ goto bail;
+ }
+
bail:
return ret;
} /* detect_block */
--
1.5.6.5
--
"In the long run...we'll all be dead."
-Unknown
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
More information about the Ocfs2-tools-devel
mailing list