[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