[Ocfs2-tools-devel] [PATCH] debugfs.ocfs2: Add 'frag' command

Sunil Mushran sunil.mushran at oracle.com
Thu Aug 6 14:10:41 PDT 2009


Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>

Two small comments below.


Mark Fasheh wrote:
> This patch adds a new debugfs.ocfs2 command, 'frag' which will calculate the
> ratio of extents to clusters in an inodes data btree. This can be used to
> get a semi-accurate idea of an inodes data fragmentation level.
>
> Signed-off-by: Mark Fasheh <mfasheh at suse.com>
> ---
>  debugfs.ocfs2/commands.c     |   97 ++++++++++++++++++++++++++++++++++++++++++
>  debugfs.ocfs2/dump.c         |   14 ++++++
>  debugfs.ocfs2/include/dump.h |    2 +
>  3 files changed, 113 insertions(+), 0 deletions(-)
>
> diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
> index 143fc96..08ded82 100644
> --- a/debugfs.ocfs2/commands.c
> +++ b/debugfs.ocfs2/commands.c
> @@ -75,6 +75,7 @@ static void do_dlm_locks (char **args);
>  static void do_controld(char **args);
>  static void do_dirblocks(char **args);
>  static void do_xattr(char **args);
> +static void do_frag(char **args);
>  
>  dbgfs_gbls gbls;
>  
> @@ -112,6 +113,7 @@ static Command commands[] = {
>  	{ "encode",	do_encode_lockres },
>  	{ "decode",	do_decode_lockres },
>  	{ "dirblocks",	do_dirblocks },
> +	{ "frag",	do_frag },
>  };
>  
>  /*
> @@ -858,6 +860,7 @@ static void do_help (char **args)
>  	printf ("stat <filespec>\t\t\t\tShow inode\n");
>  	printf ("stats [-h]\t\t\t\tShow superblock\n");
>  	printf ("xattr [-v] <filespec>\t\t\tShow Extended Attributes\n");
> +	printf ("frag <filespec>\t\t\tShow inode extents / clusters ratio\n");
>  }
>  
>  /*
> @@ -1841,3 +1844,97 @@ static void do_xattr(char **args)
>  
>  	return ;
>  }
> +
> +static errcode_t calc_num_extents(ocfs2_filesys *fs,
> +				  struct ocfs2_extent_list *el,
> +				  uint32_t *ne)
> +{
> +	struct ocfs2_extent_block *eb;
> +	struct ocfs2_extent_rec *rec;
> +	errcode_t ret = 0;
> +	char *buf = NULL;
> +	int i;
> +	uint32_t clusters;
> +	uint32_t extents = 0;
> +
> +	*ne = 0;
> +
> +	for (i = 0; i < el->l_next_free_rec; ++i) {
> +		rec = &(el->l_recs[i]);
> +		clusters = ocfs2_rec_clusters(el->l_tree_depth, rec);
> +
> +		/*
> +		 * In a unsuccessful insertion, we may shift a tree
> +		 * add a new branch for it and do no insertion. So we
> +		 * may meet a extent block which have
> +		 * clusters == 0, this should only be happen
> +		 * in the last extent rec. */
> +		if (!clusters && i == el->l_next_free_rec - 1)
> +			break;
> +
> +		extents = 1;
> +
> +		if (el->l_tree_depth) {
> +			ret = ocfs2_malloc_block(gbls.fs->fs_io, &buf);
> +			if (ret)
> +				goto bail;
> +
> +			ret = ocfs2_read_extent_block(fs, rec->e_blkno, buf);
> +			if (ret)
> +				goto bail;
> +
> +			eb = (struct ocfs2_extent_block *)buf;
> +
> +			ret = calc_num_extents(fs, &(eb->h_list), &extents);
> +			if (ret)
> +				goto bail;
> +
> +		}		
> +
> +		*ne = *ne + extents;
> +	}
> +
> +bail:
> +	if (buf)
> +		ocfs2_free(&buf);
> +	return ret;
> +}
> +
> +static void do_frag(char **args)
> +{
> +	struct ocfs2_dinode *inode;
> +	uint64_t blkno;
> +	char *buf = NULL;
> +	FILE *out;
> +	errcode_t ret = 0;
> +	uint32_t clusters;
> +	uint32_t extents = 0;
> +
> +	if (process_inode_args(args, &blkno))
> +		return;
> +
> +	buf = gbls.blockbuf;
> +	ret = ocfs2_read_inode(gbls.fs, blkno, buf);
> +	if (ret) {
> +		com_err(args[0], ret, "while reading inode %"PRIu64"", blkno);
> +		return ;
> +	}
> +
> +	inode = (struct ocfs2_dinode *)buf;
> +
> +	out = open_pager(gbls.interactive);
> +
> +	clusters = inode->i_clusters;
> +	if (!(inode->i_dyn_features & OCFS2_INLINE_DATA_FL))
> +		ret = calc_num_extents(gbls.fs, &(inode->id2.i_list), &extents);
> +
> +	dump_frag(out, inode->i_blkno, clusters, extents);
> +
> +	if (ret)
> +		com_err(args[0], ret, "while traversing inode at block "
> +			"%"PRIu64, blkno);
>   

Shouldn't it be:
if (ret)
com_err();
else
dump_frag();

> +
> +	close_pager(out);
> +
> +	return ;
> +}
> diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
> index 17f58e9..f69f8bd 100644
> --- a/debugfs.ocfs2/dump.c
> +++ b/debugfs.ocfs2/dump.c
> @@ -1011,3 +1011,17 @@ uint32_t dump_xattr_ibody(FILE *out, ocfs2_filesys *fs,
>  		return 0;
>  	}
>  }
> +
> +void dump_frag(FILE *out, uint64_t ino, uint32_t clusters,
> +	       uint32_t extents)
> +{
> +	float frag_level = 0;
> +
> +	if (clusters > 1 && extents) {
> +		float e = extents, c = clusters;
> +		frag_level = 100 * (e / c);
> +	}
> +
> +	fprintf(out, "Inode: %"PRIu64"\t%% fragmented: %.2f\tclusters:"
> +		" %u\textents: %u\n", ino, frag_level, clusters, extents);
>   

How about adding "%" to the fragmented value?

> +}
> diff --git a/debugfs.ocfs2/include/dump.h b/debugfs.ocfs2/include/dump.h
> index 0abccbc..8cd9a97 100644
> --- a/debugfs.ocfs2/include/dump.h
> +++ b/debugfs.ocfs2/include/dump.h
> @@ -76,5 +76,7 @@ errcode_t dump_xattr_block(FILE *out, ocfs2_filesys *fs,
>  			   uint32_t *xattrs_block,
>  			   uint64_t *xattrs_bucket,
>  			   int verbose);
> +void dump_frag(FILE *out, uint64_t ino, uint32_t clusters,
> +	       uint32_t extents);
>  
>  #endif		/* __DUMP_H__ */
>   




More information about the Ocfs2-tools-devel mailing list