[PATCH v2] ubifs: ubifs_dump: dump master node
Dongsheng Yang
yangds.fnst at cn.fujitsu.com
Thu Oct 8 21:06:11 PDT 2015
On 10/09/2015 12:05 PM, Dongsheng Yang wrote:
> Search the master lebs and found the latest master node.
> Then dump it out.
>
> Signed-off-by: Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
> ---
> changelog:
> - v1:
> fix a bug in error path in scan_for_master();
>
> Makefile | 1 +
> ubifs-utils/ubifs_dump/ubifs_dump.c | 139 +++++++++++++++++++++++++++++-------
> 2 files changed, 113 insertions(+), 27 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index cad71dc..7abbef9 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -133,6 +133,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
> 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 9ddb0f7..f7fac0d 100644
> --- a/ubifs-utils/ubifs_dump/ubifs_dump.c
> +++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
> @@ -2,9 +2,11 @@
> #define PROGRAM_NAME "ubifs-dump"
> #include "common.h"
>
> +#include "ubifs.h"
> #include "io.h"
> #include "key.h"
> #include "lpt.h"
> +#include "scan.h"
>
> #define DBG_KEY_BUF_LEN 48
>
> @@ -17,9 +19,6 @@ 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;
> @@ -376,26 +375,6 @@ void dump_node(const struct ubifs_info *c, const void *node)
> printf("\n");
> }
>
> -/**
> - * 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
> @@ -498,20 +477,126 @@ static int dump_super(void)
> return init_constants_sb(c);
> }
>
> -static int dump()
> +/**
> + * scan_for_master - search the valid master node.
> + * @c: UBIFS file-system description object
> + *
> + * This function scans the master node LEBs and search for the latest master
> + * node. Returns zero in case of success, %-EUCLEAN if there master area is
> + * corrupted and requires recovery, and a negative error code in case of
> + * failure.
> + */
> +static int scan_for_master(struct ubifs_info *c, struct ubifs_mst_node *mst_node)
> {
> + struct ubifs_scan_leb *sleb;
> + struct ubifs_scan_node *snod;
> + int lnum, offs = 0, nodes_cnt;
> + static void *leb_buf;
> int err = 0;
>
> - err = init();
> - if (err)
> + lnum = UBIFS_MST_LNUM;
> +
> + leb_buf = malloc(c->leb_size);
> + if (!leb_buf)
> + return -ENOMEM;
> +
> + sleb = ubifs_scan(c, lnum, 0, leb_buf, 1);
> + if (IS_ERR(sleb))
> + return PTR_ERR(sleb);
Damn, forgot to free leb_buf. will send v3 soon.
Yang
> + nodes_cnt = sleb->nodes_cnt;
> + if (nodes_cnt > 0) {
> + snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
> + list);
> + if (snod->type != UBIFS_MST_NODE) {
> + err = -EINVAL;
> + goto out;
> + }
> + memcpy(mst_node, snod->node, snod->len);
> + offs = snod->offs;
> + }
> + ubifs_scan_destroy(sleb);
> +
> + lnum += 1;
> +
> + sleb = ubifs_scan(c, lnum, 0, leb_buf, 1);
> + if (IS_ERR(sleb)) {
> + return PTR_ERR(sleb);
> + }
> + err = -EUCLEAN;
> + if (sleb->nodes_cnt != nodes_cnt)
> + goto out;
> + if (!sleb->nodes_cnt)
> + goto out;
> + snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list);
> + if (snod->type != UBIFS_MST_NODE) {
> + err = -EINVAL;
> + goto out;
> + }
> + if (snod->offs != offs)
> goto out;
> + if (memcmp((void *)mst_node + UBIFS_CH_SZ,
> + (void *)snod->node + UBIFS_CH_SZ,
> + UBIFS_MST_NODE_SZ - UBIFS_CH_SZ))
> + goto out;
> + err = 0;
> +
> +out:
> + free(leb_buf);
> + ubifs_scan_destroy(sleb);
> + return err;
> +}
> +
> +static int dump_master(void)
> +{
> + int err = 0;
> +
> + printf("MASTER: \n");
> + err = scan_for_master(c, &mst);
> + if (err)
> + return err;
> + dump_node(c, &mst);
> + mst.flags &= cpu_to_le32(~UBIFS_MST_RCVRY);
> +
> + c->max_sqnum = le64_to_cpu(mst.ch.sqnum);
> + c->highest_inum = le64_to_cpu(mst.highest_inum);
> + c->zroot.lnum = le32_to_cpu(mst.root_lnum);
> + c->zroot.offs = le32_to_cpu(mst.root_offs);
> + c->zroot.len = le32_to_cpu(mst.root_len);
> + c->gc_lnum = le32_to_cpu(mst.gc_lnum);
> + c->ihead_lnum = le32_to_cpu(mst.ihead_lnum);
> + c->ihead_offs = le32_to_cpu(mst.ihead_offs);
> + c->lpt_lnum = le32_to_cpu(mst.lpt_lnum);
> + c->lpt_offs = le32_to_cpu(mst.lpt_offs);
> + c->nhead_lnum = le32_to_cpu(mst.nhead_lnum);
> + c->nhead_offs = le32_to_cpu(mst.nhead_offs);
> + c->ltab_lnum = le32_to_cpu(mst.ltab_lnum);
> + c->ltab_offs = le32_to_cpu(mst.ltab_offs);
> + c->lsave_lnum = le32_to_cpu(mst.lsave_lnum);
> + c->lsave_offs = le32_to_cpu(mst.lsave_offs);
> + c->lscan_lnum = le32_to_cpu(mst.lscan_lnum);
> + c->lst.empty_lebs = le32_to_cpu(mst.empty_lebs);
> + c->lst.idx_lebs = le32_to_cpu(mst.idx_lebs);
> + c->lst.total_free = le64_to_cpu(mst.total_free);
> + c->lst.total_dirty = le64_to_cpu(mst.total_dirty);
> + c->lst.total_used = le64_to_cpu(mst.total_used);
> + c->lst.total_dead = le64_to_cpu(mst.total_dead);
> + c->lst.total_dark = le64_to_cpu(mst.total_dark);
> +
> + return 0;
> +}
> +
> +static int dump()
> +{
> + int err = 0;
>
> err = dump_super();
> if (err)
> goto out;
>
> + err = dump_master();
> + if (err)
> + goto out;
> out:
> - deinit();
> return err;
> }
>
>
More information about the linux-mtd
mailing list