[Ocfs2-tools-devel] [PATCH] debugfs.ocfs2: Add 'frag' command
Mark Fasheh
mfasheh at suse.com
Thu Aug 6 13:54:02 PDT 2009
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);
+
+ 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);
+}
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__ */
--
1.5.6
More information about the Ocfs2-tools-devel
mailing list