[PATCH 16/27] ubifs: ubifs_dump: dump super block
Dongsheng Yang
yangds.fnst at cn.fujitsu.com
Wed Aug 19 01:39:21 PDT 2015
Read the super block from ubi volume and dump it out.
Signed-off-by: Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
---
ubifs-utils/include/lpt.h | 1 +
ubifs-utils/lib/lpt.c | 29 +++++++
ubifs-utils/ubifs_dump/ubifs_dump.c | 151 ++++++++++++++++++++++++++++++++++--
3 files changed, 173 insertions(+), 8 deletions(-)
diff --git a/ubifs-utils/include/lpt.h b/ubifs-utils/include/lpt.h
index 4cde59d..e2f7348 100644
--- a/ubifs-utils/include/lpt.h
+++ b/ubifs-utils/include/lpt.h
@@ -24,5 +24,6 @@
int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt);
int create_lpt(struct ubifs_info *c);
+int ubifs_calc_lpt_geom(struct ubifs_info *c);
#endif
diff --git a/ubifs-utils/lib/lpt.c b/ubifs-utils/lib/lpt.c
index 100d747..26fb4dd 100644
--- a/ubifs-utils/lib/lpt.c
+++ b/ubifs-utils/lib/lpt.c
@@ -585,3 +585,32 @@ out:
free(pnode);
return err;
}
+
+/**
+ * ubifs_calc_lpt_geom - calculate and check sizes for the LPT area.
+ * @c: the UBIFS file-system description object
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int ubifs_calc_lpt_geom(struct ubifs_info *c)
+{
+ int lebs_needed;
+ long long sz;
+
+ do_calc_lpt_geom(c);
+
+ /* Verify that lpt_lebs is big enough */
+ sz = c->lpt_sz * 2; /* Must have at least 2 times the size */
+ lebs_needed = (sz + c->leb_size - 1) / c->leb_size;
+ if (lebs_needed > c->lpt_lebs) {
+ ubifs_err(c, "too few LPT LEBs, %d", lebs_needed);
+ return -EINVAL;
+ }
+
+ /* Verify that ltab fits in a single LEB (since ltab is a single node */
+ if (c->ltab_sz > c->leb_size) {
+ ubifs_err(c, "LPT ltab too big");
+ return -EINVAL;
+ }
+ return 0;
+}
diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c
index a510aeb..9ddb0f7 100644
--- a/ubifs-utils/ubifs_dump/ubifs_dump.c
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -4,6 +4,7 @@
#include "io.h"
#include "key.h"
+#include "lpt.h"
#define DBG_KEY_BUF_LEN 48
@@ -16,6 +17,13 @@ static const struct option longopts[] = {
struct ubifs_info info_;
static struct ubifs_info *c = &info_;
+/* Global buffers */
+static void *leb_buf;
+
+/* Global nodes*/
+struct ubifs_mst_node mst;
+struct ubifs_sb_node sup;
+
static int get_options(int argc, char**argv)
{
int opt, i;
@@ -73,13 +81,6 @@ static const char *hash_type_to_str[] = {
"UBIFS_KEY_HASH_TEST"
};
-static const char *compr_type_to_str[] = {
- "UBIFS_COMPR_NONE",
- "UBIFS_COMPR_LZO",
- "UBIFS_COMPR_ZLIB",
- "UBIFS_COMPR_TYPES_CNT",
-};
-
static const char *key_fmt_to_str[] = {
"UBIFS_SIMPLE_KEY_FMT"
};
@@ -375,11 +376,145 @@ void dump_node(const struct ubifs_info *c, const void *node)
printf("\n");
}
-static int dump()
+/**
+ * init - initialize things.
+ */
+static int init(void)
+{
+ leb_buf = malloc(c->leb_size);
+ if (!leb_buf)
+ return err_msg("out of memory");
+
+ return 0;
+}
+
+/**
+ * deinit - deinitialize things.
+ */
+static void deinit(void)
+{
+ free(leb_buf);
+}
+
+/*
+ * init_constants_sb - initialize UBIFS constants.
+ * @c: UBIFS file-system description object
+ *
+ * This is a helper function which initializes various UBIFS constants after
+ * the superblock has been read. It also checks various UBIFS parameters and
+ * makes sure they are all right. Returns zero in case of success and a
+ * negative error code in case of failure.
+ */
+static int init_constants_sb(struct ubifs_info *c)
{
+ int tmp, err;
+
+ tmp = ubifs_idx_node_sz(c, 1);
+ c->min_idx_node_sz = ALIGN(tmp, 8);
+
+ tmp = ubifs_idx_node_sz(c, c->fanout);
+ c->max_idx_node_sz = ALIGN(tmp, 8);
+
+ c->max_znode_sz = sizeof(struct ubifs_znode) +
+ c->fanout * sizeof(struct ubifs_zbranch);
+ /* Make sure LEB size is large enough to fit full commit */
+ tmp = UBIFS_CS_NODE_SZ + UBIFS_REF_NODE_SZ * c->jhead_cnt;
+ tmp = ALIGN(tmp, c->min_io_size);
+ if (tmp > c->leb_size) {
+ printf("too small LEB size %d, at least %d needed",
+ c->leb_size, tmp);
+ return -EINVAL;
+ }
+
+ err = ubifs_calc_lpt_geom(c);
+ if (err)
+ return err;
+
return 0;
}
+static int dump_super(void)
+{
+ int err = 0;
+ unsigned long sup_flags;
+
+ memset(&sup, 0, UBIFS_SB_NODE_SZ);
+ err = ubifs_read(0, UBIFS_SB_NODE_SZ, &sup);
+ if (err)
+ return err;
+
+ printf("SUPER BLOCK: \n");
+ dump_node(c, &sup);
+
+ switch (sup.key_hash) {
+ case UBIFS_KEY_HASH_R5:
+ c->key_hash = key_r5_hash;
+ c->key_hash_type = UBIFS_KEY_HASH_R5;
+ break;
+
+ case UBIFS_KEY_HASH_TEST:
+ c->key_hash = key_test_hash;
+ c->key_hash_type = UBIFS_KEY_HASH_TEST;
+ break;
+ };
+
+ c->key_fmt = sup.key_fmt;
+
+ switch (c->key_fmt) {
+ case UBIFS_SIMPLE_KEY_FMT:
+ c->key_len = UBIFS_SK_LEN;
+ break;
+ default:
+ printf("unsupported key format");
+ err = -EINVAL;
+ return err;
+ }
+
+ c->leb_size = le32_to_cpu(sup.leb_size);
+ c->min_io_size = le32_to_cpu(sup.min_io_size);
+ c->leb_cnt = le32_to_cpu(sup.leb_cnt);
+ c->max_leb_cnt = le32_to_cpu(sup.max_leb_cnt);
+ c->max_bud_bytes = le64_to_cpu(sup.max_bud_bytes);
+ c->log_lebs = le32_to_cpu(sup.log_lebs);
+ c->lpt_lebs = le32_to_cpu(sup.lpt_lebs);
+ c->orph_lebs = le32_to_cpu(sup.orph_lebs);
+ c->jhead_cnt = le32_to_cpu(sup.jhead_cnt) + NONDATA_JHEADS_CNT;
+ c->fanout = le32_to_cpu(sup.fanout);
+ c->lsave_cnt = le32_to_cpu(sup.lsave_cnt);
+ c->rp_size = le64_to_cpu(sup.rp_size);
+ sup_flags = le32_to_cpu(sup.flags);
+ c->default_compr = le16_to_cpu(sup.default_compr);
+
+ c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT);
+ c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP);
+
+ /* Automatically increase file system size to the maximum size */
+ c->lpt_first = UBIFS_LOG_LNUM + c->log_lebs;
+ c->lpt_last = c->lpt_first + c->lpt_lebs - 1;
+ c->main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS;
+ c->main_lebs -= c->log_lebs + c->lpt_lebs + c->orph_lebs;
+ c->main_first = c->leb_cnt - c->main_lebs;
+
+ return init_constants_sb(c);
+}
+
+static int dump()
+{
+ int err = 0;
+
+ err = init();
+ if (err)
+ goto out;
+
+ err = dump_super();
+ if (err)
+ goto out;
+
+out:
+ deinit();
+ return err;
+}
+
int main(int argc, char *argv[])
{
int err;
--
1.8.4.2
More information about the linux-mtd
mailing list