[Ocfs2-tools-devel] [PATCH 6/6] debugfs.ocfs2: Print dirblocks as a whole.
Sunil Mushran
sunil.mushran at oracle.com
Fri Jan 9 17:10:47 PST 2009
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
Joel Becker wrote:
> 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 */
>
More information about the Ocfs2-tools-devel
mailing list