diff mbox

[v3,22/27] ubifs: ubifs_dump: dump lpt area

Message ID 1447395218-7061-23-git-send-email-yangds.fnst@cn.fujitsu.com
State Not Applicable
Delegated to: David Oberhollenzer
Headers show

Commit Message

Dongsheng Yang Nov. 13, 2015, 6:13 a.m. UTC
At first dump the ltab and then scan the whole lpt,
dumping every lprops in it.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 Makefile                            |   2 +-
 ubifs-utils/ubifs_dump/ubifs_dump.c | 170 ++++++++++++++++++++++++++++++++++++
 2 files changed, 171 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/Makefile b/Makefile
index 1d7e5f2..0be4772 100644
--- a/Makefile
+++ b/Makefile
@@ -130,7 +130,7 @@  $(foreach v,$(UBI_BINS),$(eval $(call mkdep,ubi-utils/,$(v),libubi.a ubiutils-co
 $(foreach v,crc16.o lpt.o compr.o devtable.o io.o hashtable.o hashtable_itr.o,$(eval UBIFS_LIBS += ../lib/$(v)))
 
 obj-ubifs_dump = $(UBIFS_LIBS)
-obj-ubifs_dump += ../lib/scan.o
+obj-ubifs_dump += ../lib/scan.o ../lib/lprops.o
 LDFLAGS_ubifs_dump = $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(UUIDLDFLAGS)
 LDLIBS_ubifs_dump = -lz -llzo2 -lm -luuid
 $(call mkdep,ubifs-utils/ubifs_dump/,ubifs_dump,,ubi-utils/libubi.a)
diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c
index d7a2951..4b255e3 100644
--- a/ubifs-utils/ubifs_dump/ubifs_dump.c
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -717,6 +717,172 @@  out:
 	return err;
 }
 
+void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
+{
+	int spc, dark = 0, dead = 0;
+
+	if ((lp->flags & LPROPS_CAT_MASK) == LPROPS_EMPTY)
+		return;
+
+	spc = lp->free + lp->dirty;
+	dead = spc;
+
+	if (lp->flags & LPROPS_INDEX)
+		printf("\tLEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d flags %#x (",
+		       lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc,
+		       lp->flags);
+	else
+		printf("\tLEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d flags %#-4x (",
+		       lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc,
+		       dark, dead, (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags);
+
+	if (lp->flags & LPROPS_TAKEN) {
+		if (lp->flags & LPROPS_INDEX)
+			printf("index, taken");
+		else
+			printf("taken");
+	} else {
+		const char *s;
+
+		if (lp->flags & LPROPS_INDEX) {
+			switch (lp->flags & LPROPS_CAT_MASK) {
+			case LPROPS_DIRTY_IDX:
+				s = "dirty index";
+				break;
+			case LPROPS_FRDI_IDX:
+				s = "freeable index";
+				break;
+			default:
+				s = "index";
+			}
+		} else {
+			switch (lp->flags & LPROPS_CAT_MASK) {
+			case LPROPS_UNCAT:
+				s = "not categorized";
+				break;
+			case LPROPS_DIRTY:
+				s = "dirty";
+				break;
+			case LPROPS_FREE:
+				s = "free";
+				break;
+			case LPROPS_EMPTY:
+				s = "empty";
+				break;
+			case LPROPS_FREEABLE:
+				s = "freeable";
+				break;
+			default:
+				s = NULL;
+				break;
+			}
+		}
+		printf("%s", s);
+	}
+
+	if (lp->lnum == c->gc_lnum)
+		printf(", GC LEB");
+	printf(")\n");
+}
+
+void ubifs_dump_lstats(const struct ubifs_lp_stats *lst)
+{
+	printf("\tempty_lebs %d, idx_lebs  %d\n",
+	       lst->empty_lebs, lst->idx_lebs);
+	printf("\ttaken_empty_lebs %d, total_free %lld, total_dirty %lld\n",
+	       lst->taken_empty_lebs, lst->total_free, lst->total_dirty);
+	printf("\ttotal_used %lld, total_dark %lld, total_dead %lld\n",
+	       lst->total_used, lst->total_dark, lst->total_dead);
+	printf("\n");
+}
+
+static int scan_dump_cb(struct ubifs_info *c,
+			 const struct ubifs_lprops *lp, int in_tree __attribute__((unused)),
+			 struct ubifs_lp_stats *lst __attribute__((unused)))
+{
+	ubifs_dump_lprop(c, lp);
+	return 0;
+}
+
+static int ubifs_dump_lprops(struct ubifs_info *c)
+{
+	printf("\tLPROPS statistics: \n");
+	ubifs_dump_lstats(&c->lst);
+	printf("\tLPROPS TREE: \n");
+	c->lpt_nod_buf = malloc(min(c->nnode_sz, c->pnode_sz));
+	ubifs_lpt_scan_nolock(c, c->main_first, c->leb_cnt - 1,
+			  (ubifs_lpt_scan_callback)scan_dump_cb, NULL);
+	printf("\n");
+
+	return 0;
+}
+
+/**
+ * read_ltab - read LPT's own lprops table.
+ * @c: UBIFS file-system description object
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+static int read_ltab(struct ubifs_info *c)
+{
+	int err;
+	void *buf;
+
+	buf = vmalloc(c->ltab_sz);
+	if (!buf)
+		return -ENOMEM;
+	err = ubifs_read(c->ltab_lnum * c->leb_size + c->ltab_offs, c->ltab_sz, buf);
+	if (err)
+		goto out;
+	err = unpack_ltab(c, buf);
+out:
+	vfree(buf);
+	return err;
+}
+
+static int ubifs_dump_lpt_info(struct ubifs_info *c)
+{
+	int i;
+	int ret = 0;
+
+	c->ltab = malloc(c->lpt_lebs * sizeof(struct ubifs_lprops));
+	if (!c->ltab)
+		return err_msg("unable to allocate LPT ltab");
+
+	ret = read_ltab(c);
+	if (ret)
+		return ret;
+	printf("\tLPT INFO: \n");
+	printf("\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
+	printf("\tLPT head is at %d:%d\n",
+	       c->nhead_lnum, c->nhead_offs);
+	printf("\tLPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs);
+	if (c->big_lpt)
+		printf("\tLPT lsave is at %d:%d\n",
+		       c->lsave_lnum, c->lsave_offs);
+	for (i = 0; i < c->lpt_lebs; i++)
+		printf("\tLPT LEB %d free %d dirty %d tgc %d cmt %d\n",
+		       i + c->lpt_first, c->ltab[i].free, c->ltab[i].dirty,
+		       c->ltab[i].tgc, c->ltab[i].cmt);
+	printf("\n");
+	return 0;
+}
+
+static int dump_lpt(void)
+{
+	int ret = 0;
+
+	printf("LPT AREA: \n");
+	ret = ubifs_dump_lpt_info(c);
+	if (ret)
+		return ret;
+
+	ret = ubifs_dump_lprops(c);
+	if (ret)
+		return ret;
+	return 0;
+}
+
 static int dump()
 {
 	int err = 0;
@@ -738,6 +904,10 @@  static int dump()
 	err = dump_log();
 	if (err)
 		goto free;
+
+	err = dump_lpt();
+	if (err)
+		goto free;
 free:
 	free(leb_buf);
 out: