[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