All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils
@ 2015-11-13  6:13 Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 01/27] ubifs: pick some common definitions into ubifs_common.h Dongsheng Yang
                   ` (26 more replies)
  0 siblings, 27 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Hi,
	The first one patch is in master. Then rebase the others
here and resend them.

https://github.com/yangdongsheng/mtd-utils ubifs_dump_v3

Yang

Dongsheng Yang (27):
  ubifs: pick some common definitions into ubifs_common.h
  ubifs: move the all io related code into io.[h|c]
  ubifs: remove the including of mkfs.ubifs.h in lpt.c
  ubifs: cut off the dependence from compr.o to mkfs.ubifs
  ubifs: cut off the dependence from devtable to mkfs.ubifs.h
  ubifs: introduce ubifs-utils/include and ubifs-utils/lib
  ubifs: move more functions into io lib
  ubifs: introduce a new tool ubifs_dump
  ubifs: introduce list.h
  ubifs: copy some important data in ubifs.h from kernel to ubifs-utils
  ubifs: copy some important functions in key.h from kernel to
    ubifs-utils
  ubifs: ubifs_dump: add dump_ch and dump_node functions
  ubifs: defs.h: introduce some compatible definition for printk class
  ubifs: io: introduce ubifs_read function to read ubi volume
  ubifs: ubifs_dump: dump super block
  ubifs: introduce scan for ubifs-utils
  ubifs: add some more compatible definitions in defs.h
  ubifs: ubifs_dump: dump master node
  ubifs: ubifs_dump: dump log area
  ubifs: introduce lprops lib
  ubifs: lpt: implement functions to scan lpt
  ubifs: ubifs_dump: dump lpt area
  ubifs: ubifs_dump: dump index area
  ubifs: defs.h: introduce some compatible definitions about integer
    such as __u16
  ubifs: introduce hexdump lib
  ubifs: ubifs_dump: dump data in hex format
  gitignore: add ubifs_dump in gitignore

 .gitignore                                         |    1 +
 Makefile                                           |   16 +-
 ubifs-utils/COPYING                                |  340 ++++++
 ubifs-utils/README                                 |    9 +
 ubifs-utils/include/compr.h                        |   45 +
 ubifs-utils/include/crc16.h                        |   27 +
 ubifs-utils/include/defs.h                         |  215 ++++
 ubifs-utils/include/devtable.h                     |   55 +
 ubifs-utils/include/hashtable.h                    |  199 +++
 ubifs-utils/include/hashtable_itr.h                |  112 ++
 ubifs-utils/include/hashtable_private.h            |   85 ++
 ubifs-utils/include/hexdump.h                      |   21 +
 ubifs-utils/include/io.h                           |   21 +
 ubifs-utils/include/key.h                          |  281 +++++
 ubifs-utils/include/list.h                         |  484 ++++++++
 ubifs-utils/include/lprops.h                       |    6 +
 ubifs-utils/include/lpt.h                          |   32 +
 ubifs-utils/include/scan.h                         |    8 +
 ubifs-utils/include/ubifs.h                        |  536 ++++++++
 ubifs-utils/include/ubifs_common.h                 |   50 +
 ubifs-utils/lib/compr.c                            |  229 ++++
 ubifs-utils/lib/crc16.c                            |   56 +
 ubifs-utils/lib/devtable.c                         |  525 ++++++++
 ubifs-utils/lib/hashtable.c                        |  277 +++++
 ubifs-utils/lib/hashtable_itr.c                    |  176 +++
 ubifs-utils/lib/hexdump.c                          |  200 +++
 ubifs-utils/lib/io.c                               |  152 +++
 ubifs-utils/lib/lprops.c                           |   79 ++
 ubifs-utils/lib/lpt.c                              | 1275 ++++++++++++++++++++
 ubifs-utils/lib/scan.c                             |  318 +++++
 ubifs-utils/mkfs.ubifs/COPYING                     |  340 ------
 ubifs-utils/mkfs.ubifs/README                      |    9 -
 ubifs-utils/mkfs.ubifs/compr.c                     |  234 ----
 ubifs-utils/mkfs.ubifs/compr.h                     |   46 -
 ubifs-utils/mkfs.ubifs/crc16.c                     |   56 -
 ubifs-utils/mkfs.ubifs/crc16.h                     |   27 -
 ubifs-utils/mkfs.ubifs/defs.h                      |   92 --
 ubifs-utils/mkfs.ubifs/devtable.c                  |  524 --------
 ubifs-utils/mkfs.ubifs/hashtable/hashtable.c       |  277 -----
 ubifs-utils/mkfs.ubifs/hashtable/hashtable.h       |  199 ---
 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c   |  176 ---
 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h   |  112 --
 .../mkfs.ubifs/hashtable/hashtable_private.h       |   85 --
 ubifs-utils/mkfs.ubifs/key.h                       |  207 ----
 ubifs-utils/mkfs.ubifs/lpt.c                       |  578 ---------
 ubifs-utils/mkfs.ubifs/lpt.h                       |   28 -
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c                |  144 +--
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.h                |  102 +-
 ubifs-utils/mkfs.ubifs/ubifs.h                     |  450 -------
 ubifs-utils/ubifs_dump/ubifs_dump.c                | 1038 ++++++++++++++++
 50 files changed, 6878 insertions(+), 3676 deletions(-)
 create mode 100644 ubifs-utils/COPYING
 create mode 100644 ubifs-utils/README
 create mode 100644 ubifs-utils/include/compr.h
 create mode 100644 ubifs-utils/include/crc16.h
 create mode 100644 ubifs-utils/include/defs.h
 create mode 100644 ubifs-utils/include/devtable.h
 create mode 100644 ubifs-utils/include/hashtable.h
 create mode 100644 ubifs-utils/include/hashtable_itr.h
 create mode 100644 ubifs-utils/include/hashtable_private.h
 create mode 100644 ubifs-utils/include/hexdump.h
 create mode 100644 ubifs-utils/include/io.h
 create mode 100644 ubifs-utils/include/key.h
 create mode 100644 ubifs-utils/include/list.h
 create mode 100644 ubifs-utils/include/lprops.h
 create mode 100644 ubifs-utils/include/lpt.h
 create mode 100644 ubifs-utils/include/scan.h
 create mode 100644 ubifs-utils/include/ubifs.h
 create mode 100644 ubifs-utils/include/ubifs_common.h
 create mode 100644 ubifs-utils/lib/compr.c
 create mode 100644 ubifs-utils/lib/crc16.c
 create mode 100644 ubifs-utils/lib/devtable.c
 create mode 100644 ubifs-utils/lib/hashtable.c
 create mode 100644 ubifs-utils/lib/hashtable_itr.c
 create mode 100644 ubifs-utils/lib/hexdump.c
 create mode 100644 ubifs-utils/lib/io.c
 create mode 100644 ubifs-utils/lib/lprops.c
 create mode 100644 ubifs-utils/lib/lpt.c
 create mode 100644 ubifs-utils/lib/scan.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/COPYING
 delete mode 100644 ubifs-utils/mkfs.ubifs/README
 delete mode 100644 ubifs-utils/mkfs.ubifs/compr.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/compr.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/crc16.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/crc16.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/defs.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/devtable.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/key.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/lpt.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/lpt.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/ubifs.h
 create mode 100644 ubifs-utils/ubifs_dump/ubifs_dump.c

-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v3 01/27] ubifs: pick some common definitions into ubifs_common.h
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 02/27] ubifs: move the all io related code into io.[h|c] Dongsheng Yang
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Currently, lpt.c is including mkfs.ubifs.h. That make
the lpt depend on mkfs.ubifs. It's not good if we want
to introduce some more tools for ubifs, such as fsck.ubifs.

This patch start to cut off the dependence from libs, such
as lpt, devtable, to mkfs.ubifs.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.h   | 46 +-------------------------------
 ubifs-utils/mkfs.ubifs/ubifs_common.h | 50 +++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 45 deletions(-)
 create mode 100644 ubifs-utils/mkfs.ubifs/ubifs_common.h

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
index 944a159..d6d46a2 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
@@ -23,37 +23,12 @@
 #ifndef __MKFS_UBIFS_H__
 #define __MKFS_UBIFS_H__
 
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-#include <string.h>
-#include <stdint.h>
-#include <endian.h>
-#include <byteswap.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <libgen.h>
-#include <ctype.h>
-#include <uuid/uuid.h>
-#include <sys/file.h>
-
-#include <mtd/ubifs-media.h>
+#include "ubifs_common.h"
 
 /* common.h requires the PROGRAM_NAME macro */
 #define PROGRAM_NAME "mkfs.ubifs"
 #include "common.h"
 
-#include "libubi.h"
-#include "defs.h"
 #include "crc16.h"
 #include "ubifs.h"
 #include "key.h"
@@ -74,25 +49,6 @@
 #error MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
 #endif
 
-extern int verbose;
-extern int debug_level;
-
-#define dbg_msg(lvl, fmt, ...) do {if (debug_level >= lvl)                \
-	printf("mkfs.ubifs: %s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
-} while(0)
-
-#define err_msg(fmt, ...) ({                                \
-	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); \
-	-1;                                                 \
-})
-
-#define sys_err_msg(fmt, ...) ({                                         \
-	int err_ = errno;                                                \
-	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__);              \
-	fprintf(stderr, "       %s (error %d)\n", strerror(err_), err_); \
-	-1;                                                              \
-})
-
 /**
  * struct path_htbl_element - an element of the path hash table.
  * @path: the UBIFS path the element describes (the key of the element)
diff --git a/ubifs-utils/mkfs.ubifs/ubifs_common.h b/ubifs-utils/mkfs.ubifs/ubifs_common.h
new file mode 100644
index 0000000..958c20a
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/ubifs_common.h
@@ -0,0 +1,50 @@
+#ifndef __UBIFS_COMMON_H__
+#define __UBIFS_COMMON_H__
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
+#include <ctype.h>
+#include <uuid/uuid.h>
+#include <sys/file.h>
+
+#include <mtd/ubifs-media.h>
+
+#include "libubi.h"
+#include "defs.h"
+
+extern int verbose;
+extern int debug_level;
+
+#define dbg_msg(lvl, fmt, ...) do {if (debug_level >= lvl)                \
+	printf("ubifs: %s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
+} while(0)
+
+#define err_msg(fmt, ...) ({                                \
+	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); \
+	-1;                                                 \
+})
+
+#define sys_err_msg(fmt, ...) ({                                         \
+	int err_ = errno;                                                \
+	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__);              \
+	fprintf(stderr, "       %s (error %d)\n", strerror(err_), err_); \
+	-1;                                                              \
+})
+#endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 02/27] ubifs: move the all io related code into io.[h|c]
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 01/27] ubifs: pick some common definitions into ubifs_common.h Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 03/27] ubifs: remove the including of mkfs.ubifs.h in lpt.c Dongsheng Yang
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

To cut off the dependence from common lib to mkfs.ubifs,
this patch refactor the io related functions into a new
lib named as io.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 Makefile                            |  2 +-
 ubifs-utils/mkfs.ubifs/io.c         | 33 +++++++++++++++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/io.h         | 15 +++++++++++++++
 ubifs-utils/mkfs.ubifs/lpt.c        | 10 +++++-----
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 34 +++-------------------------------
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.h |  2 +-
 6 files changed, 58 insertions(+), 38 deletions(-)
 create mode 100644 ubifs-utils/mkfs.ubifs/io.c
 create mode 100644 ubifs-utils/mkfs.ubifs/io.h

diff --git a/Makefile b/Makefile
index bd9504a..8864675 100644
--- a/Makefile
+++ b/Makefile
@@ -126,7 +126,7 @@ $(foreach v,$(UBI_BINS),$(eval $(call mkdep,ubi-utils/,$(v),libubi.a ubiutils-co
 #
 # Utils in ubifs-utils subdir
 #
-obj-mkfs.ubifs = crc16.o lpt.o compr.o devtable.o \
+obj-mkfs.ubifs = crc16.o lpt.o compr.o devtable.o io.o\
 	hashtable/hashtable.o hashtable/hashtable_itr.o
 LDFLAGS_mkfs.ubifs = $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(UUIDLDFLAGS)
 LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid
diff --git a/ubifs-utils/mkfs.ubifs/io.c b/ubifs-utils/mkfs.ubifs/io.c
new file mode 100644
index 0000000..7aba0a6
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/io.c
@@ -0,0 +1,33 @@
+#include "io.h"
+#define PROGRAM_NAME "ubifs-io"
+#include <common.h>
+
+int out_fd;
+int out_ubi;
+libubi_t ubi;
+
+/**
+ * write_leb - copy the image of a LEB to the output target.
+ * @lnum: LEB number
+ * @len: length of data in the buffer
+ * @buf: buffer (must be at least c->leb_size bytes)
+ */
+int write_leb(struct ubifs_info *c, int lnum, int len, void *buf)
+{
+	off_t pos = (off_t)lnum * c->leb_size;
+
+	dbg_msg(3, "LEB %d len %d", lnum, len);
+	memset(buf + len, 0xff, c->leb_size - len);
+	if (out_ubi)
+		if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size))
+			return sys_err_msg("ubi_leb_change_start failed");
+
+	if (lseek(out_fd, pos, SEEK_SET) != pos)
+		return sys_err_msg("lseek failed seeking %"PRIdoff_t, pos);
+
+	if (write(out_fd, buf, c->leb_size) != c->leb_size)
+		return sys_err_msg("write failed writing %d bytes at pos %"PRIdoff_t,
+				   c->leb_size, pos);
+
+	return 0;
+}
diff --git a/ubifs-utils/mkfs.ubifs/io.h b/ubifs-utils/mkfs.ubifs/io.h
new file mode 100644
index 0000000..e24d0c6
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/io.h
@@ -0,0 +1,15 @@
+/**
+ * Header file for the io to ubi volume
+ */
+#ifndef __UBIFS_IO_H__
+#define __UBIFS_IO_H__
+
+#include "ubifs_common.h"
+#include "ubifs.h"
+
+extern int out_fd;
+extern int out_ubi;
+extern libubi_t ubi;
+
+int write_leb(struct ubifs_info *c, int lnum, int len, void *buf);
+#endif
diff --git a/ubifs-utils/mkfs.ubifs/lpt.c b/ubifs-utils/mkfs.ubifs/lpt.c
index 6aa0b88..cee221c 100644
--- a/ubifs-utils/mkfs.ubifs/lpt.c
+++ b/ubifs-utils/mkfs.ubifs/lpt.c
@@ -410,7 +410,7 @@ int create_lpt(struct ubifs_info *c)
 			alen = ALIGN(len, c->min_io_size);
 			set_ltab(c, lnum, c->leb_size - alen, alen - len);
 			memset(p, 0xff, alen - len);
-			err = write_leb(lnum++, alen, buf);
+			err = write_leb(c, lnum++, alen, buf);
 			if (err)
 				goto out;
 			p = buf;
@@ -452,7 +452,7 @@ int create_lpt(struct ubifs_info *c)
 				set_ltab(c, lnum, c->leb_size - alen,
 					    alen - len);
 				memset(p, 0xff, alen - len);
-				err = write_leb(lnum++, alen, buf);
+				err = write_leb(c, lnum++, alen, buf);
 				if (err)
 					goto out;
 				p = buf;
@@ -499,7 +499,7 @@ int create_lpt(struct ubifs_info *c)
 			alen = ALIGN(len, c->min_io_size);
 			set_ltab(c, lnum, c->leb_size - alen, alen - len);
 			memset(p, 0xff, alen - len);
-			err = write_leb(lnum++, alen, buf);
+			err = write_leb(c, lnum++, alen, buf);
 			if (err)
 				goto out;
 			p = buf;
@@ -522,7 +522,7 @@ int create_lpt(struct ubifs_info *c)
 		alen = ALIGN(len, c->min_io_size);
 		set_ltab(c, lnum, c->leb_size - alen, alen - len);
 		memset(p, 0xff, alen - len);
-		err = write_leb(lnum++, alen, buf);
+		err = write_leb(c, lnum++, alen, buf);
 		if (err)
 			goto out;
 		p = buf;
@@ -542,7 +542,7 @@ int create_lpt(struct ubifs_info *c)
 
 	/* Write remaining buffer */
 	memset(p, 0xff, alen - len);
-	err = write_leb(lnum, alen, buf);
+	err = write_leb(c, lnum, alen, buf);
 	if (err)
 		goto out;
 
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 90e727c..5b63d32 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -101,7 +101,6 @@ struct inum_mapping {
  */
 struct ubifs_info info_;
 static struct ubifs_info *c = &info_;
-static libubi_t ubi;
 
 /* Debug levels are: 0 (none), 1 (statistics), 2 (files) ,3 (more details) */
 int debug_level;
@@ -112,8 +111,6 @@ static char *root;
 static int root_len;
 static struct stat root_st;
 static char *output;
-static int out_fd;
-static int out_ubi;
 static int squash_owner;
 static int do_create_inum_attr;
 
@@ -753,31 +750,6 @@ static void prepare_node(void *node, int len)
 	ch->crc = cpu_to_le32(crc);
 }
 
-/**
- * write_leb - copy the image of a LEB to the output target.
- * @lnum: LEB number
- * @len: length of data in the buffer
- * @buf: buffer (must be at least c->leb_size bytes)
- */
-int write_leb(int lnum, int len, void *buf)
-{
-	off_t pos = (off_t)lnum * c->leb_size;
-
-	dbg_msg(3, "LEB %d len %d", lnum, len);
-	memset(buf + len, 0xff, c->leb_size - len);
-	if (out_ubi)
-		if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size))
-			return sys_err_msg("ubi_leb_change_start failed");
-
-	if (lseek(out_fd, pos, SEEK_SET) != pos)
-		return sys_err_msg("lseek failed seeking %"PRIdoff_t, pos);
-
-	if (write(out_fd, buf, c->leb_size) != c->leb_size)
-		return sys_err_msg("write failed writing %d bytes at pos %"PRIdoff_t,
-				   c->leb_size, pos);
-
-	return 0;
-}
 
 /**
  * write_empty_leb - copy the image of an empty LEB to the output target.
@@ -785,7 +757,7 @@ int write_leb(int lnum, int len, void *buf)
  */
 static int write_empty_leb(int lnum)
 {
-	return write_leb(lnum, 0, leb_buf);
+	return write_leb(c, lnum, 0, leb_buf);
 }
 
 /**
@@ -841,7 +813,7 @@ static int write_node(void *node, int len, int lnum)
 
 	len = do_pad(leb_buf, len);
 
-	return write_leb(lnum, len, leb_buf);
+	return write_leb(c, lnum, len, leb_buf);
 }
 
 /**
@@ -951,7 +923,7 @@ static int flush_nodes(void)
 	if (!head_offs)
 		return 0;
 	len = do_pad(leb_buf, head_offs);
-	err = write_leb(head_lnum, len, leb_buf);
+	err = write_leb(c, head_lnum, len, leb_buf);
 	if (err)
 		return err;
 	set_lprops(head_lnum, head_offs, head_flags);
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
index d6d46a2..ba646a6 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
@@ -34,6 +34,7 @@
 #include "key.h"
 #include "lpt.h"
 #include "compr.h"
+#include "io.h"
 
 /*
  * Compression flags are duplicated so that compr.c can compile without ubifs.h.
@@ -88,7 +89,6 @@ extern struct ubifs_info info_;
 
 struct hashtable_itr;
 
-int write_leb(int lnum, int len, void *buf);
 int parse_devtable(const char *tbl_file);
 struct path_htbl_element *devtbl_find_path(const char *path);
 struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 03/27] ubifs: remove the including of mkfs.ubifs.h in lpt.c
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 01/27] ubifs: pick some common definitions into ubifs_common.h Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 02/27] ubifs: move the all io related code into io.[h|c] Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 04/27] ubifs: cut off the dependence from compr.o to mkfs.ubifs Dongsheng Yang
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

As we have a ubifs_common.h and a seperate io lib, then
remove the including of mkfs.ubifs.h in lpt.c

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/mkfs.ubifs/lpt.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/ubifs-utils/mkfs.ubifs/lpt.c b/ubifs-utils/mkfs.ubifs/lpt.c
index cee221c..100d747 100644
--- a/ubifs-utils/mkfs.ubifs/lpt.c
+++ b/ubifs-utils/mkfs.ubifs/lpt.c
@@ -20,7 +20,16 @@
  *          Artem Bityutskiy
  */
 
-#include "mkfs.ubifs.h"
+#include "ubifs_common.h"
+
+/* common.h requires the PROGRAM_NAME macro */
+#define PROGRAM_NAME "ubifs-lpt"
+#include "common.h"
+
+#include "crc16.h"
+#include "ubifs.h"
+#include "lpt.h"
+#include "io.h"
 
 /**
  * do_calc_lpt_geom - calculate sizes for the LPT area.
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 04/27] ubifs: cut off the dependence from compr.o to mkfs.ubifs
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (2 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 03/27] ubifs: remove the including of mkfs.ubifs.h in lpt.c Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 05/27] ubifs: cut off the dependence from devtable to mkfs.ubifs.h Dongsheng Yang
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

remove the including of mkfs.ubifs.h in compr lib and
drop the reference of globle variable info_ from compr to mkfs.ubifs.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/mkfs.ubifs/compr.c      | 21 ++++++++-------------
 ubifs-utils/mkfs.ubifs/compr.h      |  3 +--
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c |  8 ++++++--
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/compr.c b/ubifs-utils/mkfs.ubifs/compr.c
index d534f10..4603f5c 100644
--- a/ubifs-utils/mkfs.ubifs/compr.c
+++ b/ubifs-utils/mkfs.ubifs/compr.c
@@ -20,25 +20,20 @@
  *          Zoltan Sogor
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
+#include "ubifs_common.h"
+
 #ifndef WITHOUT_LZO
 #include <lzo/lzo1x.h>
 #endif
-#include <linux/types.h>
 
 #define crc32 __zlib_crc32
 #include <zlib.h>
 #undef crc32
 
 #include "compr.h"
-#include "mkfs.ubifs.h"
 
 static void *lzo_mem;
 static unsigned long long errcnt = 0;
-static struct ubifs_info *c = &info_;
 
 #define DEFLATE_DEF_LEVEL     Z_DEFAULT_COMPRESSION
 #define DEFLATE_DEF_WINBITS   11
@@ -119,7 +114,7 @@ static char *zlib_buf;
 
 #ifndef WITHOUT_LZO
 static int favor_lzo_compress(void *in_buf, size_t in_len, void *out_buf,
-			       size_t *out_len, int *type)
+				size_t *out_len, int *type, int lzo_percent)
 {
 	int lzo_ret, zlib_ret;
 	size_t lzo_len, zlib_len;
@@ -141,7 +136,7 @@ static int favor_lzo_compress(void *in_buf, size_t in_len, void *out_buf,
 
 		percent = (double)zlib_len / (double)lzo_len;
 		percent *= 100;
-		if (percent > 100 - c->favor_percent)
+		if (percent > 100 - lzo_percent)
 			goto select_lzo;
 		goto select_zlib;
 	}
@@ -165,8 +160,8 @@ select_zlib:
 }
 #endif
 
-int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
-		  int type)
+int compress_data(void *in_buf, size_t in_len, void *out_buf,
+		size_t *out_len, int type, int lzo_percent)
 {
 	int ret;
 
@@ -179,8 +174,8 @@ int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
 	{
 		switch (type) {
 #else
-	if (c->favor_lzo)
-		ret = favor_lzo_compress(in_buf, in_len, out_buf, out_len, &type);
+	if (lzo_percent)
+		ret = favor_lzo_compress(in_buf, in_len, out_buf, out_len, &type, lzo_percent);
 	else {
 		switch (type) {
 		case MKFS_UBIFS_COMPR_LZO:
diff --git a/ubifs-utils/mkfs.ubifs/compr.h b/ubifs-utils/mkfs.ubifs/compr.h
index e3dd95c..d44a2ba 100644
--- a/ubifs-utils/mkfs.ubifs/compr.h
+++ b/ubifs-utils/mkfs.ubifs/compr.h
@@ -38,8 +38,7 @@ enum compression_type
 	MKFS_UBIFS_COMPR_ZLIB,
 };
 
-int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
-		  int type);
+int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len, int type, int lzo_percent);
 int init_compression(void);
 void destroy_compression(void);
 
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 5b63d32..a16e856 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1455,8 +1455,12 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 #endif
 		else
 			use_compr = c->default_compr;
-		compr_type = compress_data(buf, bytes_read, &dn->data,
-					   &out_len, use_compr);
+		if (c->favor_lzo)
+			compr_type = compress_data(buf, bytes_read, &dn->data,
+					   &out_len, use_compr, c->favor_percent);
+		else
+			compr_type = compress_data(buf, bytes_read, &dn->data,
+					   &out_len, use_compr, 0);
 		dn->compr_type = cpu_to_le16(compr_type);
 		dn_len = UBIFS_DATA_NODE_SZ + out_len;
 		/* Add data node to file system */
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 05/27] ubifs: cut off the dependence from devtable to mkfs.ubifs.h
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (3 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 04/27] ubifs: cut off the dependence from compr.o to mkfs.ubifs Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 06/27] ubifs: introduce ubifs-utils/include and ubifs-utils/lib Dongsheng Yang
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Refactor the devtable related definitions in mkfs.ubifs.h
to a new devtable.h

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/mkfs.ubifs/devtable.c   |  3 +-
 ubifs-utils/mkfs.ubifs/devtable.h   | 55 +++++++++++++++++++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.h | 54 +-----------------------------------
 3 files changed, 58 insertions(+), 54 deletions(-)
 create mode 100644 ubifs-utils/mkfs.ubifs/devtable.h

diff --git a/ubifs-utils/mkfs.ubifs/devtable.c b/ubifs-utils/mkfs.ubifs/devtable.c
index dee035d..1fc0256 100644
--- a/ubifs-utils/mkfs.ubifs/devtable.c
+++ b/ubifs-utils/mkfs.ubifs/devtable.c
@@ -44,7 +44,8 @@
  * for more information about what the device table is.
  */
 
-#include "mkfs.ubifs.h"
+#include "ubifs_common.h"
+#include "devtable.h"
 #include "hashtable/hashtable.h"
 #include "hashtable/hashtable_itr.h"
 
diff --git a/ubifs-utils/mkfs.ubifs/devtable.h b/ubifs-utils/mkfs.ubifs/devtable.h
new file mode 100644
index 0000000..987d4d4
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/devtable.h
@@ -0,0 +1,55 @@
+#include "ubifs_common.h"
+
+/**
+ * struct path_htbl_element - an element of the path hash table.
+ * @path: the UBIFS path the element describes (the key of the element)
+ * @name_htbl: one more (nested) hash table containing names of all
+ *             files/directories/device nodes which should be created at this
+ *             path
+ *
+ * See device table handling for more information.
+ */
+struct path_htbl_element {
+	const char *path;
+	struct hashtable *name_htbl;
+};
+
+/**
+ * struct name_htbl_element - an element in the name hash table
+ * @name: name of the file/directory/device node (the key of the element)
+ * @mode: accsess rights and file type
+ * @uid: user ID
+ * @gid: group ID
+ * @major: device node major number
+ * @minor: device node minor number
+ *
+ * This is an element of the name hash table. Name hash table sits in the path
+ * hash table elements and describes file names which should be created/changed
+ * at this path.
+ */
+struct name_htbl_element {
+	const char *name;
+	unsigned int mode;
+	unsigned int uid;
+	unsigned int gid;
+	dev_t dev;
+};
+
+extern struct ubifs_info info_;
+
+struct hashtable_itr;
+
+int parse_devtable(const char *tbl_file);
+struct path_htbl_element *devtbl_find_path(const char *path);
+struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
+					   const char *name);
+int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
+			struct name_htbl_element *nh_elt);
+struct name_htbl_element *
+first_name_htbl_element(struct path_htbl_element *ph_elt,
+			struct hashtable_itr **itr);
+struct name_htbl_element *
+next_name_htbl_element(struct path_htbl_element *ph_elt,
+			struct hashtable_itr **itr);
+void free_devtable_info(void);
+
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
index ba646a6..1963e12 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
@@ -34,6 +34,7 @@
 #include "key.h"
 #include "lpt.h"
 #include "compr.h"
+#include "devtable.h"
 #include "io.h"
 
 /*
@@ -50,57 +51,4 @@
 #error MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
 #endif
 
-/**
- * struct path_htbl_element - an element of the path hash table.
- * @path: the UBIFS path the element describes (the key of the element)
- * @name_htbl: one more (nested) hash table containing names of all
- *             files/directories/device nodes which should be created at this
- *             path
- *
- * See device table handling for more information.
- */
-struct path_htbl_element {
-	const char *path;
-	struct hashtable *name_htbl;
-};
-
-/**
- * struct name_htbl_element - an element in the name hash table
- * @name: name of the file/directory/device node (the key of the element)
- * @mode: accsess rights and file type
- * @uid: user ID
- * @gid: group ID
- * @major: device node major number
- * @minor: device node minor number
- *
- * This is an element of the name hash table. Name hash table sits in the path
- * hash table elements and describes file names which should be created/changed
- * at this path.
- */
-struct name_htbl_element {
-	const char *name;
-	unsigned int mode;
-	unsigned int uid;
-	unsigned int gid;
-	dev_t dev;
-};
-
-extern struct ubifs_info info_;
-
-struct hashtable_itr;
-
-int parse_devtable(const char *tbl_file);
-struct path_htbl_element *devtbl_find_path(const char *path);
-struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
-					   const char *name);
-int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
-			struct name_htbl_element *nh_elt);
-struct name_htbl_element *
-first_name_htbl_element(struct path_htbl_element *ph_elt,
-			struct hashtable_itr **itr);
-struct name_htbl_element *
-next_name_htbl_element(struct path_htbl_element *ph_elt,
-		       struct hashtable_itr **itr);
-void free_devtable_info(void);
-
 #endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 06/27] ubifs: introduce ubifs-utils/include and ubifs-utils/lib
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (4 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 05/27] ubifs: cut off the dependence from devtable to mkfs.ubifs.h Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 07/27] ubifs: move more functions into io lib Dongsheng Yang
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Restructure the ubifs-utils/, introducing ubifs-utils/include
and ubifs-utils/lib to make the ubifs-utils/ better for scalability.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 Makefile                                           |   7 +-
 ubifs-utils/COPYING                                | 340 ++++++++++++
 ubifs-utils/README                                 |   9 +
 ubifs-utils/include/compr.h                        |  45 ++
 ubifs-utils/include/crc16.h                        |  27 +
 ubifs-utils/include/defs.h                         |  92 ++++
 ubifs-utils/include/devtable.h                     |  55 ++
 ubifs-utils/include/hashtable.h                    | 199 +++++++
 ubifs-utils/include/hashtable_itr.h                | 112 ++++
 ubifs-utils/include/hashtable_private.h            |  85 +++
 ubifs-utils/include/io.h                           |  15 +
 ubifs-utils/include/key.h                          | 207 ++++++++
 ubifs-utils/include/lpt.h                          |  28 +
 ubifs-utils/include/ubifs.h                        | 450 ++++++++++++++++
 ubifs-utils/include/ubifs_common.h                 |  50 ++
 ubifs-utils/lib/compr.c                            | 229 ++++++++
 ubifs-utils/lib/crc16.c                            |  56 ++
 ubifs-utils/lib/devtable.c                         | 525 ++++++++++++++++++
 ubifs-utils/lib/hashtable.c                        | 277 ++++++++++
 ubifs-utils/lib/hashtable_itr.c                    | 176 ++++++
 ubifs-utils/lib/io.c                               |  33 ++
 ubifs-utils/lib/lpt.c                              | 587 +++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/COPYING                     | 340 ------------
 ubifs-utils/mkfs.ubifs/README                      |   9 -
 ubifs-utils/mkfs.ubifs/compr.c                     | 229 --------
 ubifs-utils/mkfs.ubifs/compr.h                     |  45 --
 ubifs-utils/mkfs.ubifs/crc16.c                     |  56 --
 ubifs-utils/mkfs.ubifs/crc16.h                     |  27 -
 ubifs-utils/mkfs.ubifs/defs.h                      |  92 ----
 ubifs-utils/mkfs.ubifs/devtable.c                  | 525 ------------------
 ubifs-utils/mkfs.ubifs/devtable.h                  |  55 --
 ubifs-utils/mkfs.ubifs/hashtable/hashtable.c       | 277 ----------
 ubifs-utils/mkfs.ubifs/hashtable/hashtable.h       | 199 -------
 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c   | 176 ------
 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h   | 112 ----
 .../mkfs.ubifs/hashtable/hashtable_private.h       |  85 ---
 ubifs-utils/mkfs.ubifs/io.c                        |  33 --
 ubifs-utils/mkfs.ubifs/io.h                        |  15 -
 ubifs-utils/mkfs.ubifs/key.h                       | 207 --------
 ubifs-utils/mkfs.ubifs/lpt.c                       | 587 ---------------------
 ubifs-utils/mkfs.ubifs/lpt.h                       |  28 -
 ubifs-utils/mkfs.ubifs/ubifs.h                     | 450 ----------------
 ubifs-utils/mkfs.ubifs/ubifs_common.h              |  50 --
 43 files changed, 3601 insertions(+), 3600 deletions(-)
 create mode 100644 ubifs-utils/COPYING
 create mode 100644 ubifs-utils/README
 create mode 100644 ubifs-utils/include/compr.h
 create mode 100644 ubifs-utils/include/crc16.h
 create mode 100644 ubifs-utils/include/defs.h
 create mode 100644 ubifs-utils/include/devtable.h
 create mode 100644 ubifs-utils/include/hashtable.h
 create mode 100644 ubifs-utils/include/hashtable_itr.h
 create mode 100644 ubifs-utils/include/hashtable_private.h
 create mode 100644 ubifs-utils/include/io.h
 create mode 100644 ubifs-utils/include/key.h
 create mode 100644 ubifs-utils/include/lpt.h
 create mode 100644 ubifs-utils/include/ubifs.h
 create mode 100644 ubifs-utils/include/ubifs_common.h
 create mode 100644 ubifs-utils/lib/compr.c
 create mode 100644 ubifs-utils/lib/crc16.c
 create mode 100644 ubifs-utils/lib/devtable.c
 create mode 100644 ubifs-utils/lib/hashtable.c
 create mode 100644 ubifs-utils/lib/hashtable_itr.c
 create mode 100644 ubifs-utils/lib/io.c
 create mode 100644 ubifs-utils/lib/lpt.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/COPYING
 delete mode 100644 ubifs-utils/mkfs.ubifs/README
 delete mode 100644 ubifs-utils/mkfs.ubifs/compr.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/compr.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/crc16.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/crc16.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/defs.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/devtable.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/devtable.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/io.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/io.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/key.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/lpt.c
 delete mode 100644 ubifs-utils/mkfs.ubifs/lpt.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/ubifs.h
 delete mode 100644 ubifs-utils/mkfs.ubifs/ubifs_common.h

diff --git a/Makefile b/Makefile
index 8864675..ad0526f 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 
 VERSION = 1.5.2
 
-CPPFLAGS += -D_GNU_SOURCE -I./include -I$(BUILDDIR)/include -I./ubi-utils/include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(UUIDCPPFLAGS)
+CPPFLAGS += -D_GNU_SOURCE -I./include -I$(BUILDDIR)/include -I./ubi-utils/include -I./ubifs-utils/include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(UUIDCPPFLAGS)
 
 ifeq ($(WITHOUT_XATTR), 1)
   CPPFLAGS += -DWITHOUT_XATTR
@@ -126,8 +126,9 @@ $(foreach v,$(UBI_BINS),$(eval $(call mkdep,ubi-utils/,$(v),libubi.a ubiutils-co
 #
 # Utils in ubifs-utils subdir
 #
-obj-mkfs.ubifs = crc16.o lpt.o compr.o devtable.o io.o\
-	hashtable/hashtable.o hashtable/hashtable_itr.o
+$(foreach v,crc16.o lpt.o compr.o devtable.o io.o hashtable.o hashtable_itr.o,$(eval UBIFS_LIBS += ../lib/$(v)))
+
+obj-mkfs.ubifs = $(UBIFS_LIBS)
 LDFLAGS_mkfs.ubifs = $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(UUIDLDFLAGS)
 LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid
 $(call mkdep,ubifs-utils/mkfs.ubifs/,mkfs.ubifs,,ubi-utils/libubi.a)
diff --git a/ubifs-utils/COPYING b/ubifs-utils/COPYING
new file mode 100644
index 0000000..60549be
--- /dev/null
+++ b/ubifs-utils/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+\f
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ubifs-utils/README b/ubifs-utils/README
new file mode 100644
index 0000000..7e19939
--- /dev/null
+++ b/ubifs-utils/README
@@ -0,0 +1,9 @@
+UBIFS File System - Make File System program
+
+* crc16.h and crc16.c were copied from the linux kernel.
+* crc32.h and crc32.c were copied from mtd-utils and amended.
+* ubifs.h is a selection of definitions from fs/ubifs/ubifs.h from the linux kernel.
+* key.h is copied from fs/ubifs/key.h from the linux kernel.
+* defs.h is a bunch of definitions to smooth things over.
+* lpt.c is a selection of functions copied from fs/ubifs/lpt.c from the linux kernel, and amended.
+* hashtable/* was downloaded from http://www.cl.cam.ac.uk/~cwc22/hashtable/
diff --git a/ubifs-utils/include/compr.h b/ubifs-utils/include/compr.h
new file mode 100644
index 0000000..d44a2ba
--- /dev/null
+++ b/ubifs-utils/include/compr.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2008 University of Szeged, Hungary
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Artem Bityutskiy
+ *          Adrian Hunter
+ *          Zoltan Sogor
+ */
+
+#ifndef __UBIFS_COMPRESS_H__
+#define __UBIFS_COMPRESS_H__
+
+/*
+ * Compressors may end-up with more data in the output buffer than in the input
+ * buffer. This constant defined the worst case factor, i.e. we assume that the
+ * output buffer may be at max. WORST_COMPR_FACTOR times larger than input
+ * buffer.
+ */
+#define WORST_COMPR_FACTOR 4
+
+enum compression_type
+{
+	MKFS_UBIFS_COMPR_NONE,
+	MKFS_UBIFS_COMPR_LZO,
+	MKFS_UBIFS_COMPR_ZLIB,
+};
+
+int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len, int type, int lzo_percent);
+int init_compression(void);
+void destroy_compression(void);
+
+#endif
diff --git a/ubifs-utils/include/crc16.h b/ubifs-utils/include/crc16.h
new file mode 100644
index 0000000..539d21a
--- /dev/null
+++ b/ubifs-utils/include/crc16.h
@@ -0,0 +1,27 @@
+/*
+ * Implements the standard CRC-16:
+ *   Width 16
+ *   Poly  0x8005 (x^16 + x^15 + x^2 + 1)
+ *   Init  0
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This code was taken from the linux kernel. The license is GPL Version 2.
+ */
+
+#ifndef __CRC16_H__
+#define __CRC16_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+
+extern uint16_t const crc16_table[256];
+
+extern uint16_t crc16(uint16_t crc, const uint8_t *buffer, size_t len);
+
+static inline uint16_t crc16_byte(uint16_t crc, const uint8_t data)
+{
+	return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
+}
+
+#endif /* __CRC16_H__ */
diff --git a/ubifs-utils/include/defs.h b/ubifs-utils/include/defs.h
new file mode 100644
index 0000000..1fa3316
--- /dev/null
+++ b/ubifs-utils/include/defs.h
@@ -0,0 +1,92 @@
+/*
+ * Greate deal of the code was taken from the kernel UBIFS implementation, and
+ * this file contains some "glue" definitions.
+ */
+
+#ifndef __UBIFS_DEFS_H__
+#define __UBIFS_DEFS_H__
+
+#define t16(x) ({ \
+	uint16_t __b = (x); \
+	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_16(__b); \
+})
+
+#define t32(x) ({ \
+	uint32_t __b = (x); \
+	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_32(__b); \
+})
+
+#define t64(x) ({ \
+	uint64_t __b = (x); \
+	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_64(__b); \
+})
+
+#define cpu_to_le16(x) ((__le16){t16(x)})
+#define cpu_to_le32(x) ((__le32){t32(x)})
+#define cpu_to_le64(x) ((__le64){t64(x)})
+
+#define le16_to_cpu(x) (t16((x)))
+#define le32_to_cpu(x) (t32((x)))
+#define le64_to_cpu(x) (t64((x)))
+
+#define unlikely(x) (x)
+
+#define ubifs_assert(x) ({})
+
+struct qstr
+{
+	char *name;
+	size_t len;
+};
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static inline int fls(int x)
+{
+	int r = 32;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff0000u)) {
+		x <<= 16;
+		r -= 16;
+	}
+	if (!(x & 0xff000000u)) {
+		x <<= 8;
+		r -= 8;
+	}
+	if (!(x & 0xf0000000u)) {
+		x <<= 4;
+		r -= 4;
+	}
+	if (!(x & 0xc0000000u)) {
+		x <<= 2;
+		r -= 2;
+	}
+	if (!(x & 0x80000000u)) {
+		x <<= 1;
+		r -= 1;
+	}
+	return r;
+}
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+#if INT_MAX != 0x7fffffff
+#error : sizeof(int) must be 4 for this program
+#endif
+
+#if (~0ULL) != 0xffffffffffffffffULL
+#error : sizeof(long long) must be 8 for this program
+#endif
+
+#endif
diff --git a/ubifs-utils/include/devtable.h b/ubifs-utils/include/devtable.h
new file mode 100644
index 0000000..987d4d4
--- /dev/null
+++ b/ubifs-utils/include/devtable.h
@@ -0,0 +1,55 @@
+#include "ubifs_common.h"
+
+/**
+ * struct path_htbl_element - an element of the path hash table.
+ * @path: the UBIFS path the element describes (the key of the element)
+ * @name_htbl: one more (nested) hash table containing names of all
+ *             files/directories/device nodes which should be created at this
+ *             path
+ *
+ * See device table handling for more information.
+ */
+struct path_htbl_element {
+	const char *path;
+	struct hashtable *name_htbl;
+};
+
+/**
+ * struct name_htbl_element - an element in the name hash table
+ * @name: name of the file/directory/device node (the key of the element)
+ * @mode: accsess rights and file type
+ * @uid: user ID
+ * @gid: group ID
+ * @major: device node major number
+ * @minor: device node minor number
+ *
+ * This is an element of the name hash table. Name hash table sits in the path
+ * hash table elements and describes file names which should be created/changed
+ * at this path.
+ */
+struct name_htbl_element {
+	const char *name;
+	unsigned int mode;
+	unsigned int uid;
+	unsigned int gid;
+	dev_t dev;
+};
+
+extern struct ubifs_info info_;
+
+struct hashtable_itr;
+
+int parse_devtable(const char *tbl_file);
+struct path_htbl_element *devtbl_find_path(const char *path);
+struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
+					   const char *name);
+int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
+			struct name_htbl_element *nh_elt);
+struct name_htbl_element *
+first_name_htbl_element(struct path_htbl_element *ph_elt,
+			struct hashtable_itr **itr);
+struct name_htbl_element *
+next_name_htbl_element(struct path_htbl_element *ph_elt,
+			struct hashtable_itr **itr);
+void free_devtable_info(void);
+
diff --git a/ubifs-utils/include/hashtable.h b/ubifs-utils/include/hashtable.h
new file mode 100644
index 0000000..c0b0acd
--- /dev/null
+++ b/ubifs-utils/include/hashtable.h
@@ -0,0 +1,199 @@
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ *
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ *
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/ubifs-utils/include/hashtable_itr.h b/ubifs-utils/include/hashtable_itr.h
new file mode 100644
index 0000000..5c94a04
--- /dev/null
+++ b/ubifs-utils/include/hashtable_itr.h
@@ -0,0 +1,112 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable.h"
+#include "hashtable_private.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    struct entry *parent;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+static inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+static inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ *          NB: if you need the value to free it, read it before
+ *          removing. ie: beware memory leaks!
+ *          returns zero if advanced to end of table */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ *          matching the supplied key.
+            h points to the hashtable to be searched.
+ *          returns zero if not found. */
+int
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
+{ \
+    return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/ubifs-utils/include/hashtable_private.h b/ubifs-utils/include/hashtable_private.h
new file mode 100644
index 0000000..3a558e6
--- /dev/null
+++ b/ubifs-utils/include/hashtable_private.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int primeindex;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+    return (hashvalue % tablelength);
+};
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/ubifs-utils/include/io.h b/ubifs-utils/include/io.h
new file mode 100644
index 0000000..e24d0c6
--- /dev/null
+++ b/ubifs-utils/include/io.h
@@ -0,0 +1,15 @@
+/**
+ * Header file for the io to ubi volume
+ */
+#ifndef __UBIFS_IO_H__
+#define __UBIFS_IO_H__
+
+#include "ubifs_common.h"
+#include "ubifs.h"
+
+extern int out_fd;
+extern int out_ubi;
+extern libubi_t ubi;
+
+int write_leb(struct ubifs_info *c, int lnum, int len, void *buf);
+#endif
diff --git a/ubifs-utils/include/key.h b/ubifs-utils/include/key.h
new file mode 100644
index 0000000..39379fd
--- /dev/null
+++ b/ubifs-utils/include/key.h
@@ -0,0 +1,207 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2006-2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Artem Bityutskiy (Битюцкий Артём)
+ *          Adrian Hunter
+ */
+
+/*
+ * This header contains various key-related definitions and helper function.
+ * UBIFS allows several key schemes, so we access key fields only via these
+ * helpers. At the moment only one key scheme is supported.
+ *
+ * Simple key scheme
+ * ~~~~~~~~~~~~~~~~~
+ *
+ * Keys are 64-bits long. First 32-bits are inode number (parent inode number
+ * in case of direntry key). Next 3 bits are node type. The last 29 bits are
+ * 4KiB offset in case of inode node, and direntry hash in case of a direntry
+ * node. We use "r5" hash borrowed from reiserfs.
+ */
+
+#ifndef __UBIFS_KEY_H__
+#define __UBIFS_KEY_H__
+
+/**
+ * key_mask_hash - mask a valid hash value.
+ * @val: value to be masked
+ *
+ * We use hash values as offset in directories, so values %0 and %1 are
+ * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
+ * function makes sure the reserved values are not used.
+ */
+static inline uint32_t key_mask_hash(uint32_t hash)
+{
+	hash &= UBIFS_S_KEY_HASH_MASK;
+	if (unlikely(hash <= 2))
+		hash += 3;
+	return hash;
+}
+
+/**
+ * key_r5_hash - R5 hash function (borrowed from reiserfs).
+ * @s: direntry name
+ * @len: name length
+ */
+static inline uint32_t key_r5_hash(const char *s, int len)
+{
+	uint32_t a = 0;
+	const signed char *str = (const signed char *)s;
+
+	len = len;
+	while (*str) {
+		a += *str << 4;
+		a += *str >> 4;
+		a *= 11;
+		str++;
+	}
+
+	return key_mask_hash(a);
+}
+
+/**
+ * key_test_hash - testing hash function.
+ * @str: direntry name
+ * @len: name length
+ */
+static inline uint32_t key_test_hash(const char *str, int len)
+{
+	uint32_t a = 0;
+
+	len = min_t(uint32_t, len, 4);
+	memcpy(&a, str, len);
+	return key_mask_hash(a);
+}
+
+/**
+ * ino_key_init - initialize inode key.
+ * @c: UBIFS file-system description object
+ * @key: key to initialize
+ * @inum: inode number
+ */
+static inline void ino_key_init(union ubifs_key *key, ino_t inum)
+{
+	key->u32[0] = inum;
+	key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS;
+}
+
+/**
+ * dent_key_init - initialize directory entry key.
+ * @c: UBIFS file-system description object
+ * @key: key to initialize
+ * @inum: parent inode number
+ * @nm: direntry name and length
+ */
+static inline void dent_key_init(const struct ubifs_info *c,
+				 union ubifs_key *key, ino_t inum,
+				 const struct qstr *nm)
+{
+	uint32_t hash = c->key_hash(nm->name, nm->len);
+
+	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+	key->u32[0] = inum;
+	key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
+}
+
+/**
+ * xent_key_init - initialize extended attribute entry key.
+ * @c: UBIFS file-system description object
+ * @key: key to initialize
+ * @inum: host inode number
+ * @nm: extended attribute entry name and length
+ */
+static inline void xent_key_init(const struct ubifs_info *c,
+				 union ubifs_key *key, ino_t inum,
+				 const struct qstr *nm)
+{
+	uint32_t hash = c->key_hash(nm->name, nm->len);
+
+	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+	key->u32[0] = inum;
+	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
+}
+
+/**
+ * data_key_init - initialize data key.
+ * @c: UBIFS file-system description object
+ * @key: key to initialize
+ * @inum: inode number
+ * @block: block number
+ */
+static inline void data_key_init(union ubifs_key *key, ino_t inum,
+				 unsigned int block)
+{
+	ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
+	key->u32[0] = inum;
+	key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
+}
+
+/**
+ * key_write - transform a key from in-memory format.
+ * @c: UBIFS file-system description object
+ * @from: the key to transform
+ * @to: the key to store the result
+ */
+static inline void key_write(const union ubifs_key *from, void *to)
+{
+	union ubifs_key *t = to;
+
+	t->j32[0] = cpu_to_le32(from->u32[0]);
+	t->j32[1] = cpu_to_le32(from->u32[1]);
+	memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8);
+}
+
+/**
+ * key_write_idx - transform a key from in-memory format for the index.
+ * @c: UBIFS file-system description object
+ * @from: the key to transform
+ * @to: the key to store the result
+ */
+static inline void key_write_idx(const union ubifs_key *from, void *to)
+{
+	union ubifs_key *t = to;
+
+	t->j32[0] = cpu_to_le32(from->u32[0]);
+	t->j32[1] = cpu_to_le32(from->u32[1]);
+}
+
+/**
+ * keys_cmp - compare keys.
+ * @c: UBIFS file-system description object
+ * @key1: the first key to compare
+ * @key2: the second key to compare
+ *
+ * This function compares 2 keys and returns %-1 if @key1 is less than
+ * @key2, 0 if the keys are equivalent and %1 if @key1 is greater than @key2.
+ */
+static inline int keys_cmp(const union ubifs_key *key1,
+			   const union ubifs_key *key2)
+{
+	if (key1->u32[0] < key2->u32[0])
+		return -1;
+	if (key1->u32[0] > key2->u32[0])
+		return 1;
+	if (key1->u32[1] < key2->u32[1])
+		return -1;
+	if (key1->u32[1] > key2->u32[1])
+		return 1;
+
+	return 0;
+}
+
+#endif /* !__UBIFS_KEY_H__ */
diff --git a/ubifs-utils/include/lpt.h b/ubifs-utils/include/lpt.h
new file mode 100644
index 0000000..4cde59d
--- /dev/null
+++ b/ubifs-utils/include/lpt.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2008 University of Szeged, Hungary
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Artem Bityutskiy
+ *          Adrian Hunter
+ */
+
+#ifndef __UBIFS_LPT_H__
+#define __UBIFS_LPT_H__
+
+int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt);
+int create_lpt(struct ubifs_info *c);
+
+#endif
diff --git a/ubifs-utils/include/ubifs.h b/ubifs-utils/include/ubifs.h
new file mode 100644
index 0000000..2f080a8
--- /dev/null
+++ b/ubifs-utils/include/ubifs.h
@@ -0,0 +1,450 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2008 University of Szeged, Hungary
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Artem Bityutskiy
+ *          Adrian Hunter
+ *          Zoltan Sogor
+ */
+
+#ifndef __UBIFS_H__
+#define __UBIFS_H__
+
+/* Maximum logical eraseblock size in bytes */
+#define UBIFS_MAX_LEB_SZ (2*1024*1024)
+
+/* Minimum amount of data UBIFS writes to the flash */
+#define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8)
+
+/* Largest key size supported in this implementation */
+#define CUR_MAX_KEY_LEN UBIFS_SK_LEN
+
+/*
+ * There is no notion of truncation key because truncation nodes do not exist
+ * in TNC. However, when replaying, it is handy to introduce fake "truncation"
+ * keys for truncation nodes because the code becomes simpler. So we define
+ * %UBIFS_TRUN_KEY type.
+ */
+#define UBIFS_TRUN_KEY UBIFS_KEY_TYPES_CNT
+
+/*
+ * How much a directory entry/extended attribute entry adds to the parent/host
+ * inode.
+ */
+#define CALC_DENT_SIZE(name_len) ALIGN(UBIFS_DENT_NODE_SZ + (name_len) + 1, 8)
+
+/* How much an extended attribute adds to the host inode */
+#define CALC_XATTR_BYTES(data_len) ALIGN(UBIFS_INO_NODE_SZ + (data_len) + 1, 8)
+
+/* The below union makes it easier to deal with keys */
+union ubifs_key
+{
+	uint8_t u8[CUR_MAX_KEY_LEN];
+	uint32_t u32[CUR_MAX_KEY_LEN/4];
+	uint64_t u64[CUR_MAX_KEY_LEN/8];
+	__le32 j32[CUR_MAX_KEY_LEN/4];
+};
+
+/*
+ * LEB properties flags.
+ *
+ * LPROPS_UNCAT: not categorized
+ * LPROPS_DIRTY: dirty > 0, not index
+ * LPROPS_DIRTY_IDX: dirty + free > UBIFS_CH_SZ and index
+ * LPROPS_FREE: free > 0, not empty, not index
+ * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs
+ * LPROPS_EMPTY: LEB is empty, not taken
+ * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken
+ * LPROPS_FRDI_IDX: free + dirty == leb_size and index, may be taken
+ * LPROPS_CAT_MASK: mask for the LEB categories above
+ * LPROPS_TAKEN: LEB was taken (this flag is not saved on the media)
+ * LPROPS_INDEX: LEB contains indexing nodes (this flag also exists on flash)
+ */
+enum {
+	LPROPS_UNCAT     =  0,
+	LPROPS_DIRTY     =  1,
+	LPROPS_DIRTY_IDX =  2,
+	LPROPS_FREE      =  3,
+	LPROPS_HEAP_CNT  =  3,
+	LPROPS_EMPTY     =  4,
+	LPROPS_FREEABLE  =  5,
+	LPROPS_FRDI_IDX  =  6,
+	LPROPS_CAT_MASK  = 15,
+	LPROPS_TAKEN     = 16,
+	LPROPS_INDEX     = 32,
+};
+
+/**
+ * struct ubifs_lprops - logical eraseblock properties.
+ * @free: amount of free space in bytes
+ * @dirty: amount of dirty space in bytes
+ * @flags: LEB properties flags (see above)
+ */
+struct ubifs_lprops
+{
+	int free;
+	int dirty;
+	int flags;
+};
+
+/**
+ * struct ubifs_lpt_lprops - LPT logical eraseblock properties.
+ * @free: amount of free space in bytes
+ * @dirty: amount of dirty space in bytes
+ */
+struct ubifs_lpt_lprops
+{
+	int free;
+	int dirty;
+};
+
+struct ubifs_nnode;
+
+/**
+ * struct ubifs_cnode - LEB Properties Tree common node.
+ * @parent: parent nnode
+ * @cnext: next cnode to commit
+ * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
+ * @iip: index in parent
+ * @level: level in the tree (zero for pnodes, greater than zero for nnodes)
+ * @num: node number
+ */
+struct ubifs_cnode
+{
+	struct ubifs_nnode *parent;
+	struct ubifs_cnode *cnext;
+	unsigned long flags;
+	int iip;
+	int level;
+	int num;
+};
+
+/**
+ * struct ubifs_pnode - LEB Properties Tree leaf node.
+ * @parent: parent nnode
+ * @cnext: next cnode to commit
+ * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
+ * @iip: index in parent
+ * @level: level in the tree (always zero for pnodes)
+ * @num: node number
+ * @lprops: LEB properties array
+ */
+struct ubifs_pnode
+{
+	struct ubifs_nnode *parent;
+	struct ubifs_cnode *cnext;
+	unsigned long flags;
+	int iip;
+	int level;
+	int num;
+	struct ubifs_lprops lprops[UBIFS_LPT_FANOUT];
+};
+
+/**
+ * struct ubifs_nbranch - LEB Properties Tree internal node branch.
+ * @lnum: LEB number of child
+ * @offs: offset of child
+ * @nnode: nnode child
+ * @pnode: pnode child
+ * @cnode: cnode child
+ */
+struct ubifs_nbranch
+{
+	int lnum;
+	int offs;
+	union
+	{
+		struct ubifs_nnode *nnode;
+		struct ubifs_pnode *pnode;
+		struct ubifs_cnode *cnode;
+	};
+};
+
+/**
+ * struct ubifs_nnode - LEB Properties Tree internal node.
+ * @parent: parent nnode
+ * @cnext: next cnode to commit
+ * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
+ * @iip: index in parent
+ * @level: level in the tree (always greater than zero for nnodes)
+ * @num: node number
+ * @nbranch: branches to child nodes
+ */
+struct ubifs_nnode
+{
+	struct ubifs_nnode *parent;
+	struct ubifs_cnode *cnext;
+	unsigned long flags;
+	int iip;
+	int level;
+	int num;
+	struct ubifs_nbranch nbranch[UBIFS_LPT_FANOUT];
+};
+
+/**
+ * struct ubifs_lp_stats - statistics of eraseblocks in the main area.
+ * @empty_lebs: number of empty LEBs
+ * @taken_empty_lebs: number of taken LEBs
+ * @idx_lebs: number of indexing LEBs
+ * @total_free: total free space in bytes
+ * @total_dirty: total dirty space in bytes
+ * @total_used: total used space in bytes (includes only data LEBs)
+ * @total_dead: total dead space in bytes (includes only data LEBs)
+ * @total_dark: total dark space in bytes (includes only data LEBs)
+ */
+struct ubifs_lp_stats {
+	int empty_lebs;
+	int taken_empty_lebs;
+	int idx_lebs;
+	long long total_free;
+	long long total_dirty;
+	long long total_used;
+	long long total_dead;
+	long long total_dark;
+};
+
+/**
+ * struct ubifs_zbranch - key/coordinate/length branch stored in znodes.
+ * @key: key
+ * @znode: znode address in memory
+ * @lnum: LEB number of the indexing node
+ * @offs: offset of the indexing node within @lnum
+ * @len: target node length
+ */
+struct ubifs_zbranch
+{
+	union ubifs_key key;
+	struct ubifs_znode *znode;
+	int lnum;
+	int offs;
+	int len;
+};
+
+/**
+ * struct ubifs_znode - in-memory representation of an indexing node.
+ * @parent: parent znode or NULL if it is the root
+ * @cnext: next znode to commit
+ * @flags: flags
+ * @time: last access time (seconds)
+ * @level: level of the entry in the TNC tree
+ * @child_cnt: count of child znodes
+ * @iip: index in parent's zbranch array
+ * @alt: lower bound of key range has altered i.e. child inserted at slot 0
+ * @zbranch: array of znode branches (@c->fanout elements)
+ */
+struct ubifs_znode
+{
+	struct ubifs_znode *parent;
+	struct ubifs_znode *cnext;
+	unsigned long flags;
+	unsigned long time;
+	int level;
+	int child_cnt;
+	int iip;
+	int alt;
+#ifdef CONFIG_UBIFS_FS_DEBUG
+	int lnum, offs, len;
+#endif
+	struct ubifs_zbranch zbranch[];
+};
+
+/**
+ * struct ubifs_info - UBIFS file-system description data structure
+ * (per-superblock).
+ *
+ * @highest_inum: highest used inode number
+ * @max_sqnum: current global sequence number
+ *
+ * @jhead_cnt: count of journal heads
+ * @max_bud_bytes: maximum number of bytes allowed in buds
+ *
+ * @zroot: zbranch which points to the root index node and znode
+ * @ihead_lnum: LEB number of index head
+ * @ihead_offs: offset of index head
+ *
+ * @log_lebs: number of logical eraseblocks in the log
+ * @lpt_lebs: number of LEBs used for lprops table
+ * @lpt_first: first LEB of the lprops table area
+ * @lpt_last: last LEB of the lprops table area
+ * @main_lebs: count of LEBs in the main area
+ * @main_first: first LEB of the main area
+ * @default_compr: default compression type
+ * @favor_lzo: favor LZO compression method
+ * @favor_percent: lzo vs. zlib threshold used in case favor LZO
+ *
+ * @key_hash_type: type of the key hash
+ * @key_hash: direntry key hash function
+ * @key_fmt: key format
+ * @key_len: key length
+ * @fanout: fanout of the index tree (number of links per indexing node)
+ *
+ * @min_io_size: minimal input/output unit size
+ * @leb_size: logical eraseblock size in bytes
+ * @leb_cnt: count of logical eraseblocks
+ * @max_leb_cnt: maximum count of logical eraseblocks
+ *
+ * @old_idx_sz: size of index on flash
+ * @lst: lprops statistics
+ *
+ * @dead_wm: LEB dead space watermark
+ * @dark_wm: LEB dark space watermark
+ *
+ * @di: UBI device information
+ * @vi: UBI volume information
+ *
+ * @gc_lnum: LEB number used for garbage collection
+ * @rp_size: reserved pool size
+ *
+ * @space_bits: number of bits needed to record free or dirty space
+ * @lpt_lnum_bits: number of bits needed to record a LEB number in the LPT
+ * @lpt_offs_bits: number of bits needed to record an offset in the LPT
+ * @lpt_spc_bits: number of bits needed to space in the LPT
+ * @pcnt_bits: number of bits needed to record pnode or nnode number
+ * @lnum_bits: number of bits needed to record LEB number
+ * @nnode_sz: size of on-flash nnode
+ * @pnode_sz: size of on-flash pnode
+ * @ltab_sz: size of on-flash LPT lprops table
+ * @lsave_sz: size of on-flash LPT save table
+ * @pnode_cnt: number of pnodes
+ * @nnode_cnt: number of nnodes
+ * @lpt_hght: height of the LPT
+ *
+ * @lpt_lnum: LEB number of the root nnode of the LPT
+ * @lpt_offs: offset of the root nnode of the LPT
+ * @nhead_lnum: LEB number of LPT head
+ * @nhead_offs: offset of LPT head
+ * @big_lpt: flag that LPT is too big to write whole during commit
+ * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up
+ * @lpt_sz: LPT size
+ *
+ * @ltab_lnum: LEB number of LPT's own lprops table
+ * @ltab_offs: offset of LPT's own lprops table
+ * @lpt: lprops table
+ * @ltab: LPT's own lprops table
+ * @lsave_cnt: number of LEB numbers in LPT's save table
+ * @lsave_lnum: LEB number of LPT's save table
+ * @lsave_offs: offset of LPT's save table
+ * @lsave: LPT's save table
+ * @lscan_lnum: LEB number of last LPT scan
+ */
+struct ubifs_info
+{
+	ino_t highest_inum;
+	unsigned long long max_sqnum;
+
+	int jhead_cnt;
+	long long max_bud_bytes;
+
+	struct ubifs_zbranch zroot;
+	int ihead_lnum;
+	int ihead_offs;
+
+	int log_lebs;
+	int lpt_lebs;
+	int lpt_first;
+	int lpt_last;
+	int orph_lebs;
+	int main_lebs;
+	int main_first;
+	int default_compr;
+	int favor_lzo;
+	int favor_percent;
+
+	uint8_t key_hash_type;
+	uint32_t (*key_hash)(const char *str, int len);
+	int key_fmt;
+	int key_len;
+	int fanout;
+
+	int min_io_size;
+	int leb_size;
+	int leb_cnt;
+	int max_leb_cnt;
+
+	unsigned long long old_idx_sz;
+	struct ubifs_lp_stats lst;
+
+	int dead_wm;
+	int dark_wm;
+
+	struct ubi_dev_info di;
+	struct ubi_vol_info vi;
+
+	int gc_lnum;
+	long long rp_size;
+
+	int space_bits;
+	int lpt_lnum_bits;
+	int lpt_offs_bits;
+	int lpt_spc_bits;
+	int pcnt_bits;
+	int lnum_bits;
+	int nnode_sz;
+	int pnode_sz;
+	int ltab_sz;
+	int lsave_sz;
+	int pnode_cnt;
+	int nnode_cnt;
+	int lpt_hght;
+
+	int lpt_lnum;
+	int lpt_offs;
+	int nhead_lnum;
+	int nhead_offs;
+	int big_lpt;
+	int space_fixup;
+	long long lpt_sz;
+
+	int ltab_lnum;
+	int ltab_offs;
+	struct ubifs_lprops *lpt;
+	struct ubifs_lpt_lprops *ltab;
+	int lsave_cnt;
+	int lsave_lnum;
+	int lsave_offs;
+	int *lsave;
+	int lscan_lnum;
+
+};
+
+/**
+ * ubifs_idx_node_sz - return index node size.
+ * @c: the UBIFS file-system description object
+ * @child_cnt: number of children of this index node
+ */
+static inline int ubifs_idx_node_sz(const struct ubifs_info *c, int child_cnt)
+{
+	return UBIFS_IDX_NODE_SZ + (UBIFS_BRANCH_SZ + c->key_len) * child_cnt;
+}
+
+/**
+ * ubifs_idx_branch - return pointer to an index branch.
+ * @c: the UBIFS file-system description object
+ * @idx: index node
+ * @bnum: branch number
+ */
+static inline
+struct ubifs_branch *ubifs_idx_branch(const struct ubifs_info *c,
+				      const struct ubifs_idx_node *idx,
+				      int bnum)
+{
+	return (struct ubifs_branch *)((void *)idx->branches +
+				       (UBIFS_BRANCH_SZ + c->key_len) * bnum);
+}
+
+#endif /* __UBIFS_H__ */
diff --git a/ubifs-utils/include/ubifs_common.h b/ubifs-utils/include/ubifs_common.h
new file mode 100644
index 0000000..958c20a
--- /dev/null
+++ b/ubifs-utils/include/ubifs_common.h
@@ -0,0 +1,50 @@
+#ifndef __UBIFS_COMMON_H__
+#define __UBIFS_COMMON_H__
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
+#include <ctype.h>
+#include <uuid/uuid.h>
+#include <sys/file.h>
+
+#include <mtd/ubifs-media.h>
+
+#include "libubi.h"
+#include "defs.h"
+
+extern int verbose;
+extern int debug_level;
+
+#define dbg_msg(lvl, fmt, ...) do {if (debug_level >= lvl)                \
+	printf("ubifs: %s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
+} while(0)
+
+#define err_msg(fmt, ...) ({                                \
+	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); \
+	-1;                                                 \
+})
+
+#define sys_err_msg(fmt, ...) ({                                         \
+	int err_ = errno;                                                \
+	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__);              \
+	fprintf(stderr, "       %s (error %d)\n", strerror(err_), err_); \
+	-1;                                                              \
+})
+#endif
diff --git a/ubifs-utils/lib/compr.c b/ubifs-utils/lib/compr.c
new file mode 100644
index 0000000..4603f5c
--- /dev/null
+++ b/ubifs-utils/lib/compr.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2008 University of Szeged, Hungary
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Artem Bityutskiy
+ *          Adrian Hunter
+ *          Zoltan Sogor
+ */
+
+#include "ubifs_common.h"
+
+#ifndef WITHOUT_LZO
+#include <lzo/lzo1x.h>
+#endif
+
+#define crc32 __zlib_crc32
+#include <zlib.h>
+#undef crc32
+
+#include "compr.h"
+
+static void *lzo_mem;
+static unsigned long long errcnt = 0;
+
+#define DEFLATE_DEF_LEVEL     Z_DEFAULT_COMPRESSION
+#define DEFLATE_DEF_WINBITS   11
+#define DEFLATE_DEF_MEMLEVEL  8
+
+static int zlib_deflate(void *in_buf, size_t in_len, void *out_buf,
+			size_t *out_len)
+{
+	z_stream strm;
+
+	strm.zalloc = NULL;
+	strm.zfree = NULL;
+
+	/*
+	 * Match exactly the zlib parameters used by the Linux kernel crypto
+	 * API.
+	 */
+        if (deflateInit2(&strm, DEFLATE_DEF_LEVEL, Z_DEFLATED,
+			 -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
+			 Z_DEFAULT_STRATEGY)) {
+		errcnt += 1;
+		return -1;
+	}
+
+	strm.next_in = in_buf;
+	strm.avail_in = in_len;
+	strm.total_in = 0;
+
+	strm.next_out = out_buf;
+	strm.avail_out = *out_len;
+	strm.total_out = 0;
+
+	if (deflate(&strm, Z_FINISH) != Z_STREAM_END) {
+		deflateEnd(&strm);
+		errcnt += 1;
+		return -1;
+	}
+
+	if (deflateEnd(&strm) != Z_OK) {
+		errcnt += 1;
+		return -1;
+	}
+
+	*out_len = strm.total_out;
+
+	return 0;
+}
+
+#ifndef WITHOUT_LZO
+static int lzo_compress(void *in_buf, size_t in_len, void *out_buf,
+			size_t *out_len)
+{
+	lzo_uint len;
+	int ret;
+
+	len = *out_len;
+	ret = lzo1x_999_compress(in_buf, in_len, out_buf, &len, lzo_mem);
+	*out_len = len;
+
+	if (ret != LZO_E_OK) {
+		errcnt += 1;
+		return -1;
+	}
+
+	return 0;
+}
+#endif
+
+static int no_compress(void *in_buf, size_t in_len, void *out_buf,
+		       size_t *out_len)
+{
+	memcpy(out_buf, in_buf, in_len);
+	*out_len = in_len;
+	return 0;
+}
+
+static char *zlib_buf;
+
+#ifndef WITHOUT_LZO
+static int favor_lzo_compress(void *in_buf, size_t in_len, void *out_buf,
+				size_t *out_len, int *type, int lzo_percent)
+{
+	int lzo_ret, zlib_ret;
+	size_t lzo_len, zlib_len;
+
+	lzo_len = zlib_len = *out_len;
+	lzo_ret = lzo_compress(in_buf, in_len, out_buf, &lzo_len);
+	zlib_ret = zlib_deflate(in_buf, in_len, zlib_buf, &zlib_len);
+
+	if (lzo_ret && zlib_ret)
+		/* Both compressors failed */
+		return -1;
+
+	if (!lzo_ret && !zlib_ret) {
+		double percent;
+
+		/* Both compressors succeeded */
+		if (lzo_len <= zlib_len )
+			goto select_lzo;
+
+		percent = (double)zlib_len / (double)lzo_len;
+		percent *= 100;
+		if (percent > 100 - lzo_percent)
+			goto select_lzo;
+		goto select_zlib;
+	}
+
+	if (lzo_ret)
+		/* Only zlib compressor succeeded */
+		goto select_zlib;
+
+	/* Only LZO compressor succeeded */
+
+select_lzo:
+	*out_len = lzo_len;
+	*type = MKFS_UBIFS_COMPR_LZO;
+	return 0;
+
+select_zlib:
+	*out_len = zlib_len;
+	*type = MKFS_UBIFS_COMPR_ZLIB;
+	memcpy(out_buf, zlib_buf, zlib_len);
+	return 0;
+}
+#endif
+
+int compress_data(void *in_buf, size_t in_len, void *out_buf,
+		size_t *out_len, int type, int lzo_percent)
+{
+	int ret;
+
+	if (in_len < UBIFS_MIN_COMPR_LEN) {
+		no_compress(in_buf, in_len, out_buf, out_len);
+		return MKFS_UBIFS_COMPR_NONE;
+	}
+
+#ifdef WITHOUT_LZO
+	{
+		switch (type) {
+#else
+	if (lzo_percent)
+		ret = favor_lzo_compress(in_buf, in_len, out_buf, out_len, &type, lzo_percent);
+	else {
+		switch (type) {
+		case MKFS_UBIFS_COMPR_LZO:
+			ret = lzo_compress(in_buf, in_len, out_buf, out_len);
+			break;
+#endif
+		case MKFS_UBIFS_COMPR_ZLIB:
+			ret = zlib_deflate(in_buf, in_len, out_buf, out_len);
+			break;
+		case MKFS_UBIFS_COMPR_NONE:
+			ret = 1;
+			break;
+		default:
+			errcnt += 1;
+			ret = 1;
+			break;
+		}
+	}
+	if (ret || *out_len >= in_len) {
+		no_compress(in_buf, in_len, out_buf, out_len);
+		return MKFS_UBIFS_COMPR_NONE;
+	}
+	return type;
+}
+
+int init_compression(void)
+{
+#ifdef WITHOUT_LZO
+	lzo_mem = NULL;
+#else
+	lzo_mem = malloc(LZO1X_999_MEM_COMPRESS);
+	if (!lzo_mem)
+		return -1;
+#endif
+
+	zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR);
+	if (!zlib_buf) {
+		free(lzo_mem);
+		return -1;
+	}
+
+	return 0;
+}
+
+void destroy_compression(void)
+{
+	free(zlib_buf);
+	free(lzo_mem);
+	if (errcnt)
+		fprintf(stderr, "%llu compression errors occurred\n", errcnt);
+}
diff --git a/ubifs-utils/lib/crc16.c b/ubifs-utils/lib/crc16.c
new file mode 100644
index 0000000..a19512e
--- /dev/null
+++ b/ubifs-utils/lib/crc16.c
@@ -0,0 +1,56 @@
+/*
+ * This code was taken from the linux kernel. The license is GPL Version 2.
+ */
+
+#include "crc16.h"
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
+uint16_t const crc16_table[256] = {
+	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+/**
+ * crc16 - compute the CRC-16 for the data buffer
+ * @crc:	previous CRC value
+ * @buffer:	data pointer
+ * @len:	number of bytes in the buffer
+ *
+ * Returns the updated CRC value.
+ */
+uint16_t crc16(uint16_t crc, uint8_t const *buffer, size_t len)
+{
+	while (len--)
+		crc = crc16_byte(crc, *buffer++);
+	return crc;
+}
diff --git a/ubifs-utils/lib/devtable.c b/ubifs-utils/lib/devtable.c
new file mode 100644
index 0000000..e6ec319
--- /dev/null
+++ b/ubifs-utils/lib/devtable.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Artem Bityutskiy
+ *
+ * Part of the device table parsing code was taken from the mkfs.jffs2 utility.
+ * The original author of that code is Erik Andersen, hence:
+ *	Copyright (C) 2001, 2002 Erik Andersen <andersen@codepoet.org>
+ */
+
+/*
+ * This file implemented device table support. Device table entries take the
+ * form of:
+ * <path>    <type> <mode> <uid> <gid> <major> <minor> <start>	<inc> <count>
+ * /dev/mem  c       640   0     0     1       1       0        0     -
+ *
+ * Type can be one of:
+ * f  A regular file
+ * d  Directory
+ * c  Character special device file
+ * b  Block special device file
+ * p  Fifo (named pipe)
+ *
+ * Don't bother with symlinks (permissions are irrelevant), hard links (special
+ * cases of regular files), or sockets (why bother).
+ *
+ * Regular files must exist in the target root directory. If a char, block,
+ * fifo, or directory does not exist, it will be created.
+ *
+ * Please, refer the device_table.txt file which can be found at MTD utilities
+ * for more information about what the device table is.
+ */
+
+#include "ubifs_common.h"
+#include "devtable.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+
+/*
+ * The hash table which contains paths to files/directories/device nodes
+ * referred to in the device table. For example, if the device table refers
+ * "/dev/loop0", the @path_htbl will contain "/dev" element.
+ */
+static struct hashtable *path_htbl;
+
+/* Hash function used for hash tables */
+static unsigned int r5_hash(void *s)
+{
+	unsigned int a = 0;
+	const signed char *str = s;
+
+	while (*str) {
+		a += *str << 4;
+		a += *str >> 4;
+		a *= 11;
+		str++;
+	}
+
+	return a;
+}
+
+/*
+ * Check whether 2 keys of a hash table are equivalent. The keys are path/file
+ * names, so we simply use 'strcmp()'.
+ */
+static int is_equivalent(void *k1, void *k2)
+{
+	return !strcmp(k1, k2);
+}
+
+/**
+ * separate_last - separate out the last path component
+ * @buf: the path to split
+ * @len: length of the @buf string
+ * @path: the beginning of path is returned here
+ * @name: the last path component is returned here
+ *
+ * This helper function separates out the the last component of the full path
+ * string. For example, "/dev/loop" would be split on "/dev" and "loop". This
+ * function allocates memory for @path and @name and return the result there.
+ * Returns zero in case of success and a negative error code in case of
+ * failure.
+ */
+static int separate_last(const char *buf, int len, char **path, char **name)
+{
+	int path_len = len, name_len;
+	const char *p = buf + len, *n;
+
+	while (*--p != '/')
+		path_len -= 1;
+
+	/* Drop the final '/' unless this is the root directory */
+	name_len = len - path_len;
+	n = buf + path_len;
+	if (path_len > 1)
+		path_len -= 1;
+
+	*path = malloc(path_len + 1);
+	if (!*path)
+		return err_msg("cannot allocate %d bytes of memory",
+			       path_len + 1);
+	memcpy(*path, buf, path_len);
+	(*path)[path_len] = '\0';
+
+	*name = malloc(name_len + 1);
+	if (!*name) {
+		free(*path);
+		return err_msg("cannot allocate %d bytes of memory",
+			       name_len + 1);
+	}
+	memcpy(*name, n, name_len + 1);
+
+	return 0;
+}
+
+static int interpret_table_entry(const char *line)
+{
+	char buf[1024], type, *path = NULL, *name = NULL;
+	int len;
+	struct path_htbl_element *ph_elt = NULL;
+	struct name_htbl_element *nh_elt = NULL;
+	unsigned int mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;
+	unsigned int start = 0, increment = 0, count = 0;
+
+	if (sscanf(line, "%1023s %c %o %u %u %u %u %u %u %u",
+		   buf, &type, &mode, &uid, &gid, &major, &minor,
+		   &start, &increment, &count) < 0)
+		return sys_err_msg("sscanf failed");
+
+	dbg_msg(3, "name %s, type %c, mode %o, uid %u, gid %u, major %u, "
+		"minor %u, start %u, inc %u, cnt %u",
+		buf, type, mode, uid, gid, major, minor, start,
+		increment, count);
+
+	len = strnlen(buf, 1024);
+	if (len == 1024)
+		return err_msg("too long path");
+
+	if (!strcmp(buf, "/"))
+		return err_msg("device table entries require absolute paths");
+	if (buf[1] == '\0')
+		return err_msg("root directory cannot be created");
+	if (strstr(buf, "//"))
+		return err_msg("'//' cannot be used in the path");
+	if (buf[len - 1] == '/')
+		return err_msg("do not put '/' at the end");
+
+	if (strstr(buf, "/./") || strstr(buf, "/../") ||
+	    !strcmp(buf + len - 2, "/.") || !strcmp(buf + len - 3, "/.."))
+		return err_msg("'.' and '..' cannot be used in the path");
+
+	switch (type) {
+		case 'd':
+			mode |= S_IFDIR;
+			break;
+		case 'f':
+			mode |= S_IFREG;
+			break;
+		case 'p':
+			mode |= S_IFIFO;
+			break;
+		case 'c':
+			mode |= S_IFCHR;
+			break;
+		case 'b':
+			mode |= S_IFBLK;
+			break;
+		default:
+			return err_msg("unsupported file type '%c'", type);
+	}
+
+	if (separate_last(buf, len, &path, &name))
+		return -1;
+
+	/*
+	 * Check if this path already exist in the path hash table and add it
+	 * if it is not.
+	 */
+	ph_elt = hashtable_search(path_htbl, path);
+	if (!ph_elt) {
+		dbg_msg(3, "inserting '%s' into path hash table", path);
+		ph_elt = malloc(sizeof(struct path_htbl_element));
+		if (!ph_elt) {
+			err_msg("cannot allocate %zd bytes of memory",
+				sizeof(struct path_htbl_element));
+			goto out_free;
+		}
+
+		if (!hashtable_insert(path_htbl, path, ph_elt)) {
+			err_msg("cannot insert into path hash table");
+			goto out_free;
+		}
+
+		ph_elt->path = path;
+		path = NULL;
+		ph_elt->name_htbl = create_hashtable(128, &r5_hash,
+						     &is_equivalent);
+		if (!ph_elt->name_htbl) {
+			err_msg("cannot create name hash table");
+			goto out_free;
+		}
+	}
+
+	if (increment != 0 && count == 0)
+		return err_msg("count cannot be zero if increment is non-zero");
+
+	/*
+	 * Add the file/directory/device node (last component of the path) to
+	 * the name hashtable. The name hashtable resides in the corresponding
+	 * path hashtable element.
+	 */
+
+	if (count == 0) {
+		/* This entry does not require any iterating */
+		nh_elt = malloc(sizeof(struct name_htbl_element));
+		if (!nh_elt) {
+			err_msg("cannot allocate %zd bytes of memory",
+				sizeof(struct name_htbl_element));
+			goto out_free;
+		}
+
+		nh_elt->mode = mode;
+		nh_elt->uid = uid;
+		nh_elt->gid = gid;
+		nh_elt->dev = makedev(major, minor);
+
+		dbg_msg(3, "inserting '%s' into name hash table (major %d, minor %d)",
+			name, major(nh_elt->dev), minor(nh_elt->dev));
+
+		if (hashtable_search(ph_elt->name_htbl, name))
+			return err_msg("'%s' is referred twice", buf);
+
+		nh_elt->name = name;
+		if (!hashtable_insert(ph_elt->name_htbl, name, nh_elt)) {
+			err_msg("cannot insert into name hash table");
+			goto out_free;
+		}
+	} else {
+		int i, num = start + count, len = strlen(name) + 20;
+		char *nm;
+
+		for (i = start; i < num; i++) {
+			nh_elt = malloc(sizeof(struct name_htbl_element));
+			if (!nh_elt) {
+				err_msg("cannot allocate %zd bytes of memory",
+					sizeof(struct name_htbl_element));
+				goto out_free;
+			}
+
+			nh_elt->mode = mode;
+			nh_elt->uid = uid;
+			nh_elt->gid = gid;
+			nh_elt->dev = makedev(major, minor + (i - start) * increment);
+
+			nm = malloc(len);
+			if (!nm) {
+				err_msg("cannot allocate %d bytes of memory", len);
+				goto out_free;
+			}
+
+			sprintf(nm, "%s%d", name, i);
+			nh_elt->name = nm;
+
+			dbg_msg(3, "inserting '%s' into name hash table (major %d, minor %d)",
+			        nm, major(nh_elt->dev), minor(nh_elt->dev));
+
+			if (hashtable_search(ph_elt->name_htbl, nm)) {
+				err_msg("'%s' is referred twice", buf);
+				free (nm);
+				goto out_free;
+			}
+
+			if (!hashtable_insert(ph_elt->name_htbl, nm, nh_elt)) {
+				err_msg("cannot insert into name hash table");
+				free (nm);
+				goto out_free;
+			}
+		}
+		free(name);
+		name = NULL;
+	}
+
+	return 0;
+
+out_free:
+	free(ph_elt);
+	free(nh_elt);
+	free(path);
+	free(name);
+	return -1;
+}
+
+/**
+ * parse_devtable - parse the device table.
+ * @tbl_file: device table file name
+ *
+ * This function parses the device table and prepare the hash table which will
+ * later be used by mkfs.ubifs to create the specified files/device nodes.
+ * Returns zero in case of success and a negative error code in case of
+ * failure.
+ */
+int parse_devtable(const char *tbl_file)
+{
+	FILE *f;
+	char *line = NULL;
+	struct stat st;
+	size_t len;
+
+	dbg_msg(1, "parsing device table file '%s'", tbl_file);
+
+	path_htbl = create_hashtable(128, &r5_hash, &is_equivalent);
+	if (!path_htbl)
+		return err_msg("cannot create path hash table");
+
+	f = fopen(tbl_file, "r");
+	if (!f)
+		return sys_err_msg("cannot open '%s'", tbl_file);
+
+	if (fstat(fileno(f), &st) < 0) {
+		sys_err_msg("cannot stat '%s'", tbl_file);
+		goto out_close;
+	}
+
+	if (st.st_size < 10) {
+		sys_err_msg("'%s' is too short", tbl_file);
+		goto out_close;
+	}
+
+	/*
+	 * The general plan now is to read in one line at a time, check for
+	 * leading comment delimiters ('#'), then try and parse the line as a
+	 * device table
+	 */
+	while (getline(&line, &len, f) != -1) {
+		/* First trim off any white-space */
+		len = strlen(line);
+
+		/* Trim trailing white-space */
+		while (len > 0 && isspace(line[len - 1]))
+			line[--len] = '\0';
+		/* Trim leading white-space */
+		memmove(line, &line[strspn(line, " \n\r\t\v")], len);
+
+		/* How long are we after trimming? */
+		len = strlen(line);
+
+		/* If this is not a comment line, try to interpret it */
+		if (len && *line != '#') {
+			if (interpret_table_entry(line)) {
+				err_msg("cannot parse '%s'", line);
+				goto out_close;
+			}
+		}
+
+		free(line);
+		line = NULL;
+	}
+
+	dbg_msg(1, "finished parsing");
+	fclose(f);
+	return 0;
+
+out_close:
+	fclose(f);
+	free_devtable_info();
+	return -1;
+}
+
+/**
+ * devtbl_find_path - find a path in the path hash table.
+ * @path: UBIFS path to find.
+ *
+ * This looks up the path hash table. Returns the path hash table element
+ * reference if @path was found and %NULL if not.
+ */
+struct path_htbl_element *devtbl_find_path(const char *path)
+{
+	if (!path_htbl)
+		return NULL;
+
+	return hashtable_search(path_htbl, (void *)path);
+}
+
+/**
+ * devtbl_find_name - find a name in the name hash table.
+ * @ph_etl: path hash table element to find at
+ * @name: name to find
+ *
+ * This looks up the name hash table. Returns the name hash table element
+ * reference if @name found and %NULL if not.
+ */
+struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
+					   const char *name)
+{
+	if (!path_htbl)
+		return NULL;
+
+	return hashtable_search(ph_elt->name_htbl, (void *)name);
+}
+
+/**
+ * override_attributes - override inode attributes.
+ * @st: struct stat object to containing the attributes to override
+ * @ph_elt: path hash table element object
+ * @nh_elt: name hash table element object containing the new values
+ *
+ * The device table file may override attributes like UID of files. For
+ * example, the device table may contain a "/dev" entry, and the UBIFS FS on
+ * the host may contain "/dev" directory. In this case the attributes of the
+ * "/dev" directory inode has to be as the device table specifies.
+ *
+ * Note, the hash element is removed by this function as well.
+ */
+int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
+			struct name_htbl_element *nh_elt)
+{
+	if (!path_htbl)
+		return 0;
+
+	if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode) ||
+	    S_ISFIFO(st->st_mode))
+		return err_msg("%s/%s both exists at UBIFS root at host, "
+			       "and is referred from the device table",
+			       strcmp(ph_elt->path, "/") ? ph_elt->path : "",
+			       nh_elt->name);
+
+	if ((st->st_mode & S_IFMT) != (nh_elt->mode & S_IFMT))
+		return err_msg("%s/%s is referred from the device table also exists in "
+			       "the UBIFS root directory at host, but the file type is "
+			       "different", strcmp(ph_elt->path, "/") ? ph_elt->path : "",
+			       nh_elt->name);
+
+	dbg_msg(3, "set UID %d, GID %d, mode %o for %s/%s as device table says",
+		nh_elt->uid, nh_elt->gid, nh_elt->mode, ph_elt->path, nh_elt->name);
+
+	st->st_uid = nh_elt->uid;
+	st->st_gid = nh_elt->gid;
+	st->st_mode = nh_elt->mode;
+
+	hashtable_remove(ph_elt->name_htbl, (void *)nh_elt->name);
+	return 0;
+}
+
+/**
+ * first_name_htbl_element - return first element of the name hash table.
+ * @ph_elt: the path hash table the name hash table belongs to
+ * @itr: double pointer to a 'struct hashtable_itr' object where the
+ *       information about further iterations is stored
+ *
+ * This function implements name hash table iteration together with
+ * 'next_name_htbl_element()'. Returns the first name hash table element or
+ * %NULL if the hash table is empty.
+ */
+struct name_htbl_element *
+first_name_htbl_element(struct path_htbl_element *ph_elt,
+			struct hashtable_itr **itr)
+{
+	if (!path_htbl || !ph_elt || hashtable_count(ph_elt->name_htbl) == 0)
+		return NULL;
+
+	*itr = hashtable_iterator(ph_elt->name_htbl);
+	return hashtable_iterator_value(*itr);
+}
+
+/**
+ * first_name_htbl_element - return next element of the name hash table.
+ * @ph_elt: the path hash table the name hash table belongs to
+ * @itr: double pointer to a 'struct hashtable_itr' object where the
+ *       information about further iterations is stored
+ *
+ * This function implements name hash table iteration together with
+ * 'first_name_htbl_element()'. Returns the next name hash table element or
+ * %NULL if there are no more elements.
+ */
+struct name_htbl_element *
+next_name_htbl_element(struct path_htbl_element *ph_elt,
+		       struct hashtable_itr **itr)
+{
+	if (!path_htbl || !ph_elt || !hashtable_iterator_advance(*itr))
+		return NULL;
+
+	return hashtable_iterator_value(*itr);
+}
+
+/**
+ * free_devtable_info - free device table information.
+ *
+ * This function frees the path hash table and the name hash tables.
+ */
+void free_devtable_info(void)
+{
+	struct hashtable_itr *ph_itr;
+	struct path_htbl_element *ph_elt;
+
+	if (!path_htbl)
+		return;
+
+	if (hashtable_count(path_htbl) > 0) {
+		ph_itr = hashtable_iterator(path_htbl);
+		do {
+			ph_elt = hashtable_iterator_value(ph_itr);
+			/*
+			 * Note, since we use the same string for the key and
+			 * @name in the name hash table elements, we do not
+			 * have to iterate name hash table because @name memory
+			 * will be freed when freeing the key.
+			 */
+			hashtable_destroy(ph_elt->name_htbl, 1);
+		} while (hashtable_iterator_advance(ph_itr));
+	}
+	hashtable_destroy(path_htbl, 1);
+}
diff --git a/ubifs-utils/lib/hashtable.c b/ubifs-utils/lib/hashtable.c
new file mode 100644
index 0000000..c1f99ed
--- /dev/null
+++ b/ubifs-utils/lib/hashtable.c
@@ -0,0 +1,277 @@
+/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#define PROGRAM_NAME "hashtable"
+
+#include "common.h"
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = ARRAY_SIZE(primes);
+const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(struct entry *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
+    return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            freekey(e->k);
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f); }
+        }
+    }
+    free(h->table);
+    free(h);
+}
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/ubifs-utils/lib/hashtable_itr.c b/ubifs-utils/lib/hashtable_itr.c
new file mode 100644
index 0000000..d102453
--- /dev/null
+++ b/ubifs-utils/lib/hashtable_itr.c
@@ -0,0 +1,176 @@
+/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname@cl.cam.ac.uk> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_itr.h"
+#include <stdlib.h> /* defines NULL */
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+    unsigned int i, tablelength;
+    struct hashtable_itr *itr = (struct hashtable_itr *)
+        malloc(sizeof(struct hashtable_itr));
+    if (NULL == itr) return NULL;
+    itr->h = h;
+    itr->e = NULL;
+    itr->parent = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) return itr;
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+    return itr;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+    unsigned int j,tablelength;
+    struct entry **table;
+    struct entry *next;
+    if (NULL == itr->e) return 0; /* stupidity check */
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->parent = itr->e;
+        itr->e = next;
+        return -1;
+    }
+    tablelength = itr->h->tablelength;
+    itr->parent = NULL;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        return 0;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            itr->e = NULL;
+            return 0;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    return -1;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ *          and advance the iterator, if there is a successive
+ *          element.
+ *          If you want the value, read it before you remove:
+ *          beware memory leaks if you don't.
+ *          Returns zero if end of iteration. */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr)
+{
+    struct entry *remember_e, *remember_parent;
+    int ret;
+
+    /* Do the removal */
+    if (NULL == (itr->parent))
+    {
+        /* element is head of a chain */
+        itr->h->table[itr->index] = itr->e->next;
+    } else {
+        /* element is mid-chain */
+        itr->parent->next = itr->e->next;
+    }
+    /* itr->e is now outside the hashtable */
+    remember_e = itr->e;
+    itr->h->entrycount--;
+    freekey(remember_e->k);
+
+    /* Advance the iterator, correcting the parent */
+    remember_parent = itr->parent;
+    ret = hashtable_iterator_advance(itr);
+    if (itr->parent == remember_e) { itr->parent = remember_parent; }
+    free(remember_e);
+    return ret;
+}
+
+/*****************************************************************************/
+int /* returns zero if not found */
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k)
+{
+    struct entry *e, *parent;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+
+    e = h->table[index];
+    parent = NULL;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            itr->index = index;
+            itr->e = e;
+            itr->parent = parent;
+            itr->h = h;
+            return -1;
+        }
+        parent = e;
+        e = e->next;
+    }
+    return 0;
+}
+
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/ubifs-utils/lib/io.c b/ubifs-utils/lib/io.c
new file mode 100644
index 0000000..7aba0a6
--- /dev/null
+++ b/ubifs-utils/lib/io.c
@@ -0,0 +1,33 @@
+#include "io.h"
+#define PROGRAM_NAME "ubifs-io"
+#include <common.h>
+
+int out_fd;
+int out_ubi;
+libubi_t ubi;
+
+/**
+ * write_leb - copy the image of a LEB to the output target.
+ * @lnum: LEB number
+ * @len: length of data in the buffer
+ * @buf: buffer (must be at least c->leb_size bytes)
+ */
+int write_leb(struct ubifs_info *c, int lnum, int len, void *buf)
+{
+	off_t pos = (off_t)lnum * c->leb_size;
+
+	dbg_msg(3, "LEB %d len %d", lnum, len);
+	memset(buf + len, 0xff, c->leb_size - len);
+	if (out_ubi)
+		if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size))
+			return sys_err_msg("ubi_leb_change_start failed");
+
+	if (lseek(out_fd, pos, SEEK_SET) != pos)
+		return sys_err_msg("lseek failed seeking %"PRIdoff_t, pos);
+
+	if (write(out_fd, buf, c->leb_size) != c->leb_size)
+		return sys_err_msg("write failed writing %d bytes at pos %"PRIdoff_t,
+				   c->leb_size, pos);
+
+	return 0;
+}
diff --git a/ubifs-utils/lib/lpt.c b/ubifs-utils/lib/lpt.c
new file mode 100644
index 0000000..100d747
--- /dev/null
+++ b/ubifs-utils/lib/lpt.c
@@ -0,0 +1,587 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2006, 2007 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Adrian Hunter
+ *          Artem Bityutskiy
+ */
+
+#include "ubifs_common.h"
+
+/* common.h requires the PROGRAM_NAME macro */
+#define PROGRAM_NAME "ubifs-lpt"
+#include "common.h"
+
+#include "crc16.h"
+#include "ubifs.h"
+#include "lpt.h"
+#include "io.h"
+
+/**
+ * do_calc_lpt_geom - calculate sizes for the LPT area.
+ * @c: the UBIFS file-system description object
+ *
+ * Calculate the sizes of LPT bit fields, nodes, and tree, based on the
+ * properties of the flash and whether LPT is "big" (c->big_lpt).
+ */
+static void do_calc_lpt_geom(struct ubifs_info *c)
+{
+	int n, bits, per_leb_wastage;
+	long long sz, tot_wastage;
+
+	c->pnode_cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
+
+	n = (c->pnode_cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
+	c->nnode_cnt = n;
+	while (n > 1) {
+		n = (n + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
+		c->nnode_cnt += n;
+	}
+
+	c->lpt_hght = 1;
+	n = UBIFS_LPT_FANOUT;
+	while (n < c->pnode_cnt) {
+		c->lpt_hght += 1;
+		n <<= UBIFS_LPT_FANOUT_SHIFT;
+	}
+
+	c->space_bits = fls(c->leb_size) - 3;
+	c->lpt_lnum_bits = fls(c->lpt_lebs);
+	c->lpt_offs_bits = fls(c->leb_size - 1);
+	c->lpt_spc_bits = fls(c->leb_size);
+
+	n = (c->max_leb_cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
+	c->pcnt_bits = fls(n - 1);
+
+	c->lnum_bits = fls(c->max_leb_cnt - 1);
+
+	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
+	       (c->big_lpt ? c->pcnt_bits : 0) +
+	       (c->space_bits * 2 + 1) * UBIFS_LPT_FANOUT;
+	c->pnode_sz = (bits + 7) / 8;
+
+	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
+	       (c->big_lpt ? c->pcnt_bits : 0) +
+	       (c->lpt_lnum_bits + c->lpt_offs_bits) * UBIFS_LPT_FANOUT;
+	c->nnode_sz = (bits + 7) / 8;
+
+	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
+	       c->lpt_lebs * c->lpt_spc_bits * 2;
+	c->ltab_sz = (bits + 7) / 8;
+
+	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
+	       c->lnum_bits * c->lsave_cnt;
+	c->lsave_sz = (bits + 7) / 8;
+
+	/* Calculate the minimum LPT size */
+	c->lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
+	c->lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
+	c->lpt_sz += c->ltab_sz;
+	c->lpt_sz += c->lsave_sz;
+
+	/* Add wastage */
+	sz = c->lpt_sz;
+	per_leb_wastage = max_t(int, c->pnode_sz, c->nnode_sz);
+	sz += per_leb_wastage;
+	tot_wastage = per_leb_wastage;
+	while (sz > c->leb_size) {
+		sz += per_leb_wastage;
+		sz -= c->leb_size;
+		tot_wastage += per_leb_wastage;
+	}
+	tot_wastage += ALIGN(sz, c->min_io_size) - sz;
+	c->lpt_sz += tot_wastage;
+}
+
+/**
+ * calc_dflt_lpt_geom - calculate default LPT geometry.
+ * @c: the UBIFS file-system description object
+ * @main_lebs: number of main area LEBs is passed and returned here
+ * @big_lpt: whether the LPT area is "big" is returned here
+ *
+ * The size of the LPT area depends on parameters that themselves are dependent
+ * on the size of the LPT area. This function, successively recalculates the LPT
+ * area geometry until the parameters and resultant geometry are consistent.
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt)
+{
+	int i, lebs_needed;
+	long long sz;
+
+	/* Start by assuming the minimum number of LPT LEBs */
+	c->lpt_lebs = UBIFS_MIN_LPT_LEBS;
+	c->main_lebs = *main_lebs - c->lpt_lebs;
+	if (c->main_lebs <= 0)
+		return -EINVAL;
+
+	/* And assume we will use the small LPT model */
+	c->big_lpt = 0;
+
+	/*
+	 * Calculate the geometry based on assumptions above and then see if it
+	 * makes sense
+	 */
+	do_calc_lpt_geom(c);
+
+	/* Small LPT model must have lpt_sz < leb_size */
+	if (c->lpt_sz > c->leb_size) {
+		/* Nope, so try again using big LPT model */
+		c->big_lpt = 1;
+		do_calc_lpt_geom(c);
+	}
+
+	/* Now check there are enough LPT LEBs */
+	for (i = 0; i < 64 ; i++) {
+		sz = c->lpt_sz * 4; /* Allow 4 times the size */
+		sz += c->leb_size - 1;
+		do_div(sz, c->leb_size);
+		lebs_needed = sz;
+		if (lebs_needed > c->lpt_lebs) {
+			/* Not enough LPT LEBs so try again with more */
+			c->lpt_lebs = lebs_needed;
+			c->main_lebs = *main_lebs - c->lpt_lebs;
+			if (c->main_lebs <= 0)
+				return -EINVAL;
+			do_calc_lpt_geom(c);
+			continue;
+		}
+		if (c->ltab_sz > c->leb_size) {
+			err_msg("LPT ltab too big");
+			return -EINVAL;
+		}
+		*main_lebs = c->main_lebs;
+		*big_lpt = c->big_lpt;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+/**
+ * pack_bits - pack bit fields end-to-end.
+ * @addr: address at which to pack (passed and next address returned)
+ * @pos: bit position at which to pack (passed and next position returned)
+ * @val: value to pack
+ * @nrbits: number of bits of value to pack (1-32)
+ */
+static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
+{
+	uint8_t *p = *addr;
+	int b = *pos;
+
+	if (b) {
+		*p |= ((uint8_t)val) << b;
+		nrbits += b;
+		if (nrbits > 8) {
+			*++p = (uint8_t)(val >>= (8 - b));
+			if (nrbits > 16) {
+				*++p = (uint8_t)(val >>= 8);
+				if (nrbits > 24) {
+					*++p = (uint8_t)(val >>= 8);
+					if (nrbits > 32)
+						*++p = (uint8_t)(val >>= 8);
+				}
+			}
+		}
+	} else {
+		*p = (uint8_t)val;
+		if (nrbits > 8) {
+			*++p = (uint8_t)(val >>= 8);
+			if (nrbits > 16) {
+				*++p = (uint8_t)(val >>= 8);
+				if (nrbits > 24)
+					*++p = (uint8_t)(val >>= 8);
+			}
+		}
+	}
+	b = nrbits & 7;
+	if (b == 0)
+		p++;
+	*addr = p;
+	*pos = b;
+}
+
+/**
+ * pack_pnode - pack all the bit fields of a pnode.
+ * @c: UBIFS file-system description object
+ * @buf: buffer into which to pack
+ * @pnode: pnode to pack
+ */
+static void pack_pnode(struct ubifs_info *c, void *buf,
+		       struct ubifs_pnode *pnode)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0;
+	uint16_t crc;
+
+	pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
+	if (c->big_lpt)
+		pack_bits(&addr, &pos, pnode->num, c->pcnt_bits);
+	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
+		pack_bits(&addr, &pos, pnode->lprops[i].free >> 3,
+			  c->space_bits);
+		pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3,
+			  c->space_bits);
+		if (pnode->lprops[i].flags & LPROPS_INDEX)
+			pack_bits(&addr, &pos, 1, 1);
+		else
+			pack_bits(&addr, &pos, 0, 1);
+	}
+	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
+		    c->pnode_sz - UBIFS_LPT_CRC_BYTES);
+	addr = buf;
+	pos = 0;
+	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+}
+
+/**
+ * pack_nnode - pack all the bit fields of a nnode.
+ * @c: UBIFS file-system description object
+ * @buf: buffer into which to pack
+ * @nnode: nnode to pack
+ */
+static void pack_nnode(struct ubifs_info *c, void *buf,
+		       struct ubifs_nnode *nnode)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0;
+	uint16_t crc;
+
+	pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
+	if (c->big_lpt)
+		pack_bits(&addr, &pos, nnode->num, c->pcnt_bits);
+	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
+		int lnum = nnode->nbranch[i].lnum;
+
+		if (lnum == 0)
+			lnum = c->lpt_last + 1;
+		pack_bits(&addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
+		pack_bits(&addr, &pos, nnode->nbranch[i].offs,
+			  c->lpt_offs_bits);
+	}
+	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
+		    c->nnode_sz - UBIFS_LPT_CRC_BYTES);
+	addr = buf;
+	pos = 0;
+	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+}
+
+/**
+ * pack_ltab - pack the LPT's own lprops table.
+ * @c: UBIFS file-system description object
+ * @buf: buffer into which to pack
+ * @ltab: LPT's own lprops table to pack
+ */
+static void pack_ltab(struct ubifs_info *c, void *buf,
+			 struct ubifs_lpt_lprops *ltab)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0;
+	uint16_t crc;
+
+	pack_bits(&addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
+	for (i = 0; i < c->lpt_lebs; i++) {
+		pack_bits(&addr, &pos, ltab[i].free, c->lpt_spc_bits);
+		pack_bits(&addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
+	}
+	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
+		    c->ltab_sz - UBIFS_LPT_CRC_BYTES);
+	addr = buf;
+	pos = 0;
+	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+}
+
+/**
+ * pack_lsave - pack the LPT's save table.
+ * @c: UBIFS file-system description object
+ * @buf: buffer into which to pack
+ * @lsave: LPT's save table to pack
+ */
+static void pack_lsave(struct ubifs_info *c, void *buf, int *lsave)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0;
+	uint16_t crc;
+
+	pack_bits(&addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
+	for (i = 0; i < c->lsave_cnt; i++)
+		pack_bits(&addr, &pos, lsave[i], c->lnum_bits);
+	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
+		    c->lsave_sz - UBIFS_LPT_CRC_BYTES);
+	addr = buf;
+	pos = 0;
+	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+}
+
+/**
+ * set_ltab - set LPT LEB properties.
+ * @c: UBIFS file-system description object
+ * @lnum: LEB number
+ * @free: amount of free space
+ * @dirty: amount of dirty space
+ */
+static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
+{
+	dbg_msg(3, "LEB %d free %d dirty %d to %d %d",
+		lnum, c->ltab[lnum - c->lpt_first].free,
+		c->ltab[lnum - c->lpt_first].dirty, free, dirty);
+	c->ltab[lnum - c->lpt_first].free = free;
+	c->ltab[lnum - c->lpt_first].dirty = dirty;
+}
+
+/**
+ * calc_nnode_num - calculate nnode number.
+ * @row: the row in the tree (root is zero)
+ * @col: the column in the row (leftmost is zero)
+ *
+ * The nnode number is a number that uniquely identifies a nnode and can be used
+ * easily to traverse the tree from the root to that nnode.
+ *
+ * This function calculates and returns the nnode number for the nnode at @row
+ * and @col.
+ */
+static int calc_nnode_num(int row, int col)
+{
+	int num, bits;
+
+	num = 1;
+	while (row--) {
+		bits = (col & (UBIFS_LPT_FANOUT - 1));
+		col >>= UBIFS_LPT_FANOUT_SHIFT;
+		num <<= UBIFS_LPT_FANOUT_SHIFT;
+		num |= bits;
+	}
+	return num;
+}
+
+/**
+ * create_lpt - create LPT.
+ * @c: UBIFS file-system description object
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int create_lpt(struct ubifs_info *c)
+{
+	int lnum, err = 0, i, j, cnt, len, alen, row;
+	int blnum, boffs, bsz, bcnt;
+	struct ubifs_pnode *pnode = NULL;
+	struct ubifs_nnode *nnode = NULL;
+	void *buf = NULL, *p;
+	int *lsave = NULL;
+
+	pnode = malloc(sizeof(struct ubifs_pnode));
+	nnode = malloc(sizeof(struct ubifs_nnode));
+	buf = malloc(c->leb_size);
+	lsave = malloc(sizeof(int) * c->lsave_cnt);
+	if (!pnode || !nnode || !buf || !lsave) {
+		err = -ENOMEM;
+		goto out;
+	}
+	memset(pnode, 0 , sizeof(struct ubifs_pnode));
+	memset(nnode, 0 , sizeof(struct ubifs_nnode));
+
+	c->lscan_lnum = c->main_first;
+
+	lnum = c->lpt_first;
+	p = buf;
+	len = 0;
+	/* Number of leaf nodes (pnodes) */
+	cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) >> UBIFS_LPT_FANOUT_SHIFT;
+	//printf("pnode_cnt=%d\n",cnt);
+
+	/*
+	 * To calculate the internal node branches, we keep information about
+	 * the level below.
+	 */
+	blnum = lnum; /* LEB number of level below */
+	boffs = 0; /* Offset of level below */
+	bcnt = cnt; /* Number of nodes in level below */
+	bsz = c->pnode_sz; /* Size of nodes in level below */
+
+	/* Add pnodes */
+	for (i = 0; i < cnt; i++) {
+		if (len + c->pnode_sz > c->leb_size) {
+			alen = ALIGN(len, c->min_io_size);
+			set_ltab(c, lnum, c->leb_size - alen, alen - len);
+			memset(p, 0xff, alen - len);
+			err = write_leb(c, lnum++, alen, buf);
+			if (err)
+				goto out;
+			p = buf;
+			len = 0;
+		}
+		/* Fill in the pnode */
+		for (j = 0; j < UBIFS_LPT_FANOUT; j++) {
+			int k = (i << UBIFS_LPT_FANOUT_SHIFT) + j;
+
+			if (k < c->main_lebs)
+				pnode->lprops[j] = c->lpt[k];
+			else {
+				pnode->lprops[j].free = c->leb_size;
+				pnode->lprops[j].dirty = 0;
+				pnode->lprops[j].flags = 0;
+			}
+		}
+		pack_pnode(c, p, pnode);
+		p += c->pnode_sz;
+		len += c->pnode_sz;
+		/*
+		 * pnodes are simply numbered left to right starting at zero,
+		 * which means the pnode number can be used easily to traverse
+		 * down the tree to the corresponding pnode.
+		 */
+		pnode->num += 1;
+	}
+
+	row = c->lpt_hght - 1;
+	/* Add all nnodes, one level at a time */
+	while (1) {
+		/* Number of internal nodes (nnodes) at next level */
+		cnt = (cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
+		if (cnt == 0)
+			cnt = 1;
+		for (i = 0; i < cnt; i++) {
+			if (len + c->nnode_sz > c->leb_size) {
+				alen = ALIGN(len, c->min_io_size);
+				set_ltab(c, lnum, c->leb_size - alen,
+					    alen - len);
+				memset(p, 0xff, alen - len);
+				err = write_leb(c, lnum++, alen, buf);
+				if (err)
+					goto out;
+				p = buf;
+				len = 0;
+			}
+			/* The root is on row zero */
+			if (row == 0) {
+				c->lpt_lnum = lnum;
+				c->lpt_offs = len;
+			}
+			/* Set branches to the level below */
+			for (j = 0; j < UBIFS_LPT_FANOUT; j++) {
+				if (bcnt) {
+					if (boffs + bsz > c->leb_size) {
+						blnum += 1;
+						boffs = 0;
+					}
+					nnode->nbranch[j].lnum = blnum;
+					nnode->nbranch[j].offs = boffs;
+					boffs += bsz;
+					bcnt--;
+				} else {
+					nnode->nbranch[j].lnum = 0;
+					nnode->nbranch[j].offs = 0;
+				}
+			}
+			nnode->num = calc_nnode_num(row, i);
+			pack_nnode(c, p, nnode);
+			p += c->nnode_sz;
+			len += c->nnode_sz;
+		}
+		/* Row zero  is the top row */
+		if (row == 0)
+			break;
+		/* Update the information about the level below */
+		bcnt = cnt;
+		bsz = c->nnode_sz;
+		row -= 1;
+	}
+
+	if (c->big_lpt) {
+		/* Need to add LPT's save table */
+		if (len + c->lsave_sz > c->leb_size) {
+			alen = ALIGN(len, c->min_io_size);
+			set_ltab(c, lnum, c->leb_size - alen, alen - len);
+			memset(p, 0xff, alen - len);
+			err = write_leb(c, lnum++, alen, buf);
+			if (err)
+				goto out;
+			p = buf;
+			len = 0;
+		}
+
+		c->lsave_lnum = lnum;
+		c->lsave_offs = len;
+
+		for (i = 0; i < c->lsave_cnt; i++)
+			lsave[i] = c->main_first + i;
+
+		pack_lsave(c, p, lsave);
+		p += c->lsave_sz;
+		len += c->lsave_sz;
+	}
+
+	/* Need to add LPT's own LEB properties table */
+	if (len + c->ltab_sz > c->leb_size) {
+		alen = ALIGN(len, c->min_io_size);
+		set_ltab(c, lnum, c->leb_size - alen, alen - len);
+		memset(p, 0xff, alen - len);
+		err = write_leb(c, lnum++, alen, buf);
+		if (err)
+			goto out;
+		p = buf;
+		len = 0;
+	}
+
+	c->ltab_lnum = lnum;
+	c->ltab_offs = len;
+
+	/* Update ltab before packing it */
+	len += c->ltab_sz;
+	alen = ALIGN(len, c->min_io_size);
+	set_ltab(c, lnum, c->leb_size - alen, alen - len);
+
+	pack_ltab(c, p, c->ltab);
+	p += c->ltab_sz;
+
+	/* Write remaining buffer */
+	memset(p, 0xff, alen - len);
+	err = write_leb(c, lnum, alen, buf);
+	if (err)
+		goto out;
+
+	c->nhead_lnum = lnum;
+	c->nhead_offs = ALIGN(len, c->min_io_size);
+
+	dbg_msg(1, "lpt_sz:         %lld", c->lpt_sz);
+	dbg_msg(1, "space_bits:     %d", c->space_bits);
+	dbg_msg(1, "lpt_lnum_bits:  %d", c->lpt_lnum_bits);
+	dbg_msg(1, "lpt_offs_bits:  %d", c->lpt_offs_bits);
+	dbg_msg(1, "lpt_spc_bits:   %d", c->lpt_spc_bits);
+	dbg_msg(1, "pcnt_bits:      %d", c->pcnt_bits);
+	dbg_msg(1, "lnum_bits:      %d", c->lnum_bits);
+	dbg_msg(1, "pnode_sz:       %d", c->pnode_sz);
+	dbg_msg(1, "nnode_sz:       %d", c->nnode_sz);
+	dbg_msg(1, "ltab_sz:        %d", c->ltab_sz);
+	dbg_msg(1, "lsave_sz:       %d", c->lsave_sz);
+	dbg_msg(1, "lsave_cnt:      %d", c->lsave_cnt);
+	dbg_msg(1, "lpt_hght:       %d", c->lpt_hght);
+	dbg_msg(1, "big_lpt:        %d", c->big_lpt);
+	dbg_msg(1, "LPT root is at  %d:%d", c->lpt_lnum, c->lpt_offs);
+	dbg_msg(1, "LPT head is at  %d:%d", c->nhead_lnum, c->nhead_offs);
+	dbg_msg(1, "LPT ltab is at  %d:%d", c->ltab_lnum, c->ltab_offs);
+	if (c->big_lpt)
+		dbg_msg(1, "LPT lsave is at %d:%d",
+		        c->lsave_lnum, c->lsave_offs);
+out:
+	free(lsave);
+	free(buf);
+	free(nnode);
+	free(pnode);
+	return err;
+}
diff --git a/ubifs-utils/mkfs.ubifs/COPYING b/ubifs-utils/mkfs.ubifs/COPYING
deleted file mode 100644
index 60549be..0000000
--- a/ubifs-utils/mkfs.ubifs/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-\f
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/ubifs-utils/mkfs.ubifs/README b/ubifs-utils/mkfs.ubifs/README
deleted file mode 100644
index 7e19939..0000000
--- a/ubifs-utils/mkfs.ubifs/README
+++ /dev/null
@@ -1,9 +0,0 @@
-UBIFS File System - Make File System program
-
-* crc16.h and crc16.c were copied from the linux kernel.
-* crc32.h and crc32.c were copied from mtd-utils and amended.
-* ubifs.h is a selection of definitions from fs/ubifs/ubifs.h from the linux kernel.
-* key.h is copied from fs/ubifs/key.h from the linux kernel.
-* defs.h is a bunch of definitions to smooth things over.
-* lpt.c is a selection of functions copied from fs/ubifs/lpt.c from the linux kernel, and amended.
-* hashtable/* was downloaded from http://www.cl.cam.ac.uk/~cwc22/hashtable/
diff --git a/ubifs-utils/mkfs.ubifs/compr.c b/ubifs-utils/mkfs.ubifs/compr.c
deleted file mode 100644
index 4603f5c..0000000
--- a/ubifs-utils/mkfs.ubifs/compr.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation.
- * Copyright (C) 2008 University of Szeged, Hungary
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy
- *          Adrian Hunter
- *          Zoltan Sogor
- */
-
-#include "ubifs_common.h"
-
-#ifndef WITHOUT_LZO
-#include <lzo/lzo1x.h>
-#endif
-
-#define crc32 __zlib_crc32
-#include <zlib.h>
-#undef crc32
-
-#include "compr.h"
-
-static void *lzo_mem;
-static unsigned long long errcnt = 0;
-
-#define DEFLATE_DEF_LEVEL     Z_DEFAULT_COMPRESSION
-#define DEFLATE_DEF_WINBITS   11
-#define DEFLATE_DEF_MEMLEVEL  8
-
-static int zlib_deflate(void *in_buf, size_t in_len, void *out_buf,
-			size_t *out_len)
-{
-	z_stream strm;
-
-	strm.zalloc = NULL;
-	strm.zfree = NULL;
-
-	/*
-	 * Match exactly the zlib parameters used by the Linux kernel crypto
-	 * API.
-	 */
-        if (deflateInit2(&strm, DEFLATE_DEF_LEVEL, Z_DEFLATED,
-			 -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
-			 Z_DEFAULT_STRATEGY)) {
-		errcnt += 1;
-		return -1;
-	}
-
-	strm.next_in = in_buf;
-	strm.avail_in = in_len;
-	strm.total_in = 0;
-
-	strm.next_out = out_buf;
-	strm.avail_out = *out_len;
-	strm.total_out = 0;
-
-	if (deflate(&strm, Z_FINISH) != Z_STREAM_END) {
-		deflateEnd(&strm);
-		errcnt += 1;
-		return -1;
-	}
-
-	if (deflateEnd(&strm) != Z_OK) {
-		errcnt += 1;
-		return -1;
-	}
-
-	*out_len = strm.total_out;
-
-	return 0;
-}
-
-#ifndef WITHOUT_LZO
-static int lzo_compress(void *in_buf, size_t in_len, void *out_buf,
-			size_t *out_len)
-{
-	lzo_uint len;
-	int ret;
-
-	len = *out_len;
-	ret = lzo1x_999_compress(in_buf, in_len, out_buf, &len, lzo_mem);
-	*out_len = len;
-
-	if (ret != LZO_E_OK) {
-		errcnt += 1;
-		return -1;
-	}
-
-	return 0;
-}
-#endif
-
-static int no_compress(void *in_buf, size_t in_len, void *out_buf,
-		       size_t *out_len)
-{
-	memcpy(out_buf, in_buf, in_len);
-	*out_len = in_len;
-	return 0;
-}
-
-static char *zlib_buf;
-
-#ifndef WITHOUT_LZO
-static int favor_lzo_compress(void *in_buf, size_t in_len, void *out_buf,
-				size_t *out_len, int *type, int lzo_percent)
-{
-	int lzo_ret, zlib_ret;
-	size_t lzo_len, zlib_len;
-
-	lzo_len = zlib_len = *out_len;
-	lzo_ret = lzo_compress(in_buf, in_len, out_buf, &lzo_len);
-	zlib_ret = zlib_deflate(in_buf, in_len, zlib_buf, &zlib_len);
-
-	if (lzo_ret && zlib_ret)
-		/* Both compressors failed */
-		return -1;
-
-	if (!lzo_ret && !zlib_ret) {
-		double percent;
-
-		/* Both compressors succeeded */
-		if (lzo_len <= zlib_len )
-			goto select_lzo;
-
-		percent = (double)zlib_len / (double)lzo_len;
-		percent *= 100;
-		if (percent > 100 - lzo_percent)
-			goto select_lzo;
-		goto select_zlib;
-	}
-
-	if (lzo_ret)
-		/* Only zlib compressor succeeded */
-		goto select_zlib;
-
-	/* Only LZO compressor succeeded */
-
-select_lzo:
-	*out_len = lzo_len;
-	*type = MKFS_UBIFS_COMPR_LZO;
-	return 0;
-
-select_zlib:
-	*out_len = zlib_len;
-	*type = MKFS_UBIFS_COMPR_ZLIB;
-	memcpy(out_buf, zlib_buf, zlib_len);
-	return 0;
-}
-#endif
-
-int compress_data(void *in_buf, size_t in_len, void *out_buf,
-		size_t *out_len, int type, int lzo_percent)
-{
-	int ret;
-
-	if (in_len < UBIFS_MIN_COMPR_LEN) {
-		no_compress(in_buf, in_len, out_buf, out_len);
-		return MKFS_UBIFS_COMPR_NONE;
-	}
-
-#ifdef WITHOUT_LZO
-	{
-		switch (type) {
-#else
-	if (lzo_percent)
-		ret = favor_lzo_compress(in_buf, in_len, out_buf, out_len, &type, lzo_percent);
-	else {
-		switch (type) {
-		case MKFS_UBIFS_COMPR_LZO:
-			ret = lzo_compress(in_buf, in_len, out_buf, out_len);
-			break;
-#endif
-		case MKFS_UBIFS_COMPR_ZLIB:
-			ret = zlib_deflate(in_buf, in_len, out_buf, out_len);
-			break;
-		case MKFS_UBIFS_COMPR_NONE:
-			ret = 1;
-			break;
-		default:
-			errcnt += 1;
-			ret = 1;
-			break;
-		}
-	}
-	if (ret || *out_len >= in_len) {
-		no_compress(in_buf, in_len, out_buf, out_len);
-		return MKFS_UBIFS_COMPR_NONE;
-	}
-	return type;
-}
-
-int init_compression(void)
-{
-#ifdef WITHOUT_LZO
-	lzo_mem = NULL;
-#else
-	lzo_mem = malloc(LZO1X_999_MEM_COMPRESS);
-	if (!lzo_mem)
-		return -1;
-#endif
-
-	zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR);
-	if (!zlib_buf) {
-		free(lzo_mem);
-		return -1;
-	}
-
-	return 0;
-}
-
-void destroy_compression(void)
-{
-	free(zlib_buf);
-	free(lzo_mem);
-	if (errcnt)
-		fprintf(stderr, "%llu compression errors occurred\n", errcnt);
-}
diff --git a/ubifs-utils/mkfs.ubifs/compr.h b/ubifs-utils/mkfs.ubifs/compr.h
deleted file mode 100644
index d44a2ba..0000000
--- a/ubifs-utils/mkfs.ubifs/compr.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation.
- * Copyright (C) 2008 University of Szeged, Hungary
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy
- *          Adrian Hunter
- *          Zoltan Sogor
- */
-
-#ifndef __UBIFS_COMPRESS_H__
-#define __UBIFS_COMPRESS_H__
-
-/*
- * Compressors may end-up with more data in the output buffer than in the input
- * buffer. This constant defined the worst case factor, i.e. we assume that the
- * output buffer may be at max. WORST_COMPR_FACTOR times larger than input
- * buffer.
- */
-#define WORST_COMPR_FACTOR 4
-
-enum compression_type
-{
-	MKFS_UBIFS_COMPR_NONE,
-	MKFS_UBIFS_COMPR_LZO,
-	MKFS_UBIFS_COMPR_ZLIB,
-};
-
-int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len, int type, int lzo_percent);
-int init_compression(void);
-void destroy_compression(void);
-
-#endif
diff --git a/ubifs-utils/mkfs.ubifs/crc16.c b/ubifs-utils/mkfs.ubifs/crc16.c
deleted file mode 100644
index a19512e..0000000
--- a/ubifs-utils/mkfs.ubifs/crc16.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This code was taken from the linux kernel. The license is GPL Version 2.
- */
-
-#include "crc16.h"
-
-/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
-uint16_t const crc16_table[256] = {
-	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
-	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
-	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
-	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
-	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
-	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
-	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
-	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
-	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
-	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
-	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
-	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
-	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
-	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
-	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
-	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
-	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
-	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
-	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
-	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
-	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
-	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
-	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
-	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
-	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
-	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
-	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
-	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
-	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
-	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
-	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
-	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
-};
-
-/**
- * crc16 - compute the CRC-16 for the data buffer
- * @crc:	previous CRC value
- * @buffer:	data pointer
- * @len:	number of bytes in the buffer
- *
- * Returns the updated CRC value.
- */
-uint16_t crc16(uint16_t crc, uint8_t const *buffer, size_t len)
-{
-	while (len--)
-		crc = crc16_byte(crc, *buffer++);
-	return crc;
-}
diff --git a/ubifs-utils/mkfs.ubifs/crc16.h b/ubifs-utils/mkfs.ubifs/crc16.h
deleted file mode 100644
index 539d21a..0000000
--- a/ubifs-utils/mkfs.ubifs/crc16.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Implements the standard CRC-16:
- *   Width 16
- *   Poly  0x8005 (x^16 + x^15 + x^2 + 1)
- *   Init  0
- *
- * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
- *
- * This code was taken from the linux kernel. The license is GPL Version 2.
- */
-
-#ifndef __CRC16_H__
-#define __CRC16_H__
-
-#include <stdlib.h>
-#include <stdint.h>
-
-extern uint16_t const crc16_table[256];
-
-extern uint16_t crc16(uint16_t crc, const uint8_t *buffer, size_t len);
-
-static inline uint16_t crc16_byte(uint16_t crc, const uint8_t data)
-{
-	return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
-}
-
-#endif /* __CRC16_H__ */
diff --git a/ubifs-utils/mkfs.ubifs/defs.h b/ubifs-utils/mkfs.ubifs/defs.h
deleted file mode 100644
index 1fa3316..0000000
--- a/ubifs-utils/mkfs.ubifs/defs.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Greate deal of the code was taken from the kernel UBIFS implementation, and
- * this file contains some "glue" definitions.
- */
-
-#ifndef __UBIFS_DEFS_H__
-#define __UBIFS_DEFS_H__
-
-#define t16(x) ({ \
-	uint16_t __b = (x); \
-	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_16(__b); \
-})
-
-#define t32(x) ({ \
-	uint32_t __b = (x); \
-	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_32(__b); \
-})
-
-#define t64(x) ({ \
-	uint64_t __b = (x); \
-	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_64(__b); \
-})
-
-#define cpu_to_le16(x) ((__le16){t16(x)})
-#define cpu_to_le32(x) ((__le32){t32(x)})
-#define cpu_to_le64(x) ((__le64){t64(x)})
-
-#define le16_to_cpu(x) (t16((x)))
-#define le32_to_cpu(x) (t32((x)))
-#define le64_to_cpu(x) (t64((x)))
-
-#define unlikely(x) (x)
-
-#define ubifs_assert(x) ({})
-
-struct qstr
-{
-	char *name;
-	size_t len;
-};
-
-/**
- * fls - find last (most-significant) bit set
- * @x: the word to search
- *
- * This is defined the same way as ffs.
- * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
- */
-static inline int fls(int x)
-{
-	int r = 32;
-
-	if (!x)
-		return 0;
-	if (!(x & 0xffff0000u)) {
-		x <<= 16;
-		r -= 16;
-	}
-	if (!(x & 0xff000000u)) {
-		x <<= 8;
-		r -= 8;
-	}
-	if (!(x & 0xf0000000u)) {
-		x <<= 4;
-		r -= 4;
-	}
-	if (!(x & 0xc0000000u)) {
-		x <<= 2;
-		r -= 2;
-	}
-	if (!(x & 0x80000000u)) {
-		x <<= 1;
-		r -= 1;
-	}
-	return r;
-}
-
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
-#if INT_MAX != 0x7fffffff
-#error : sizeof(int) must be 4 for this program
-#endif
-
-#if (~0ULL) != 0xffffffffffffffffULL
-#error : sizeof(long long) must be 8 for this program
-#endif
-
-#endif
diff --git a/ubifs-utils/mkfs.ubifs/devtable.c b/ubifs-utils/mkfs.ubifs/devtable.c
deleted file mode 100644
index 1fc0256..0000000
--- a/ubifs-utils/mkfs.ubifs/devtable.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: Artem Bityutskiy
- *
- * Part of the device table parsing code was taken from the mkfs.jffs2 utility.
- * The original author of that code is Erik Andersen, hence:
- *	Copyright (C) 2001, 2002 Erik Andersen <andersen@codepoet.org>
- */
-
-/*
- * This file implemented device table support. Device table entries take the
- * form of:
- * <path>    <type> <mode> <uid> <gid> <major> <minor> <start>	<inc> <count>
- * /dev/mem  c       640   0     0     1       1       0        0     -
- *
- * Type can be one of:
- * f  A regular file
- * d  Directory
- * c  Character special device file
- * b  Block special device file
- * p  Fifo (named pipe)
- *
- * Don't bother with symlinks (permissions are irrelevant), hard links (special
- * cases of regular files), or sockets (why bother).
- *
- * Regular files must exist in the target root directory. If a char, block,
- * fifo, or directory does not exist, it will be created.
- *
- * Please, refer the device_table.txt file which can be found at MTD utilities
- * for more information about what the device table is.
- */
-
-#include "ubifs_common.h"
-#include "devtable.h"
-#include "hashtable/hashtable.h"
-#include "hashtable/hashtable_itr.h"
-
-/*
- * The hash table which contains paths to files/directories/device nodes
- * referred to in the device table. For example, if the device table refers
- * "/dev/loop0", the @path_htbl will contain "/dev" element.
- */
-static struct hashtable *path_htbl;
-
-/* Hash function used for hash tables */
-static unsigned int r5_hash(void *s)
-{
-	unsigned int a = 0;
-	const signed char *str = s;
-
-	while (*str) {
-		a += *str << 4;
-		a += *str >> 4;
-		a *= 11;
-		str++;
-	}
-
-	return a;
-}
-
-/*
- * Check whether 2 keys of a hash table are equivalent. The keys are path/file
- * names, so we simply use 'strcmp()'.
- */
-static int is_equivalent(void *k1, void *k2)
-{
-	return !strcmp(k1, k2);
-}
-
-/**
- * separate_last - separate out the last path component
- * @buf: the path to split
- * @len: length of the @buf string
- * @path: the beginning of path is returned here
- * @name: the last path component is returned here
- *
- * This helper function separates out the the last component of the full path
- * string. For example, "/dev/loop" would be split on "/dev" and "loop". This
- * function allocates memory for @path and @name and return the result there.
- * Returns zero in case of success and a negative error code in case of
- * failure.
- */
-static int separate_last(const char *buf, int len, char **path, char **name)
-{
-	int path_len = len, name_len;
-	const char *p = buf + len, *n;
-
-	while (*--p != '/')
-		path_len -= 1;
-
-	/* Drop the final '/' unless this is the root directory */
-	name_len = len - path_len;
-	n = buf + path_len;
-	if (path_len > 1)
-		path_len -= 1;
-
-	*path = malloc(path_len + 1);
-	if (!*path)
-		return err_msg("cannot allocate %d bytes of memory",
-			       path_len + 1);
-	memcpy(*path, buf, path_len);
-	(*path)[path_len] = '\0';
-
-	*name = malloc(name_len + 1);
-	if (!*name) {
-		free(*path);
-		return err_msg("cannot allocate %d bytes of memory",
-			       name_len + 1);
-	}
-	memcpy(*name, n, name_len + 1);
-
-	return 0;
-}
-
-static int interpret_table_entry(const char *line)
-{
-	char buf[1024], type, *path = NULL, *name = NULL;
-	int len;
-	struct path_htbl_element *ph_elt = NULL;
-	struct name_htbl_element *nh_elt = NULL;
-	unsigned int mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;
-	unsigned int start = 0, increment = 0, count = 0;
-
-	if (sscanf(line, "%1023s %c %o %u %u %u %u %u %u %u",
-		   buf, &type, &mode, &uid, &gid, &major, &minor,
-		   &start, &increment, &count) < 0)
-		return sys_err_msg("sscanf failed");
-
-	dbg_msg(3, "name %s, type %c, mode %o, uid %u, gid %u, major %u, "
-		"minor %u, start %u, inc %u, cnt %u",
-		buf, type, mode, uid, gid, major, minor, start,
-		increment, count);
-
-	len = strnlen(buf, 1024);
-	if (len == 1024)
-		return err_msg("too long path");
-
-	if (!strcmp(buf, "/"))
-		return err_msg("device table entries require absolute paths");
-	if (buf[1] == '\0')
-		return err_msg("root directory cannot be created");
-	if (strstr(buf, "//"))
-		return err_msg("'//' cannot be used in the path");
-	if (buf[len - 1] == '/')
-		return err_msg("do not put '/' at the end");
-
-	if (strstr(buf, "/./") || strstr(buf, "/../") ||
-	    !strcmp(buf + len - 2, "/.") || !strcmp(buf + len - 3, "/.."))
-		return err_msg("'.' and '..' cannot be used in the path");
-
-	switch (type) {
-		case 'd':
-			mode |= S_IFDIR;
-			break;
-		case 'f':
-			mode |= S_IFREG;
-			break;
-		case 'p':
-			mode |= S_IFIFO;
-			break;
-		case 'c':
-			mode |= S_IFCHR;
-			break;
-		case 'b':
-			mode |= S_IFBLK;
-			break;
-		default:
-			return err_msg("unsupported file type '%c'", type);
-	}
-
-	if (separate_last(buf, len, &path, &name))
-		return -1;
-
-	/*
-	 * Check if this path already exist in the path hash table and add it
-	 * if it is not.
-	 */
-	ph_elt = hashtable_search(path_htbl, path);
-	if (!ph_elt) {
-		dbg_msg(3, "inserting '%s' into path hash table", path);
-		ph_elt = malloc(sizeof(struct path_htbl_element));
-		if (!ph_elt) {
-			err_msg("cannot allocate %zd bytes of memory",
-				sizeof(struct path_htbl_element));
-			goto out_free;
-		}
-
-		if (!hashtable_insert(path_htbl, path, ph_elt)) {
-			err_msg("cannot insert into path hash table");
-			goto out_free;
-		}
-
-		ph_elt->path = path;
-		path = NULL;
-		ph_elt->name_htbl = create_hashtable(128, &r5_hash,
-						     &is_equivalent);
-		if (!ph_elt->name_htbl) {
-			err_msg("cannot create name hash table");
-			goto out_free;
-		}
-	}
-
-	if (increment != 0 && count == 0)
-		return err_msg("count cannot be zero if increment is non-zero");
-
-	/*
-	 * Add the file/directory/device node (last component of the path) to
-	 * the name hashtable. The name hashtable resides in the corresponding
-	 * path hashtable element.
-	 */
-
-	if (count == 0) {
-		/* This entry does not require any iterating */
-		nh_elt = malloc(sizeof(struct name_htbl_element));
-		if (!nh_elt) {
-			err_msg("cannot allocate %zd bytes of memory",
-				sizeof(struct name_htbl_element));
-			goto out_free;
-		}
-
-		nh_elt->mode = mode;
-		nh_elt->uid = uid;
-		nh_elt->gid = gid;
-		nh_elt->dev = makedev(major, minor);
-
-		dbg_msg(3, "inserting '%s' into name hash table (major %d, minor %d)",
-			name, major(nh_elt->dev), minor(nh_elt->dev));
-
-		if (hashtable_search(ph_elt->name_htbl, name))
-			return err_msg("'%s' is referred twice", buf);
-
-		nh_elt->name = name;
-		if (!hashtable_insert(ph_elt->name_htbl, name, nh_elt)) {
-			err_msg("cannot insert into name hash table");
-			goto out_free;
-		}
-	} else {
-		int i, num = start + count, len = strlen(name) + 20;
-		char *nm;
-
-		for (i = start; i < num; i++) {
-			nh_elt = malloc(sizeof(struct name_htbl_element));
-			if (!nh_elt) {
-				err_msg("cannot allocate %zd bytes of memory",
-					sizeof(struct name_htbl_element));
-				goto out_free;
-			}
-
-			nh_elt->mode = mode;
-			nh_elt->uid = uid;
-			nh_elt->gid = gid;
-			nh_elt->dev = makedev(major, minor + (i - start) * increment);
-
-			nm = malloc(len);
-			if (!nm) {
-				err_msg("cannot allocate %d bytes of memory", len);
-				goto out_free;
-			}
-
-			sprintf(nm, "%s%d", name, i);
-			nh_elt->name = nm;
-
-			dbg_msg(3, "inserting '%s' into name hash table (major %d, minor %d)",
-			        nm, major(nh_elt->dev), minor(nh_elt->dev));
-
-			if (hashtable_search(ph_elt->name_htbl, nm)) {
-				err_msg("'%s' is referred twice", buf);
-				free (nm);
-				goto out_free;
-			}
-
-			if (!hashtable_insert(ph_elt->name_htbl, nm, nh_elt)) {
-				err_msg("cannot insert into name hash table");
-				free (nm);
-				goto out_free;
-			}
-		}
-		free(name);
-		name = NULL;
-	}
-
-	return 0;
-
-out_free:
-	free(ph_elt);
-	free(nh_elt);
-	free(path);
-	free(name);
-	return -1;
-}
-
-/**
- * parse_devtable - parse the device table.
- * @tbl_file: device table file name
- *
- * This function parses the device table and prepare the hash table which will
- * later be used by mkfs.ubifs to create the specified files/device nodes.
- * Returns zero in case of success and a negative error code in case of
- * failure.
- */
-int parse_devtable(const char *tbl_file)
-{
-	FILE *f;
-	char *line = NULL;
-	struct stat st;
-	size_t len;
-
-	dbg_msg(1, "parsing device table file '%s'", tbl_file);
-
-	path_htbl = create_hashtable(128, &r5_hash, &is_equivalent);
-	if (!path_htbl)
-		return err_msg("cannot create path hash table");
-
-	f = fopen(tbl_file, "r");
-	if (!f)
-		return sys_err_msg("cannot open '%s'", tbl_file);
-
-	if (fstat(fileno(f), &st) < 0) {
-		sys_err_msg("cannot stat '%s'", tbl_file);
-		goto out_close;
-	}
-
-	if (st.st_size < 10) {
-		sys_err_msg("'%s' is too short", tbl_file);
-		goto out_close;
-	}
-
-	/*
-	 * The general plan now is to read in one line at a time, check for
-	 * leading comment delimiters ('#'), then try and parse the line as a
-	 * device table
-	 */
-	while (getline(&line, &len, f) != -1) {
-		/* First trim off any white-space */
-		len = strlen(line);
-
-		/* Trim trailing white-space */
-		while (len > 0 && isspace(line[len - 1]))
-			line[--len] = '\0';
-		/* Trim leading white-space */
-		memmove(line, &line[strspn(line, " \n\r\t\v")], len);
-
-		/* How long are we after trimming? */
-		len = strlen(line);
-
-		/* If this is not a comment line, try to interpret it */
-		if (len && *line != '#') {
-			if (interpret_table_entry(line)) {
-				err_msg("cannot parse '%s'", line);
-				goto out_close;
-			}
-		}
-
-		free(line);
-		line = NULL;
-	}
-
-	dbg_msg(1, "finished parsing");
-	fclose(f);
-	return 0;
-
-out_close:
-	fclose(f);
-	free_devtable_info();
-	return -1;
-}
-
-/**
- * devtbl_find_path - find a path in the path hash table.
- * @path: UBIFS path to find.
- *
- * This looks up the path hash table. Returns the path hash table element
- * reference if @path was found and %NULL if not.
- */
-struct path_htbl_element *devtbl_find_path(const char *path)
-{
-	if (!path_htbl)
-		return NULL;
-
-	return hashtable_search(path_htbl, (void *)path);
-}
-
-/**
- * devtbl_find_name - find a name in the name hash table.
- * @ph_etl: path hash table element to find at
- * @name: name to find
- *
- * This looks up the name hash table. Returns the name hash table element
- * reference if @name found and %NULL if not.
- */
-struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
-					   const char *name)
-{
-	if (!path_htbl)
-		return NULL;
-
-	return hashtable_search(ph_elt->name_htbl, (void *)name);
-}
-
-/**
- * override_attributes - override inode attributes.
- * @st: struct stat object to containing the attributes to override
- * @ph_elt: path hash table element object
- * @nh_elt: name hash table element object containing the new values
- *
- * The device table file may override attributes like UID of files. For
- * example, the device table may contain a "/dev" entry, and the UBIFS FS on
- * the host may contain "/dev" directory. In this case the attributes of the
- * "/dev" directory inode has to be as the device table specifies.
- *
- * Note, the hash element is removed by this function as well.
- */
-int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
-			struct name_htbl_element *nh_elt)
-{
-	if (!path_htbl)
-		return 0;
-
-	if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode) ||
-	    S_ISFIFO(st->st_mode))
-		return err_msg("%s/%s both exists at UBIFS root at host, "
-			       "and is referred from the device table",
-			       strcmp(ph_elt->path, "/") ? ph_elt->path : "",
-			       nh_elt->name);
-
-	if ((st->st_mode & S_IFMT) != (nh_elt->mode & S_IFMT))
-		return err_msg("%s/%s is referred from the device table also exists in "
-			       "the UBIFS root directory at host, but the file type is "
-			       "different", strcmp(ph_elt->path, "/") ? ph_elt->path : "",
-			       nh_elt->name);
-
-	dbg_msg(3, "set UID %d, GID %d, mode %o for %s/%s as device table says",
-		nh_elt->uid, nh_elt->gid, nh_elt->mode, ph_elt->path, nh_elt->name);
-
-	st->st_uid = nh_elt->uid;
-	st->st_gid = nh_elt->gid;
-	st->st_mode = nh_elt->mode;
-
-	hashtable_remove(ph_elt->name_htbl, (void *)nh_elt->name);
-	return 0;
-}
-
-/**
- * first_name_htbl_element - return first element of the name hash table.
- * @ph_elt: the path hash table the name hash table belongs to
- * @itr: double pointer to a 'struct hashtable_itr' object where the
- *       information about further iterations is stored
- *
- * This function implements name hash table iteration together with
- * 'next_name_htbl_element()'. Returns the first name hash table element or
- * %NULL if the hash table is empty.
- */
-struct name_htbl_element *
-first_name_htbl_element(struct path_htbl_element *ph_elt,
-			struct hashtable_itr **itr)
-{
-	if (!path_htbl || !ph_elt || hashtable_count(ph_elt->name_htbl) == 0)
-		return NULL;
-
-	*itr = hashtable_iterator(ph_elt->name_htbl);
-	return hashtable_iterator_value(*itr);
-}
-
-/**
- * first_name_htbl_element - return next element of the name hash table.
- * @ph_elt: the path hash table the name hash table belongs to
- * @itr: double pointer to a 'struct hashtable_itr' object where the
- *       information about further iterations is stored
- *
- * This function implements name hash table iteration together with
- * 'first_name_htbl_element()'. Returns the next name hash table element or
- * %NULL if there are no more elements.
- */
-struct name_htbl_element *
-next_name_htbl_element(struct path_htbl_element *ph_elt,
-		       struct hashtable_itr **itr)
-{
-	if (!path_htbl || !ph_elt || !hashtable_iterator_advance(*itr))
-		return NULL;
-
-	return hashtable_iterator_value(*itr);
-}
-
-/**
- * free_devtable_info - free device table information.
- *
- * This function frees the path hash table and the name hash tables.
- */
-void free_devtable_info(void)
-{
-	struct hashtable_itr *ph_itr;
-	struct path_htbl_element *ph_elt;
-
-	if (!path_htbl)
-		return;
-
-	if (hashtable_count(path_htbl) > 0) {
-		ph_itr = hashtable_iterator(path_htbl);
-		do {
-			ph_elt = hashtable_iterator_value(ph_itr);
-			/*
-			 * Note, since we use the same string for the key and
-			 * @name in the name hash table elements, we do not
-			 * have to iterate name hash table because @name memory
-			 * will be freed when freeing the key.
-			 */
-			hashtable_destroy(ph_elt->name_htbl, 1);
-		} while (hashtable_iterator_advance(ph_itr));
-	}
-	hashtable_destroy(path_htbl, 1);
-}
diff --git a/ubifs-utils/mkfs.ubifs/devtable.h b/ubifs-utils/mkfs.ubifs/devtable.h
deleted file mode 100644
index 987d4d4..0000000
--- a/ubifs-utils/mkfs.ubifs/devtable.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "ubifs_common.h"
-
-/**
- * struct path_htbl_element - an element of the path hash table.
- * @path: the UBIFS path the element describes (the key of the element)
- * @name_htbl: one more (nested) hash table containing names of all
- *             files/directories/device nodes which should be created at this
- *             path
- *
- * See device table handling for more information.
- */
-struct path_htbl_element {
-	const char *path;
-	struct hashtable *name_htbl;
-};
-
-/**
- * struct name_htbl_element - an element in the name hash table
- * @name: name of the file/directory/device node (the key of the element)
- * @mode: accsess rights and file type
- * @uid: user ID
- * @gid: group ID
- * @major: device node major number
- * @minor: device node minor number
- *
- * This is an element of the name hash table. Name hash table sits in the path
- * hash table elements and describes file names which should be created/changed
- * at this path.
- */
-struct name_htbl_element {
-	const char *name;
-	unsigned int mode;
-	unsigned int uid;
-	unsigned int gid;
-	dev_t dev;
-};
-
-extern struct ubifs_info info_;
-
-struct hashtable_itr;
-
-int parse_devtable(const char *tbl_file);
-struct path_htbl_element *devtbl_find_path(const char *path);
-struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
-					   const char *name);
-int override_attributes(struct stat *st, struct path_htbl_element *ph_elt,
-			struct name_htbl_element *nh_elt);
-struct name_htbl_element *
-first_name_htbl_element(struct path_htbl_element *ph_elt,
-			struct hashtable_itr **itr);
-struct name_htbl_element *
-next_name_htbl_element(struct path_htbl_element *ph_elt,
-			struct hashtable_itr **itr);
-void free_devtable_info(void);
-
diff --git a/ubifs-utils/mkfs.ubifs/hashtable/hashtable.c b/ubifs-utils/mkfs.ubifs/hashtable/hashtable.c
deleted file mode 100644
index c1f99ed..0000000
--- a/ubifs-utils/mkfs.ubifs/hashtable/hashtable.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-
-#define PROGRAM_NAME "hashtable"
-
-#include "common.h"
-#include "hashtable.h"
-#include "hashtable_private.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-/*
-Credit for primes table: Aaron Krowne
- http://br.endernet.org/~akrowne/
- http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
-*/
-static const unsigned int primes[] = {
-53, 97, 193, 389,
-769, 1543, 3079, 6151,
-12289, 24593, 49157, 98317,
-196613, 393241, 786433, 1572869,
-3145739, 6291469, 12582917, 25165843,
-50331653, 100663319, 201326611, 402653189,
-805306457, 1610612741
-};
-const unsigned int prime_table_length = ARRAY_SIZE(primes);
-const float max_load_factor = 0.65;
-
-/*****************************************************************************/
-struct hashtable *
-create_hashtable(unsigned int minsize,
-                 unsigned int (*hashf) (void*),
-                 int (*eqf) (void*,void*))
-{
-    struct hashtable *h;
-    unsigned int pindex, size = primes[0];
-    /* Check requested hashtable isn't too large */
-    if (minsize > (1u << 30)) return NULL;
-    /* Enforce size as prime */
-    for (pindex=0; pindex < prime_table_length; pindex++) {
-        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
-    }
-    h = (struct hashtable *)malloc(sizeof(struct hashtable));
-    if (NULL == h) return NULL; /*oom*/
-    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
-    if (NULL == h->table) { free(h); return NULL; } /*oom*/
-    memset(h->table, 0, size * sizeof(struct entry *));
-    h->tablelength  = size;
-    h->primeindex   = pindex;
-    h->entrycount   = 0;
-    h->hashfn       = hashf;
-    h->eqfn         = eqf;
-    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
-    return h;
-}
-
-/*****************************************************************************/
-unsigned int
-hash(struct hashtable *h, void *k)
-{
-    /* Aim to protect against poor hash functions by adding logic here
-     * - logic taken from java 1.4 hashtable source */
-    unsigned int i = h->hashfn(k);
-    i += ~(i << 9);
-    i ^=  ((i >> 14) | (i << 18)); /* >>> */
-    i +=  (i << 4);
-    i ^=  ((i >> 10) | (i << 22)); /* >>> */
-    return i;
-}
-
-/*****************************************************************************/
-static int
-hashtable_expand(struct hashtable *h)
-{
-    /* Double the size of the table to accomodate more entries */
-    struct entry **newtable;
-    struct entry *e;
-    struct entry **pE;
-    unsigned int newsize, i, index;
-    /* Check we're not hitting max capacity */
-    if (h->primeindex == (prime_table_length - 1)) return 0;
-    newsize = primes[++(h->primeindex)];
-
-    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
-    if (NULL != newtable)
-    {
-        memset(newtable, 0, newsize * sizeof(struct entry *));
-        /* This algorithm is not 'stable'. ie. it reverses the list
-         * when it transfers entries between the tables */
-        for (i = 0; i < h->tablelength; i++) {
-            while (NULL != (e = h->table[i])) {
-                h->table[i] = e->next;
-                index = indexFor(newsize,e->h);
-                e->next = newtable[index];
-                newtable[index] = e;
-            }
-        }
-        free(h->table);
-        h->table = newtable;
-    }
-    /* Plan B: realloc instead */
-    else
-    {
-        newtable = (struct entry **)
-                   realloc(h->table, newsize * sizeof(struct entry *));
-        if (NULL == newtable) { (h->primeindex)--; return 0; }
-        h->table = newtable;
-        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
-        for (i = 0; i < h->tablelength; i++) {
-            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
-                index = indexFor(newsize,e->h);
-                if (index == i)
-                {
-                    pE = &(e->next);
-                }
-                else
-                {
-                    *pE = e->next;
-                    e->next = newtable[index];
-                    newtable[index] = e;
-                }
-            }
-        }
-    }
-    h->tablelength = newsize;
-    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
-    return -1;
-}
-
-/*****************************************************************************/
-unsigned int
-hashtable_count(struct hashtable *h)
-{
-    return h->entrycount;
-}
-
-/*****************************************************************************/
-int
-hashtable_insert(struct hashtable *h, void *k, void *v)
-{
-    /* This method allows duplicate keys - but they shouldn't be used */
-    unsigned int index;
-    struct entry *e;
-    if (++(h->entrycount) > h->loadlimit)
-    {
-        /* Ignore the return value. If expand fails, we should
-         * still try cramming just this value into the existing table
-         * -- we may not have memory for a larger table, but one more
-         * element may be ok. Next time we insert, we'll try expanding again.*/
-        hashtable_expand(h);
-    }
-    e = (struct entry *)malloc(sizeof(struct entry));
-    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
-    e->h = hash(h,k);
-    index = indexFor(h->tablelength,e->h);
-    e->k = k;
-    e->v = v;
-    e->next = h->table[index];
-    h->table[index] = e;
-    return -1;
-}
-
-/*****************************************************************************/
-void * /* returns value associated with key */
-hashtable_search(struct hashtable *h, void *k)
-{
-    struct entry *e;
-    unsigned int hashvalue, index;
-    hashvalue = hash(h,k);
-    index = indexFor(h->tablelength,hashvalue);
-    e = h->table[index];
-    while (NULL != e)
-    {
-        /* Check hash value to short circuit heavier comparison */
-        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
-        e = e->next;
-    }
-    return NULL;
-}
-
-/*****************************************************************************/
-void * /* returns value associated with key */
-hashtable_remove(struct hashtable *h, void *k)
-{
-    /* TODO: consider compacting the table when the load factor drops enough,
-     *       or provide a 'compact' method. */
-
-    struct entry *e;
-    struct entry **pE;
-    void *v;
-    unsigned int hashvalue, index;
-
-    hashvalue = hash(h,k);
-    index = indexFor(h->tablelength,hash(h,k));
-    pE = &(h->table[index]);
-    e = *pE;
-    while (NULL != e)
-    {
-        /* Check hash value to short circuit heavier comparison */
-        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
-        {
-            *pE = e->next;
-            h->entrycount--;
-            v = e->v;
-            freekey(e->k);
-            free(e);
-            return v;
-        }
-        pE = &(e->next);
-        e = e->next;
-    }
-    return NULL;
-}
-
-/*****************************************************************************/
-/* destroy */
-void
-hashtable_destroy(struct hashtable *h, int free_values)
-{
-    unsigned int i;
-    struct entry *e, *f;
-    struct entry **table = h->table;
-    if (free_values)
-    {
-        for (i = 0; i < h->tablelength; i++)
-        {
-            e = table[i];
-            while (NULL != e)
-            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
-        }
-    }
-    else
-    {
-        for (i = 0; i < h->tablelength; i++)
-        {
-            e = table[i];
-            while (NULL != e)
-            { f = e; e = e->next; freekey(f->k); free(f); }
-        }
-    }
-    free(h->table);
-    free(h);
-}
-
-/*
- * Copyright (c) 2002, Christopher Clark
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
diff --git a/ubifs-utils/mkfs.ubifs/hashtable/hashtable.h b/ubifs-utils/mkfs.ubifs/hashtable/hashtable.h
deleted file mode 100644
index c0b0acd..0000000
--- a/ubifs-utils/mkfs.ubifs/hashtable/hashtable.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-
-#ifndef __HASHTABLE_CWC22_H__
-#define __HASHTABLE_CWC22_H__
-
-struct hashtable;
-
-/* Example of use:
- *
- *      struct hashtable  *h;
- *      struct some_key   *k;
- *      struct some_value *v;
- *
- *      static unsigned int         hash_from_key_fn( void *k );
- *      static int                  keys_equal_fn ( void *key1, void *key2 );
- *
- *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
- *      k = (struct some_key *)     malloc(sizeof(struct some_key));
- *      v = (struct some_value *)   malloc(sizeof(struct some_value));
- *
- *      (initialise k and v to suitable values)
- *
- *      if (! hashtable_insert(h,k,v) )
- *      {     exit(-1);               }
- *
- *      if (NULL == (found = hashtable_search(h,k) ))
- *      {    printf("not found!");                  }
- *
- *      if (NULL == (found = hashtable_remove(h,k) ))
- *      {    printf("Not found\n");                 }
- *
- */
-
-/* Macros may be used to define type-safe(r) hashtable access functions, with
- * methods specialized to take known key and value types as parameters.
- *
- * Example:
- *
- * Insert this at the start of your file:
- *
- * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
- * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
- * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
- *
- * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
- * These operate just like hashtable_insert etc., with the same parameters,
- * but their function signatures have 'struct some_key *' rather than
- * 'void *', and hence can generate compile time errors if your program is
- * supplying incorrect data as a key (and similarly for value).
- *
- * Note that the hash and key equality functions passed to create_hashtable
- * still take 'void *' parameters instead of 'some key *'. This shouldn't be
- * a difficult issue as they're only defined and passed once, and the other
- * functions will ensure that only valid keys are supplied to them.
- *
- * The cost for this checking is increased code size and runtime overhead
- * - if performance is important, it may be worth switching back to the
- * unsafe methods once your program has been debugged with the safe methods.
- * This just requires switching to some simple alternative defines - eg:
- * #define insert_some hashtable_insert
- *
- */
-
-/*****************************************************************************
- * create_hashtable
-
- * @name                    create_hashtable
- * @param   minsize         minimum initial size of hashtable
- * @param   hashfunction    function for hashing keys
- * @param   key_eq_fn       function for determining key equality
- * @return                  newly created hashtable or NULL on failure
- */
-
-struct hashtable *
-create_hashtable(unsigned int minsize,
-                 unsigned int (*hashfunction) (void*),
-                 int (*key_eq_fn) (void*,void*));
-
-/*****************************************************************************
- * hashtable_insert
-
- * @name        hashtable_insert
- * @param   h   the hashtable to insert into
- * @param   k   the key - hashtable claims ownership and will free on removal
- * @param   v   the value - does not claim ownership
- * @return      non-zero for successful insertion
- *
- * This function will cause the table to expand if the insertion would take
- * the ratio of entries to table size over the maximum load factor.
- *
- * This function does not check for repeated insertions with a duplicate key.
- * The value returned when using a duplicate key is undefined -- when
- * the hashtable changes size, the order of retrieval of duplicate key
- * entries is reversed.
- * If in doubt, remove before insert.
- */
-
-int
-hashtable_insert(struct hashtable *h, void *k, void *v);
-
-#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
-int fnname (struct hashtable *h, keytype *k, valuetype *v) \
-{ \
-    return hashtable_insert(h,k,v); \
-}
-
-/*****************************************************************************
- * hashtable_search
-
- * @name        hashtable_search
- * @param   h   the hashtable to search
- * @param   k   the key to search for  - does not claim ownership
- * @return      the value associated with the key, or NULL if none found
- */
-
-void *
-hashtable_search(struct hashtable *h, void *k);
-
-#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
-valuetype * fnname (struct hashtable *h, keytype *k) \
-{ \
-    return (valuetype *) (hashtable_search(h,k)); \
-}
-
-/*****************************************************************************
- * hashtable_remove
-
- * @name        hashtable_remove
- * @param   h   the hashtable to remove the item from
- * @param   k   the key to search for  - does not claim ownership
- * @return      the value associated with the key, or NULL if none found
- */
-
-void * /* returns value */
-hashtable_remove(struct hashtable *h, void *k);
-
-#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
-valuetype * fnname (struct hashtable *h, keytype *k) \
-{ \
-    return (valuetype *) (hashtable_remove(h,k)); \
-}
-
-
-/*****************************************************************************
- * hashtable_count
-
- * @name        hashtable_count
- * @param   h   the hashtable
- * @return      the number of items stored in the hashtable
- */
-unsigned int
-hashtable_count(struct hashtable *h);
-
-
-/*****************************************************************************
- * hashtable_destroy
-
- * @name        hashtable_destroy
- * @param   h   the hashtable
- * @param       free_values     whether to call 'free' on the remaining values
- */
-
-void
-hashtable_destroy(struct hashtable *h, int free_values);
-
-#endif /* __HASHTABLE_CWC22_H__ */
-
-/*
- * Copyright (c) 2002, Christopher Clark
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
diff --git a/ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c b/ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c
deleted file mode 100644
index d102453..0000000
--- a/ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname@cl.cam.ac.uk> */
-
-#include "hashtable.h"
-#include "hashtable_private.h"
-#include "hashtable_itr.h"
-#include <stdlib.h> /* defines NULL */
-
-/*****************************************************************************/
-/* hashtable_iterator    - iterator constructor */
-
-struct hashtable_itr *
-hashtable_iterator(struct hashtable *h)
-{
-    unsigned int i, tablelength;
-    struct hashtable_itr *itr = (struct hashtable_itr *)
-        malloc(sizeof(struct hashtable_itr));
-    if (NULL == itr) return NULL;
-    itr->h = h;
-    itr->e = NULL;
-    itr->parent = NULL;
-    tablelength = h->tablelength;
-    itr->index = tablelength;
-    if (0 == h->entrycount) return itr;
-
-    for (i = 0; i < tablelength; i++)
-    {
-        if (NULL != h->table[i])
-        {
-            itr->e = h->table[i];
-            itr->index = i;
-            break;
-        }
-    }
-    return itr;
-}
-
-/*****************************************************************************/
-/* advance - advance the iterator to the next element
- *           returns zero if advanced to end of table */
-
-int
-hashtable_iterator_advance(struct hashtable_itr *itr)
-{
-    unsigned int j,tablelength;
-    struct entry **table;
-    struct entry *next;
-    if (NULL == itr->e) return 0; /* stupidity check */
-
-    next = itr->e->next;
-    if (NULL != next)
-    {
-        itr->parent = itr->e;
-        itr->e = next;
-        return -1;
-    }
-    tablelength = itr->h->tablelength;
-    itr->parent = NULL;
-    if (tablelength <= (j = ++(itr->index)))
-    {
-        itr->e = NULL;
-        return 0;
-    }
-    table = itr->h->table;
-    while (NULL == (next = table[j]))
-    {
-        if (++j >= tablelength)
-        {
-            itr->index = tablelength;
-            itr->e = NULL;
-            return 0;
-        }
-    }
-    itr->index = j;
-    itr->e = next;
-    return -1;
-}
-
-/*****************************************************************************/
-/* remove - remove the entry at the current iterator position
- *          and advance the iterator, if there is a successive
- *          element.
- *          If you want the value, read it before you remove:
- *          beware memory leaks if you don't.
- *          Returns zero if end of iteration. */
-
-int
-hashtable_iterator_remove(struct hashtable_itr *itr)
-{
-    struct entry *remember_e, *remember_parent;
-    int ret;
-
-    /* Do the removal */
-    if (NULL == (itr->parent))
-    {
-        /* element is head of a chain */
-        itr->h->table[itr->index] = itr->e->next;
-    } else {
-        /* element is mid-chain */
-        itr->parent->next = itr->e->next;
-    }
-    /* itr->e is now outside the hashtable */
-    remember_e = itr->e;
-    itr->h->entrycount--;
-    freekey(remember_e->k);
-
-    /* Advance the iterator, correcting the parent */
-    remember_parent = itr->parent;
-    ret = hashtable_iterator_advance(itr);
-    if (itr->parent == remember_e) { itr->parent = remember_parent; }
-    free(remember_e);
-    return ret;
-}
-
-/*****************************************************************************/
-int /* returns zero if not found */
-hashtable_iterator_search(struct hashtable_itr *itr,
-                          struct hashtable *h, void *k)
-{
-    struct entry *e, *parent;
-    unsigned int hashvalue, index;
-
-    hashvalue = hash(h,k);
-    index = indexFor(h->tablelength,hashvalue);
-
-    e = h->table[index];
-    parent = NULL;
-    while (NULL != e)
-    {
-        /* Check hash value to short circuit heavier comparison */
-        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
-        {
-            itr->index = index;
-            itr->e = e;
-            itr->parent = parent;
-            itr->h = h;
-            return -1;
-        }
-        parent = e;
-        e = e->next;
-    }
-    return 0;
-}
-
-
-/*
- * Copyright (c) 2002, 2004, Christopher Clark
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
diff --git a/ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h b/ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h
deleted file mode 100644
index 5c94a04..0000000
--- a/ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-
-#ifndef __HASHTABLE_ITR_CWC22__
-#define __HASHTABLE_ITR_CWC22__
-#include "hashtable.h"
-#include "hashtable_private.h" /* needed to enable inlining */
-
-/*****************************************************************************/
-/* This struct is only concrete here to allow the inlining of two of the
- * accessor functions. */
-struct hashtable_itr
-{
-    struct hashtable *h;
-    struct entry *e;
-    struct entry *parent;
-    unsigned int index;
-};
-
-
-/*****************************************************************************/
-/* hashtable_iterator
- */
-
-struct hashtable_itr *
-hashtable_iterator(struct hashtable *h);
-
-/*****************************************************************************/
-/* hashtable_iterator_key
- * - return the value of the (key,value) pair at the current position */
-
-static inline void *
-hashtable_iterator_key(struct hashtable_itr *i)
-{
-    return i->e->k;
-}
-
-/*****************************************************************************/
-/* value - return the value of the (key,value) pair at the current position */
-
-static inline void *
-hashtable_iterator_value(struct hashtable_itr *i)
-{
-    return i->e->v;
-}
-
-/*****************************************************************************/
-/* advance - advance the iterator to the next element
- *           returns zero if advanced to end of table */
-
-int
-hashtable_iterator_advance(struct hashtable_itr *itr);
-
-/*****************************************************************************/
-/* remove - remove current element and advance the iterator to the next element
- *          NB: if you need the value to free it, read it before
- *          removing. ie: beware memory leaks!
- *          returns zero if advanced to end of table */
-
-int
-hashtable_iterator_remove(struct hashtable_itr *itr);
-
-/*****************************************************************************/
-/* search - overwrite the supplied iterator, to point to the entry
- *          matching the supplied key.
-            h points to the hashtable to be searched.
- *          returns zero if not found. */
-int
-hashtable_iterator_search(struct hashtable_itr *itr,
-                          struct hashtable *h, void *k);
-
-#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
-int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
-{ \
-    return (hashtable_iterator_search(i,h,k)); \
-}
-
-
-
-#endif /* __HASHTABLE_ITR_CWC22__*/
-
-/*
- * Copyright (c) 2002, 2004, Christopher Clark
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
diff --git a/ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h b/ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h
deleted file mode 100644
index 3a558e6..0000000
--- a/ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-
-#ifndef __HASHTABLE_PRIVATE_CWC22_H__
-#define __HASHTABLE_PRIVATE_CWC22_H__
-
-#include "hashtable.h"
-
-/*****************************************************************************/
-struct entry
-{
-    void *k, *v;
-    unsigned int h;
-    struct entry *next;
-};
-
-struct hashtable {
-    unsigned int tablelength;
-    struct entry **table;
-    unsigned int entrycount;
-    unsigned int loadlimit;
-    unsigned int primeindex;
-    unsigned int (*hashfn) (void *k);
-    int (*eqfn) (void *k1, void *k2);
-};
-
-/*****************************************************************************/
-unsigned int
-hash(struct hashtable *h, void *k);
-
-/*****************************************************************************/
-/* indexFor */
-static inline unsigned int
-indexFor(unsigned int tablelength, unsigned int hashvalue) {
-    return (hashvalue % tablelength);
-};
-
-/* Only works if tablelength == 2^N */
-/*static inline unsigned int
-indexFor(unsigned int tablelength, unsigned int hashvalue)
-{
-    return (hashvalue & (tablelength - 1u));
-}
-*/
-
-/*****************************************************************************/
-#define freekey(X) free(X)
-/*define freekey(X) ; */
-
-
-/*****************************************************************************/
-
-#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
-
-/*
- * Copyright (c) 2002, Christopher Clark
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
diff --git a/ubifs-utils/mkfs.ubifs/io.c b/ubifs-utils/mkfs.ubifs/io.c
deleted file mode 100644
index 7aba0a6..0000000
--- a/ubifs-utils/mkfs.ubifs/io.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "io.h"
-#define PROGRAM_NAME "ubifs-io"
-#include <common.h>
-
-int out_fd;
-int out_ubi;
-libubi_t ubi;
-
-/**
- * write_leb - copy the image of a LEB to the output target.
- * @lnum: LEB number
- * @len: length of data in the buffer
- * @buf: buffer (must be at least c->leb_size bytes)
- */
-int write_leb(struct ubifs_info *c, int lnum, int len, void *buf)
-{
-	off_t pos = (off_t)lnum * c->leb_size;
-
-	dbg_msg(3, "LEB %d len %d", lnum, len);
-	memset(buf + len, 0xff, c->leb_size - len);
-	if (out_ubi)
-		if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size))
-			return sys_err_msg("ubi_leb_change_start failed");
-
-	if (lseek(out_fd, pos, SEEK_SET) != pos)
-		return sys_err_msg("lseek failed seeking %"PRIdoff_t, pos);
-
-	if (write(out_fd, buf, c->leb_size) != c->leb_size)
-		return sys_err_msg("write failed writing %d bytes at pos %"PRIdoff_t,
-				   c->leb_size, pos);
-
-	return 0;
-}
diff --git a/ubifs-utils/mkfs.ubifs/io.h b/ubifs-utils/mkfs.ubifs/io.h
deleted file mode 100644
index e24d0c6..0000000
--- a/ubifs-utils/mkfs.ubifs/io.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Header file for the io to ubi volume
- */
-#ifndef __UBIFS_IO_H__
-#define __UBIFS_IO_H__
-
-#include "ubifs_common.h"
-#include "ubifs.h"
-
-extern int out_fd;
-extern int out_ubi;
-extern libubi_t ubi;
-
-int write_leb(struct ubifs_info *c, int lnum, int len, void *buf);
-#endif
diff --git a/ubifs-utils/mkfs.ubifs/key.h b/ubifs-utils/mkfs.ubifs/key.h
deleted file mode 100644
index 39379fd..0000000
--- a/ubifs-utils/mkfs.ubifs/key.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file is part of UBIFS.
- *
- * Copyright (C) 2006-2008 Nokia Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy (Битюцкий Артём)
- *          Adrian Hunter
- */
-
-/*
- * This header contains various key-related definitions and helper function.
- * UBIFS allows several key schemes, so we access key fields only via these
- * helpers. At the moment only one key scheme is supported.
- *
- * Simple key scheme
- * ~~~~~~~~~~~~~~~~~
- *
- * Keys are 64-bits long. First 32-bits are inode number (parent inode number
- * in case of direntry key). Next 3 bits are node type. The last 29 bits are
- * 4KiB offset in case of inode node, and direntry hash in case of a direntry
- * node. We use "r5" hash borrowed from reiserfs.
- */
-
-#ifndef __UBIFS_KEY_H__
-#define __UBIFS_KEY_H__
-
-/**
- * key_mask_hash - mask a valid hash value.
- * @val: value to be masked
- *
- * We use hash values as offset in directories, so values %0 and %1 are
- * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
- * function makes sure the reserved values are not used.
- */
-static inline uint32_t key_mask_hash(uint32_t hash)
-{
-	hash &= UBIFS_S_KEY_HASH_MASK;
-	if (unlikely(hash <= 2))
-		hash += 3;
-	return hash;
-}
-
-/**
- * key_r5_hash - R5 hash function (borrowed from reiserfs).
- * @s: direntry name
- * @len: name length
- */
-static inline uint32_t key_r5_hash(const char *s, int len)
-{
-	uint32_t a = 0;
-	const signed char *str = (const signed char *)s;
-
-	len = len;
-	while (*str) {
-		a += *str << 4;
-		a += *str >> 4;
-		a *= 11;
-		str++;
-	}
-
-	return key_mask_hash(a);
-}
-
-/**
- * key_test_hash - testing hash function.
- * @str: direntry name
- * @len: name length
- */
-static inline uint32_t key_test_hash(const char *str, int len)
-{
-	uint32_t a = 0;
-
-	len = min_t(uint32_t, len, 4);
-	memcpy(&a, str, len);
-	return key_mask_hash(a);
-}
-
-/**
- * ino_key_init - initialize inode key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: inode number
- */
-static inline void ino_key_init(union ubifs_key *key, ino_t inum)
-{
-	key->u32[0] = inum;
-	key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS;
-}
-
-/**
- * dent_key_init - initialize directory entry key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: parent inode number
- * @nm: direntry name and length
- */
-static inline void dent_key_init(const struct ubifs_info *c,
-				 union ubifs_key *key, ino_t inum,
-				 const struct qstr *nm)
-{
-	uint32_t hash = c->key_hash(nm->name, nm->len);
-
-	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
-	key->u32[0] = inum;
-	key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
-}
-
-/**
- * xent_key_init - initialize extended attribute entry key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: host inode number
- * @nm: extended attribute entry name and length
- */
-static inline void xent_key_init(const struct ubifs_info *c,
-				 union ubifs_key *key, ino_t inum,
-				 const struct qstr *nm)
-{
-	uint32_t hash = c->key_hash(nm->name, nm->len);
-
-	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
-	key->u32[0] = inum;
-	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
-}
-
-/**
- * data_key_init - initialize data key.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: inode number
- * @block: block number
- */
-static inline void data_key_init(union ubifs_key *key, ino_t inum,
-				 unsigned int block)
-{
-	ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
-	key->u32[0] = inum;
-	key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
-}
-
-/**
- * key_write - transform a key from in-memory format.
- * @c: UBIFS file-system description object
- * @from: the key to transform
- * @to: the key to store the result
- */
-static inline void key_write(const union ubifs_key *from, void *to)
-{
-	union ubifs_key *t = to;
-
-	t->j32[0] = cpu_to_le32(from->u32[0]);
-	t->j32[1] = cpu_to_le32(from->u32[1]);
-	memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8);
-}
-
-/**
- * key_write_idx - transform a key from in-memory format for the index.
- * @c: UBIFS file-system description object
- * @from: the key to transform
- * @to: the key to store the result
- */
-static inline void key_write_idx(const union ubifs_key *from, void *to)
-{
-	union ubifs_key *t = to;
-
-	t->j32[0] = cpu_to_le32(from->u32[0]);
-	t->j32[1] = cpu_to_le32(from->u32[1]);
-}
-
-/**
- * keys_cmp - compare keys.
- * @c: UBIFS file-system description object
- * @key1: the first key to compare
- * @key2: the second key to compare
- *
- * This function compares 2 keys and returns %-1 if @key1 is less than
- * @key2, 0 if the keys are equivalent and %1 if @key1 is greater than @key2.
- */
-static inline int keys_cmp(const union ubifs_key *key1,
-			   const union ubifs_key *key2)
-{
-	if (key1->u32[0] < key2->u32[0])
-		return -1;
-	if (key1->u32[0] > key2->u32[0])
-		return 1;
-	if (key1->u32[1] < key2->u32[1])
-		return -1;
-	if (key1->u32[1] > key2->u32[1])
-		return 1;
-
-	return 0;
-}
-
-#endif /* !__UBIFS_KEY_H__ */
diff --git a/ubifs-utils/mkfs.ubifs/lpt.c b/ubifs-utils/mkfs.ubifs/lpt.c
deleted file mode 100644
index 100d747..0000000
--- a/ubifs-utils/mkfs.ubifs/lpt.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * This file is part of UBIFS.
- *
- * Copyright (C) 2006, 2007 Nokia Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Adrian Hunter
- *          Artem Bityutskiy
- */
-
-#include "ubifs_common.h"
-
-/* common.h requires the PROGRAM_NAME macro */
-#define PROGRAM_NAME "ubifs-lpt"
-#include "common.h"
-
-#include "crc16.h"
-#include "ubifs.h"
-#include "lpt.h"
-#include "io.h"
-
-/**
- * do_calc_lpt_geom - calculate sizes for the LPT area.
- * @c: the UBIFS file-system description object
- *
- * Calculate the sizes of LPT bit fields, nodes, and tree, based on the
- * properties of the flash and whether LPT is "big" (c->big_lpt).
- */
-static void do_calc_lpt_geom(struct ubifs_info *c)
-{
-	int n, bits, per_leb_wastage;
-	long long sz, tot_wastage;
-
-	c->pnode_cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
-
-	n = (c->pnode_cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
-	c->nnode_cnt = n;
-	while (n > 1) {
-		n = (n + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
-		c->nnode_cnt += n;
-	}
-
-	c->lpt_hght = 1;
-	n = UBIFS_LPT_FANOUT;
-	while (n < c->pnode_cnt) {
-		c->lpt_hght += 1;
-		n <<= UBIFS_LPT_FANOUT_SHIFT;
-	}
-
-	c->space_bits = fls(c->leb_size) - 3;
-	c->lpt_lnum_bits = fls(c->lpt_lebs);
-	c->lpt_offs_bits = fls(c->leb_size - 1);
-	c->lpt_spc_bits = fls(c->leb_size);
-
-	n = (c->max_leb_cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
-	c->pcnt_bits = fls(n - 1);
-
-	c->lnum_bits = fls(c->max_leb_cnt - 1);
-
-	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
-	       (c->big_lpt ? c->pcnt_bits : 0) +
-	       (c->space_bits * 2 + 1) * UBIFS_LPT_FANOUT;
-	c->pnode_sz = (bits + 7) / 8;
-
-	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
-	       (c->big_lpt ? c->pcnt_bits : 0) +
-	       (c->lpt_lnum_bits + c->lpt_offs_bits) * UBIFS_LPT_FANOUT;
-	c->nnode_sz = (bits + 7) / 8;
-
-	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
-	       c->lpt_lebs * c->lpt_spc_bits * 2;
-	c->ltab_sz = (bits + 7) / 8;
-
-	bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS +
-	       c->lnum_bits * c->lsave_cnt;
-	c->lsave_sz = (bits + 7) / 8;
-
-	/* Calculate the minimum LPT size */
-	c->lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
-	c->lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
-	c->lpt_sz += c->ltab_sz;
-	c->lpt_sz += c->lsave_sz;
-
-	/* Add wastage */
-	sz = c->lpt_sz;
-	per_leb_wastage = max_t(int, c->pnode_sz, c->nnode_sz);
-	sz += per_leb_wastage;
-	tot_wastage = per_leb_wastage;
-	while (sz > c->leb_size) {
-		sz += per_leb_wastage;
-		sz -= c->leb_size;
-		tot_wastage += per_leb_wastage;
-	}
-	tot_wastage += ALIGN(sz, c->min_io_size) - sz;
-	c->lpt_sz += tot_wastage;
-}
-
-/**
- * calc_dflt_lpt_geom - calculate default LPT geometry.
- * @c: the UBIFS file-system description object
- * @main_lebs: number of main area LEBs is passed and returned here
- * @big_lpt: whether the LPT area is "big" is returned here
- *
- * The size of the LPT area depends on parameters that themselves are dependent
- * on the size of the LPT area. This function, successively recalculates the LPT
- * area geometry until the parameters and resultant geometry are consistent.
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt)
-{
-	int i, lebs_needed;
-	long long sz;
-
-	/* Start by assuming the minimum number of LPT LEBs */
-	c->lpt_lebs = UBIFS_MIN_LPT_LEBS;
-	c->main_lebs = *main_lebs - c->lpt_lebs;
-	if (c->main_lebs <= 0)
-		return -EINVAL;
-
-	/* And assume we will use the small LPT model */
-	c->big_lpt = 0;
-
-	/*
-	 * Calculate the geometry based on assumptions above and then see if it
-	 * makes sense
-	 */
-	do_calc_lpt_geom(c);
-
-	/* Small LPT model must have lpt_sz < leb_size */
-	if (c->lpt_sz > c->leb_size) {
-		/* Nope, so try again using big LPT model */
-		c->big_lpt = 1;
-		do_calc_lpt_geom(c);
-	}
-
-	/* Now check there are enough LPT LEBs */
-	for (i = 0; i < 64 ; i++) {
-		sz = c->lpt_sz * 4; /* Allow 4 times the size */
-		sz += c->leb_size - 1;
-		do_div(sz, c->leb_size);
-		lebs_needed = sz;
-		if (lebs_needed > c->lpt_lebs) {
-			/* Not enough LPT LEBs so try again with more */
-			c->lpt_lebs = lebs_needed;
-			c->main_lebs = *main_lebs - c->lpt_lebs;
-			if (c->main_lebs <= 0)
-				return -EINVAL;
-			do_calc_lpt_geom(c);
-			continue;
-		}
-		if (c->ltab_sz > c->leb_size) {
-			err_msg("LPT ltab too big");
-			return -EINVAL;
-		}
-		*main_lebs = c->main_lebs;
-		*big_lpt = c->big_lpt;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-/**
- * pack_bits - pack bit fields end-to-end.
- * @addr: address at which to pack (passed and next address returned)
- * @pos: bit position at which to pack (passed and next position returned)
- * @val: value to pack
- * @nrbits: number of bits of value to pack (1-32)
- */
-static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
-{
-	uint8_t *p = *addr;
-	int b = *pos;
-
-	if (b) {
-		*p |= ((uint8_t)val) << b;
-		nrbits += b;
-		if (nrbits > 8) {
-			*++p = (uint8_t)(val >>= (8 - b));
-			if (nrbits > 16) {
-				*++p = (uint8_t)(val >>= 8);
-				if (nrbits > 24) {
-					*++p = (uint8_t)(val >>= 8);
-					if (nrbits > 32)
-						*++p = (uint8_t)(val >>= 8);
-				}
-			}
-		}
-	} else {
-		*p = (uint8_t)val;
-		if (nrbits > 8) {
-			*++p = (uint8_t)(val >>= 8);
-			if (nrbits > 16) {
-				*++p = (uint8_t)(val >>= 8);
-				if (nrbits > 24)
-					*++p = (uint8_t)(val >>= 8);
-			}
-		}
-	}
-	b = nrbits & 7;
-	if (b == 0)
-		p++;
-	*addr = p;
-	*pos = b;
-}
-
-/**
- * pack_pnode - pack all the bit fields of a pnode.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @pnode: pnode to pack
- */
-static void pack_pnode(struct ubifs_info *c, void *buf,
-		       struct ubifs_pnode *pnode)
-{
-	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
-	int i, pos = 0;
-	uint16_t crc;
-
-	pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
-	if (c->big_lpt)
-		pack_bits(&addr, &pos, pnode->num, c->pcnt_bits);
-	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
-		pack_bits(&addr, &pos, pnode->lprops[i].free >> 3,
-			  c->space_bits);
-		pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3,
-			  c->space_bits);
-		if (pnode->lprops[i].flags & LPROPS_INDEX)
-			pack_bits(&addr, &pos, 1, 1);
-		else
-			pack_bits(&addr, &pos, 0, 1);
-	}
-	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
-		    c->pnode_sz - UBIFS_LPT_CRC_BYTES);
-	addr = buf;
-	pos = 0;
-	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
-}
-
-/**
- * pack_nnode - pack all the bit fields of a nnode.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @nnode: nnode to pack
- */
-static void pack_nnode(struct ubifs_info *c, void *buf,
-		       struct ubifs_nnode *nnode)
-{
-	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
-	int i, pos = 0;
-	uint16_t crc;
-
-	pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
-	if (c->big_lpt)
-		pack_bits(&addr, &pos, nnode->num, c->pcnt_bits);
-	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
-		int lnum = nnode->nbranch[i].lnum;
-
-		if (lnum == 0)
-			lnum = c->lpt_last + 1;
-		pack_bits(&addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
-		pack_bits(&addr, &pos, nnode->nbranch[i].offs,
-			  c->lpt_offs_bits);
-	}
-	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
-		    c->nnode_sz - UBIFS_LPT_CRC_BYTES);
-	addr = buf;
-	pos = 0;
-	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
-}
-
-/**
- * pack_ltab - pack the LPT's own lprops table.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @ltab: LPT's own lprops table to pack
- */
-static void pack_ltab(struct ubifs_info *c, void *buf,
-			 struct ubifs_lpt_lprops *ltab)
-{
-	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
-	int i, pos = 0;
-	uint16_t crc;
-
-	pack_bits(&addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
-	for (i = 0; i < c->lpt_lebs; i++) {
-		pack_bits(&addr, &pos, ltab[i].free, c->lpt_spc_bits);
-		pack_bits(&addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
-	}
-	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
-		    c->ltab_sz - UBIFS_LPT_CRC_BYTES);
-	addr = buf;
-	pos = 0;
-	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
-}
-
-/**
- * pack_lsave - pack the LPT's save table.
- * @c: UBIFS file-system description object
- * @buf: buffer into which to pack
- * @lsave: LPT's save table to pack
- */
-static void pack_lsave(struct ubifs_info *c, void *buf, int *lsave)
-{
-	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
-	int i, pos = 0;
-	uint16_t crc;
-
-	pack_bits(&addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
-	for (i = 0; i < c->lsave_cnt; i++)
-		pack_bits(&addr, &pos, lsave[i], c->lnum_bits);
-	crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
-		    c->lsave_sz - UBIFS_LPT_CRC_BYTES);
-	addr = buf;
-	pos = 0;
-	pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
-}
-
-/**
- * set_ltab - set LPT LEB properties.
- * @c: UBIFS file-system description object
- * @lnum: LEB number
- * @free: amount of free space
- * @dirty: amount of dirty space
- */
-static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
-{
-	dbg_msg(3, "LEB %d free %d dirty %d to %d %d",
-		lnum, c->ltab[lnum - c->lpt_first].free,
-		c->ltab[lnum - c->lpt_first].dirty, free, dirty);
-	c->ltab[lnum - c->lpt_first].free = free;
-	c->ltab[lnum - c->lpt_first].dirty = dirty;
-}
-
-/**
- * calc_nnode_num - calculate nnode number.
- * @row: the row in the tree (root is zero)
- * @col: the column in the row (leftmost is zero)
- *
- * The nnode number is a number that uniquely identifies a nnode and can be used
- * easily to traverse the tree from the root to that nnode.
- *
- * This function calculates and returns the nnode number for the nnode at @row
- * and @col.
- */
-static int calc_nnode_num(int row, int col)
-{
-	int num, bits;
-
-	num = 1;
-	while (row--) {
-		bits = (col & (UBIFS_LPT_FANOUT - 1));
-		col >>= UBIFS_LPT_FANOUT_SHIFT;
-		num <<= UBIFS_LPT_FANOUT_SHIFT;
-		num |= bits;
-	}
-	return num;
-}
-
-/**
- * create_lpt - create LPT.
- * @c: UBIFS file-system description object
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-int create_lpt(struct ubifs_info *c)
-{
-	int lnum, err = 0, i, j, cnt, len, alen, row;
-	int blnum, boffs, bsz, bcnt;
-	struct ubifs_pnode *pnode = NULL;
-	struct ubifs_nnode *nnode = NULL;
-	void *buf = NULL, *p;
-	int *lsave = NULL;
-
-	pnode = malloc(sizeof(struct ubifs_pnode));
-	nnode = malloc(sizeof(struct ubifs_nnode));
-	buf = malloc(c->leb_size);
-	lsave = malloc(sizeof(int) * c->lsave_cnt);
-	if (!pnode || !nnode || !buf || !lsave) {
-		err = -ENOMEM;
-		goto out;
-	}
-	memset(pnode, 0 , sizeof(struct ubifs_pnode));
-	memset(nnode, 0 , sizeof(struct ubifs_nnode));
-
-	c->lscan_lnum = c->main_first;
-
-	lnum = c->lpt_first;
-	p = buf;
-	len = 0;
-	/* Number of leaf nodes (pnodes) */
-	cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) >> UBIFS_LPT_FANOUT_SHIFT;
-	//printf("pnode_cnt=%d\n",cnt);
-
-	/*
-	 * To calculate the internal node branches, we keep information about
-	 * the level below.
-	 */
-	blnum = lnum; /* LEB number of level below */
-	boffs = 0; /* Offset of level below */
-	bcnt = cnt; /* Number of nodes in level below */
-	bsz = c->pnode_sz; /* Size of nodes in level below */
-
-	/* Add pnodes */
-	for (i = 0; i < cnt; i++) {
-		if (len + c->pnode_sz > c->leb_size) {
-			alen = ALIGN(len, c->min_io_size);
-			set_ltab(c, lnum, c->leb_size - alen, alen - len);
-			memset(p, 0xff, alen - len);
-			err = write_leb(c, lnum++, alen, buf);
-			if (err)
-				goto out;
-			p = buf;
-			len = 0;
-		}
-		/* Fill in the pnode */
-		for (j = 0; j < UBIFS_LPT_FANOUT; j++) {
-			int k = (i << UBIFS_LPT_FANOUT_SHIFT) + j;
-
-			if (k < c->main_lebs)
-				pnode->lprops[j] = c->lpt[k];
-			else {
-				pnode->lprops[j].free = c->leb_size;
-				pnode->lprops[j].dirty = 0;
-				pnode->lprops[j].flags = 0;
-			}
-		}
-		pack_pnode(c, p, pnode);
-		p += c->pnode_sz;
-		len += c->pnode_sz;
-		/*
-		 * pnodes are simply numbered left to right starting at zero,
-		 * which means the pnode number can be used easily to traverse
-		 * down the tree to the corresponding pnode.
-		 */
-		pnode->num += 1;
-	}
-
-	row = c->lpt_hght - 1;
-	/* Add all nnodes, one level at a time */
-	while (1) {
-		/* Number of internal nodes (nnodes) at next level */
-		cnt = (cnt + UBIFS_LPT_FANOUT - 1) / UBIFS_LPT_FANOUT;
-		if (cnt == 0)
-			cnt = 1;
-		for (i = 0; i < cnt; i++) {
-			if (len + c->nnode_sz > c->leb_size) {
-				alen = ALIGN(len, c->min_io_size);
-				set_ltab(c, lnum, c->leb_size - alen,
-					    alen - len);
-				memset(p, 0xff, alen - len);
-				err = write_leb(c, lnum++, alen, buf);
-				if (err)
-					goto out;
-				p = buf;
-				len = 0;
-			}
-			/* The root is on row zero */
-			if (row == 0) {
-				c->lpt_lnum = lnum;
-				c->lpt_offs = len;
-			}
-			/* Set branches to the level below */
-			for (j = 0; j < UBIFS_LPT_FANOUT; j++) {
-				if (bcnt) {
-					if (boffs + bsz > c->leb_size) {
-						blnum += 1;
-						boffs = 0;
-					}
-					nnode->nbranch[j].lnum = blnum;
-					nnode->nbranch[j].offs = boffs;
-					boffs += bsz;
-					bcnt--;
-				} else {
-					nnode->nbranch[j].lnum = 0;
-					nnode->nbranch[j].offs = 0;
-				}
-			}
-			nnode->num = calc_nnode_num(row, i);
-			pack_nnode(c, p, nnode);
-			p += c->nnode_sz;
-			len += c->nnode_sz;
-		}
-		/* Row zero  is the top row */
-		if (row == 0)
-			break;
-		/* Update the information about the level below */
-		bcnt = cnt;
-		bsz = c->nnode_sz;
-		row -= 1;
-	}
-
-	if (c->big_lpt) {
-		/* Need to add LPT's save table */
-		if (len + c->lsave_sz > c->leb_size) {
-			alen = ALIGN(len, c->min_io_size);
-			set_ltab(c, lnum, c->leb_size - alen, alen - len);
-			memset(p, 0xff, alen - len);
-			err = write_leb(c, lnum++, alen, buf);
-			if (err)
-				goto out;
-			p = buf;
-			len = 0;
-		}
-
-		c->lsave_lnum = lnum;
-		c->lsave_offs = len;
-
-		for (i = 0; i < c->lsave_cnt; i++)
-			lsave[i] = c->main_first + i;
-
-		pack_lsave(c, p, lsave);
-		p += c->lsave_sz;
-		len += c->lsave_sz;
-	}
-
-	/* Need to add LPT's own LEB properties table */
-	if (len + c->ltab_sz > c->leb_size) {
-		alen = ALIGN(len, c->min_io_size);
-		set_ltab(c, lnum, c->leb_size - alen, alen - len);
-		memset(p, 0xff, alen - len);
-		err = write_leb(c, lnum++, alen, buf);
-		if (err)
-			goto out;
-		p = buf;
-		len = 0;
-	}
-
-	c->ltab_lnum = lnum;
-	c->ltab_offs = len;
-
-	/* Update ltab before packing it */
-	len += c->ltab_sz;
-	alen = ALIGN(len, c->min_io_size);
-	set_ltab(c, lnum, c->leb_size - alen, alen - len);
-
-	pack_ltab(c, p, c->ltab);
-	p += c->ltab_sz;
-
-	/* Write remaining buffer */
-	memset(p, 0xff, alen - len);
-	err = write_leb(c, lnum, alen, buf);
-	if (err)
-		goto out;
-
-	c->nhead_lnum = lnum;
-	c->nhead_offs = ALIGN(len, c->min_io_size);
-
-	dbg_msg(1, "lpt_sz:         %lld", c->lpt_sz);
-	dbg_msg(1, "space_bits:     %d", c->space_bits);
-	dbg_msg(1, "lpt_lnum_bits:  %d", c->lpt_lnum_bits);
-	dbg_msg(1, "lpt_offs_bits:  %d", c->lpt_offs_bits);
-	dbg_msg(1, "lpt_spc_bits:   %d", c->lpt_spc_bits);
-	dbg_msg(1, "pcnt_bits:      %d", c->pcnt_bits);
-	dbg_msg(1, "lnum_bits:      %d", c->lnum_bits);
-	dbg_msg(1, "pnode_sz:       %d", c->pnode_sz);
-	dbg_msg(1, "nnode_sz:       %d", c->nnode_sz);
-	dbg_msg(1, "ltab_sz:        %d", c->ltab_sz);
-	dbg_msg(1, "lsave_sz:       %d", c->lsave_sz);
-	dbg_msg(1, "lsave_cnt:      %d", c->lsave_cnt);
-	dbg_msg(1, "lpt_hght:       %d", c->lpt_hght);
-	dbg_msg(1, "big_lpt:        %d", c->big_lpt);
-	dbg_msg(1, "LPT root is at  %d:%d", c->lpt_lnum, c->lpt_offs);
-	dbg_msg(1, "LPT head is at  %d:%d", c->nhead_lnum, c->nhead_offs);
-	dbg_msg(1, "LPT ltab is at  %d:%d", c->ltab_lnum, c->ltab_offs);
-	if (c->big_lpt)
-		dbg_msg(1, "LPT lsave is at %d:%d",
-		        c->lsave_lnum, c->lsave_offs);
-out:
-	free(lsave);
-	free(buf);
-	free(nnode);
-	free(pnode);
-	return err;
-}
diff --git a/ubifs-utils/mkfs.ubifs/lpt.h b/ubifs-utils/mkfs.ubifs/lpt.h
deleted file mode 100644
index 4cde59d..0000000
--- a/ubifs-utils/mkfs.ubifs/lpt.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Corporation.
- * Copyright (C) 2008 University of Szeged, Hungary
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy
- *          Adrian Hunter
- */
-
-#ifndef __UBIFS_LPT_H__
-#define __UBIFS_LPT_H__
-
-int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, int *big_lpt);
-int create_lpt(struct ubifs_info *c);
-
-#endif
diff --git a/ubifs-utils/mkfs.ubifs/ubifs.h b/ubifs-utils/mkfs.ubifs/ubifs.h
deleted file mode 100644
index 2f080a8..0000000
--- a/ubifs-utils/mkfs.ubifs/ubifs.h
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * This file is part of UBIFS.
- *
- * Copyright (C) 2008 Nokia Corporation.
- * Copyright (C) 2008 University of Szeged, Hungary
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Artem Bityutskiy
- *          Adrian Hunter
- *          Zoltan Sogor
- */
-
-#ifndef __UBIFS_H__
-#define __UBIFS_H__
-
-/* Maximum logical eraseblock size in bytes */
-#define UBIFS_MAX_LEB_SZ (2*1024*1024)
-
-/* Minimum amount of data UBIFS writes to the flash */
-#define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8)
-
-/* Largest key size supported in this implementation */
-#define CUR_MAX_KEY_LEN UBIFS_SK_LEN
-
-/*
- * There is no notion of truncation key because truncation nodes do not exist
- * in TNC. However, when replaying, it is handy to introduce fake "truncation"
- * keys for truncation nodes because the code becomes simpler. So we define
- * %UBIFS_TRUN_KEY type.
- */
-#define UBIFS_TRUN_KEY UBIFS_KEY_TYPES_CNT
-
-/*
- * How much a directory entry/extended attribute entry adds to the parent/host
- * inode.
- */
-#define CALC_DENT_SIZE(name_len) ALIGN(UBIFS_DENT_NODE_SZ + (name_len) + 1, 8)
-
-/* How much an extended attribute adds to the host inode */
-#define CALC_XATTR_BYTES(data_len) ALIGN(UBIFS_INO_NODE_SZ + (data_len) + 1, 8)
-
-/* The below union makes it easier to deal with keys */
-union ubifs_key
-{
-	uint8_t u8[CUR_MAX_KEY_LEN];
-	uint32_t u32[CUR_MAX_KEY_LEN/4];
-	uint64_t u64[CUR_MAX_KEY_LEN/8];
-	__le32 j32[CUR_MAX_KEY_LEN/4];
-};
-
-/*
- * LEB properties flags.
- *
- * LPROPS_UNCAT: not categorized
- * LPROPS_DIRTY: dirty > 0, not index
- * LPROPS_DIRTY_IDX: dirty + free > UBIFS_CH_SZ and index
- * LPROPS_FREE: free > 0, not empty, not index
- * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs
- * LPROPS_EMPTY: LEB is empty, not taken
- * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken
- * LPROPS_FRDI_IDX: free + dirty == leb_size and index, may be taken
- * LPROPS_CAT_MASK: mask for the LEB categories above
- * LPROPS_TAKEN: LEB was taken (this flag is not saved on the media)
- * LPROPS_INDEX: LEB contains indexing nodes (this flag also exists on flash)
- */
-enum {
-	LPROPS_UNCAT     =  0,
-	LPROPS_DIRTY     =  1,
-	LPROPS_DIRTY_IDX =  2,
-	LPROPS_FREE      =  3,
-	LPROPS_HEAP_CNT  =  3,
-	LPROPS_EMPTY     =  4,
-	LPROPS_FREEABLE  =  5,
-	LPROPS_FRDI_IDX  =  6,
-	LPROPS_CAT_MASK  = 15,
-	LPROPS_TAKEN     = 16,
-	LPROPS_INDEX     = 32,
-};
-
-/**
- * struct ubifs_lprops - logical eraseblock properties.
- * @free: amount of free space in bytes
- * @dirty: amount of dirty space in bytes
- * @flags: LEB properties flags (see above)
- */
-struct ubifs_lprops
-{
-	int free;
-	int dirty;
-	int flags;
-};
-
-/**
- * struct ubifs_lpt_lprops - LPT logical eraseblock properties.
- * @free: amount of free space in bytes
- * @dirty: amount of dirty space in bytes
- */
-struct ubifs_lpt_lprops
-{
-	int free;
-	int dirty;
-};
-
-struct ubifs_nnode;
-
-/**
- * struct ubifs_cnode - LEB Properties Tree common node.
- * @parent: parent nnode
- * @cnext: next cnode to commit
- * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
- * @iip: index in parent
- * @level: level in the tree (zero for pnodes, greater than zero for nnodes)
- * @num: node number
- */
-struct ubifs_cnode
-{
-	struct ubifs_nnode *parent;
-	struct ubifs_cnode *cnext;
-	unsigned long flags;
-	int iip;
-	int level;
-	int num;
-};
-
-/**
- * struct ubifs_pnode - LEB Properties Tree leaf node.
- * @parent: parent nnode
- * @cnext: next cnode to commit
- * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
- * @iip: index in parent
- * @level: level in the tree (always zero for pnodes)
- * @num: node number
- * @lprops: LEB properties array
- */
-struct ubifs_pnode
-{
-	struct ubifs_nnode *parent;
-	struct ubifs_cnode *cnext;
-	unsigned long flags;
-	int iip;
-	int level;
-	int num;
-	struct ubifs_lprops lprops[UBIFS_LPT_FANOUT];
-};
-
-/**
- * struct ubifs_nbranch - LEB Properties Tree internal node branch.
- * @lnum: LEB number of child
- * @offs: offset of child
- * @nnode: nnode child
- * @pnode: pnode child
- * @cnode: cnode child
- */
-struct ubifs_nbranch
-{
-	int lnum;
-	int offs;
-	union
-	{
-		struct ubifs_nnode *nnode;
-		struct ubifs_pnode *pnode;
-		struct ubifs_cnode *cnode;
-	};
-};
-
-/**
- * struct ubifs_nnode - LEB Properties Tree internal node.
- * @parent: parent nnode
- * @cnext: next cnode to commit
- * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE)
- * @iip: index in parent
- * @level: level in the tree (always greater than zero for nnodes)
- * @num: node number
- * @nbranch: branches to child nodes
- */
-struct ubifs_nnode
-{
-	struct ubifs_nnode *parent;
-	struct ubifs_cnode *cnext;
-	unsigned long flags;
-	int iip;
-	int level;
-	int num;
-	struct ubifs_nbranch nbranch[UBIFS_LPT_FANOUT];
-};
-
-/**
- * struct ubifs_lp_stats - statistics of eraseblocks in the main area.
- * @empty_lebs: number of empty LEBs
- * @taken_empty_lebs: number of taken LEBs
- * @idx_lebs: number of indexing LEBs
- * @total_free: total free space in bytes
- * @total_dirty: total dirty space in bytes
- * @total_used: total used space in bytes (includes only data LEBs)
- * @total_dead: total dead space in bytes (includes only data LEBs)
- * @total_dark: total dark space in bytes (includes only data LEBs)
- */
-struct ubifs_lp_stats {
-	int empty_lebs;
-	int taken_empty_lebs;
-	int idx_lebs;
-	long long total_free;
-	long long total_dirty;
-	long long total_used;
-	long long total_dead;
-	long long total_dark;
-};
-
-/**
- * struct ubifs_zbranch - key/coordinate/length branch stored in znodes.
- * @key: key
- * @znode: znode address in memory
- * @lnum: LEB number of the indexing node
- * @offs: offset of the indexing node within @lnum
- * @len: target node length
- */
-struct ubifs_zbranch
-{
-	union ubifs_key key;
-	struct ubifs_znode *znode;
-	int lnum;
-	int offs;
-	int len;
-};
-
-/**
- * struct ubifs_znode - in-memory representation of an indexing node.
- * @parent: parent znode or NULL if it is the root
- * @cnext: next znode to commit
- * @flags: flags
- * @time: last access time (seconds)
- * @level: level of the entry in the TNC tree
- * @child_cnt: count of child znodes
- * @iip: index in parent's zbranch array
- * @alt: lower bound of key range has altered i.e. child inserted at slot 0
- * @zbranch: array of znode branches (@c->fanout elements)
- */
-struct ubifs_znode
-{
-	struct ubifs_znode *parent;
-	struct ubifs_znode *cnext;
-	unsigned long flags;
-	unsigned long time;
-	int level;
-	int child_cnt;
-	int iip;
-	int alt;
-#ifdef CONFIG_UBIFS_FS_DEBUG
-	int lnum, offs, len;
-#endif
-	struct ubifs_zbranch zbranch[];
-};
-
-/**
- * struct ubifs_info - UBIFS file-system description data structure
- * (per-superblock).
- *
- * @highest_inum: highest used inode number
- * @max_sqnum: current global sequence number
- *
- * @jhead_cnt: count of journal heads
- * @max_bud_bytes: maximum number of bytes allowed in buds
- *
- * @zroot: zbranch which points to the root index node and znode
- * @ihead_lnum: LEB number of index head
- * @ihead_offs: offset of index head
- *
- * @log_lebs: number of logical eraseblocks in the log
- * @lpt_lebs: number of LEBs used for lprops table
- * @lpt_first: first LEB of the lprops table area
- * @lpt_last: last LEB of the lprops table area
- * @main_lebs: count of LEBs in the main area
- * @main_first: first LEB of the main area
- * @default_compr: default compression type
- * @favor_lzo: favor LZO compression method
- * @favor_percent: lzo vs. zlib threshold used in case favor LZO
- *
- * @key_hash_type: type of the key hash
- * @key_hash: direntry key hash function
- * @key_fmt: key format
- * @key_len: key length
- * @fanout: fanout of the index tree (number of links per indexing node)
- *
- * @min_io_size: minimal input/output unit size
- * @leb_size: logical eraseblock size in bytes
- * @leb_cnt: count of logical eraseblocks
- * @max_leb_cnt: maximum count of logical eraseblocks
- *
- * @old_idx_sz: size of index on flash
- * @lst: lprops statistics
- *
- * @dead_wm: LEB dead space watermark
- * @dark_wm: LEB dark space watermark
- *
- * @di: UBI device information
- * @vi: UBI volume information
- *
- * @gc_lnum: LEB number used for garbage collection
- * @rp_size: reserved pool size
- *
- * @space_bits: number of bits needed to record free or dirty space
- * @lpt_lnum_bits: number of bits needed to record a LEB number in the LPT
- * @lpt_offs_bits: number of bits needed to record an offset in the LPT
- * @lpt_spc_bits: number of bits needed to space in the LPT
- * @pcnt_bits: number of bits needed to record pnode or nnode number
- * @lnum_bits: number of bits needed to record LEB number
- * @nnode_sz: size of on-flash nnode
- * @pnode_sz: size of on-flash pnode
- * @ltab_sz: size of on-flash LPT lprops table
- * @lsave_sz: size of on-flash LPT save table
- * @pnode_cnt: number of pnodes
- * @nnode_cnt: number of nnodes
- * @lpt_hght: height of the LPT
- *
- * @lpt_lnum: LEB number of the root nnode of the LPT
- * @lpt_offs: offset of the root nnode of the LPT
- * @nhead_lnum: LEB number of LPT head
- * @nhead_offs: offset of LPT head
- * @big_lpt: flag that LPT is too big to write whole during commit
- * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up
- * @lpt_sz: LPT size
- *
- * @ltab_lnum: LEB number of LPT's own lprops table
- * @ltab_offs: offset of LPT's own lprops table
- * @lpt: lprops table
- * @ltab: LPT's own lprops table
- * @lsave_cnt: number of LEB numbers in LPT's save table
- * @lsave_lnum: LEB number of LPT's save table
- * @lsave_offs: offset of LPT's save table
- * @lsave: LPT's save table
- * @lscan_lnum: LEB number of last LPT scan
- */
-struct ubifs_info
-{
-	ino_t highest_inum;
-	unsigned long long max_sqnum;
-
-	int jhead_cnt;
-	long long max_bud_bytes;
-
-	struct ubifs_zbranch zroot;
-	int ihead_lnum;
-	int ihead_offs;
-
-	int log_lebs;
-	int lpt_lebs;
-	int lpt_first;
-	int lpt_last;
-	int orph_lebs;
-	int main_lebs;
-	int main_first;
-	int default_compr;
-	int favor_lzo;
-	int favor_percent;
-
-	uint8_t key_hash_type;
-	uint32_t (*key_hash)(const char *str, int len);
-	int key_fmt;
-	int key_len;
-	int fanout;
-
-	int min_io_size;
-	int leb_size;
-	int leb_cnt;
-	int max_leb_cnt;
-
-	unsigned long long old_idx_sz;
-	struct ubifs_lp_stats lst;
-
-	int dead_wm;
-	int dark_wm;
-
-	struct ubi_dev_info di;
-	struct ubi_vol_info vi;
-
-	int gc_lnum;
-	long long rp_size;
-
-	int space_bits;
-	int lpt_lnum_bits;
-	int lpt_offs_bits;
-	int lpt_spc_bits;
-	int pcnt_bits;
-	int lnum_bits;
-	int nnode_sz;
-	int pnode_sz;
-	int ltab_sz;
-	int lsave_sz;
-	int pnode_cnt;
-	int nnode_cnt;
-	int lpt_hght;
-
-	int lpt_lnum;
-	int lpt_offs;
-	int nhead_lnum;
-	int nhead_offs;
-	int big_lpt;
-	int space_fixup;
-	long long lpt_sz;
-
-	int ltab_lnum;
-	int ltab_offs;
-	struct ubifs_lprops *lpt;
-	struct ubifs_lpt_lprops *ltab;
-	int lsave_cnt;
-	int lsave_lnum;
-	int lsave_offs;
-	int *lsave;
-	int lscan_lnum;
-
-};
-
-/**
- * ubifs_idx_node_sz - return index node size.
- * @c: the UBIFS file-system description object
- * @child_cnt: number of children of this index node
- */
-static inline int ubifs_idx_node_sz(const struct ubifs_info *c, int child_cnt)
-{
-	return UBIFS_IDX_NODE_SZ + (UBIFS_BRANCH_SZ + c->key_len) * child_cnt;
-}
-
-/**
- * ubifs_idx_branch - return pointer to an index branch.
- * @c: the UBIFS file-system description object
- * @idx: index node
- * @bnum: branch number
- */
-static inline
-struct ubifs_branch *ubifs_idx_branch(const struct ubifs_info *c,
-				      const struct ubifs_idx_node *idx,
-				      int bnum)
-{
-	return (struct ubifs_branch *)((void *)idx->branches +
-				       (UBIFS_BRANCH_SZ + c->key_len) * bnum);
-}
-
-#endif /* __UBIFS_H__ */
diff --git a/ubifs-utils/mkfs.ubifs/ubifs_common.h b/ubifs-utils/mkfs.ubifs/ubifs_common.h
deleted file mode 100644
index 958c20a..0000000
--- a/ubifs-utils/mkfs.ubifs/ubifs_common.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef __UBIFS_COMMON_H__
-#define __UBIFS_COMMON_H__
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-#include <string.h>
-#include <stdint.h>
-#include <endian.h>
-#include <byteswap.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <libgen.h>
-#include <ctype.h>
-#include <uuid/uuid.h>
-#include <sys/file.h>
-
-#include <mtd/ubifs-media.h>
-
-#include "libubi.h"
-#include "defs.h"
-
-extern int verbose;
-extern int debug_level;
-
-#define dbg_msg(lvl, fmt, ...) do {if (debug_level >= lvl)                \
-	printf("ubifs: %s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
-} while(0)
-
-#define err_msg(fmt, ...) ({                                \
-	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); \
-	-1;                                                 \
-})
-
-#define sys_err_msg(fmt, ...) ({                                         \
-	int err_ = errno;                                                \
-	fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__);              \
-	fprintf(stderr, "       %s (error %d)\n", strerror(err_), err_); \
-	-1;                                                              \
-})
-#endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 07/27] ubifs: move more functions into io lib
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (5 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 06/27] ubifs: introduce ubifs-utils/include and ubifs-utils/lib Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 08/27] ubifs: introduce a new tool ubifs_dump Dongsheng Yang
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Move some common functions in mkfs.ubifs.c to io.c
to let others can use them.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/io.h            |   4 ++
 ubifs-utils/lib/io.c                | 101 +++++++++++++++++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 102 +-----------------------------------
 3 files changed, 107 insertions(+), 100 deletions(-)

diff --git a/ubifs-utils/include/io.h b/ubifs-utils/include/io.h
index e24d0c6..920645d 100644
--- a/ubifs-utils/include/io.h
+++ b/ubifs-utils/include/io.h
@@ -10,6 +10,10 @@
 extern int out_fd;
 extern int out_ubi;
 extern libubi_t ubi;
+extern char *output;
 
 int write_leb(struct ubifs_info *c, int lnum, int len, void *buf);
+int close_target(void);
+int open_target(struct ubifs_info *c, int yes);
+int open_ubi(struct ubifs_info *c, const char *node);
 #endif
diff --git a/ubifs-utils/lib/io.c b/ubifs-utils/lib/io.c
index 7aba0a6..9817d2a 100644
--- a/ubifs-utils/lib/io.c
+++ b/ubifs-utils/lib/io.c
@@ -5,6 +5,107 @@
 int out_fd;
 int out_ubi;
 libubi_t ubi;
+char *output;
+
+/**
+ * check_volume_empty - check if the UBI volume is empty.
+ *
+ * This function checks if the UBI volume is empty by looking if its LEBs are
+ * mapped or not.
+ *
+ * Returns %0 in case of success, %1 is the volume is not empty,
+ * and a negative error code in case of failure.
+ */
+static int check_volume_empty(struct ubifs_info *c)
+{
+	int lnum, err;
+
+	for (lnum = 0; lnum < c->vi.rsvd_lebs; lnum++) {
+		err = ubi_is_mapped(out_fd, lnum);
+		if (err < 0)
+			return err;
+		if (err == 1)
+			return 1;
+	}
+	return 0;
+}
+
+/**
+ * open_ubi - open the UBI volume.
+ * @node: name of the UBI volume character device to fetch information about
+ *
+ * Returns %0 in case of success and %-1 in case of failure
+ */
+int open_ubi(struct ubifs_info *c, const char *node)
+{
+	struct stat st;
+
+	if (stat(node, &st) || !S_ISCHR(st.st_mode))
+		return -1;
+
+	ubi = libubi_open();
+	if (!ubi)
+		return -1;
+	if (ubi_get_vol_info(ubi, node, &c->vi))
+		return -1;
+	if (ubi_get_dev_info1(ubi, c->vi.dev_num, &c->di))
+		return -1;
+	return 0;
+}
+
+/**
+ * open_target - open the output target.
+ * @yes: always ansure yes
+ *
+ * Open the output target. The target can be an UBI volume
+ * or a file.
+ *
+ * Returns %0 in case of success and %-1 in case of failure.
+ */
+int open_target(struct ubifs_info *c, int yes)
+{
+	if (out_ubi) {
+		out_fd = open(output, O_RDWR | O_EXCL);
+
+		if (out_fd == -1)
+			return sys_err_msg("cannot open the UBI volume '%s'",
+					   output);
+		if (ubi_set_property(out_fd, UBI_VOL_PROP_DIRECT_WRITE, 1))
+			return sys_err_msg("ubi_set_property failed");
+
+		if (!yes && check_volume_empty(c)) {
+			if (!prompt("UBI volume is not empty.  Format anyways?", false))
+				return err_msg("UBI volume is not empty");
+		}
+	} else {
+		out_fd = open(output, O_CREAT | O_RDWR | O_TRUNC,
+			      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+		if (out_fd == -1)
+			return sys_err_msg("cannot create output file '%s'",
+					   output);
+	}
+	return 0;
+}
+
+/**
+ * close_target - close the output target.
+ *
+ * Close the output target. If the target was an UBI
+ * volume, also close libubi.
+ *
+ * Returns %0 in case of success and %-1 in case of failure.
+ */
+int close_target(void)
+{
+	if (ubi)
+		libubi_close(ubi);
+	if (out_fd >= 0 && close(out_fd) == -1)
+		return sys_err_msg("cannot close the target '%s'", output);
+	if (output)
+		free(output);
+	return 0;
+}
+
 
 /**
  * write_leb - copy the image of a LEB to the output target.
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index a16e856..6e60109 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -110,7 +110,6 @@ int yes;
 static char *root;
 static int root_len;
 static struct stat root_st;
-static char *output;
 static int squash_owner;
 static int do_create_inum_attr;
 
@@ -446,28 +445,6 @@ static long long get_bytes(const char *str)
 
 	return bytes;
 }
-/**
- * open_ubi - open the UBI volume.
- * @node: name of the UBI volume character device to fetch information about
- *
- * Returns %0 in case of success and %-1 in case of failure
- */
-static int open_ubi(const char *node)
-{
-	struct stat st;
-
-	if (stat(node, &st) || !S_ISCHR(st.st_mode))
-		return -1;
-
-	ubi = libubi_open();
-	if (!ubi)
-		return -1;
-	if (ubi_get_vol_info(ubi, node, &c->vi))
-		return -1;
-	if (ubi_get_dev_info1(ubi, c->vi.dev_num, &c->di))
-		return -1;
-	return 0;
-}
 
 static int get_options(int argc, char**argv)
 {
@@ -643,7 +620,7 @@ static int get_options(int argc, char**argv)
 	if (!output)
 		return err_msg("not output device or file specified");
 
-	out_ubi = !open_ubi(output);
+	out_ubi = !open_ubi(c, output);
 
 	if (out_ubi) {
 		c->min_io_size = c->di.min_io_size;
@@ -2248,81 +2225,6 @@ static int write_orphan_area(void)
 	return 0;
 }
 
-/**
- * check_volume_empty - check if the UBI volume is empty.
- *
- * This function checks if the UBI volume is empty by looking if its LEBs are
- * mapped or not.
- *
- * Returns %0 in case of success, %1 is the volume is not empty,
- * and a negative error code in case of failure.
- */
-static int check_volume_empty(void)
-{
-	int lnum, err;
-
-	for (lnum = 0; lnum < c->vi.rsvd_lebs; lnum++) {
-		err = ubi_is_mapped(out_fd, lnum);
-		if (err < 0)
-			return err;
-		if (err == 1)
-			return 1;
-	}
-	return 0;
-}
-
-/**
- * open_target - open the output target.
- *
- * Open the output target. The target can be an UBI volume
- * or a file.
- *
- * Returns %0 in case of success and %-1 in case of failure.
- */
-static int open_target(void)
-{
-	if (out_ubi) {
-		out_fd = open(output, O_RDWR | O_EXCL);
-
-		if (out_fd == -1)
-			return sys_err_msg("cannot open the UBI volume '%s'",
-					   output);
-		if (ubi_set_property(out_fd, UBI_VOL_PROP_DIRECT_WRITE, 1))
-			return sys_err_msg("ubi_set_property failed");
-
-		if (!yes && check_volume_empty()) {
-			if (!prompt("UBI volume is not empty.  Format anyways?", false))
-				return err_msg("UBI volume is not empty");
-		}
-	} else {
-		out_fd = open(output, O_CREAT | O_RDWR | O_TRUNC,
-			      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
-		if (out_fd == -1)
-			return sys_err_msg("cannot create output file '%s'",
-					   output);
-	}
-	return 0;
-}
-
-
-/**
- * close_target - close the output target.
- *
- * Close the output target. If the target was an UBI
- * volume, also close libubi.
- *
- * Returns %0 in case of success and %-1 in case of failure.
- */
-static int close_target(void)
-{
-	if (ubi)
-		libubi_close(ubi);
-	if (out_fd >= 0 && close(out_fd) == -1)
-		return sys_err_msg("cannot close the target '%s'", output);
-	if (output)
-		free(output);
-	return 0;
-}
 
 /**
  * init - initialize things.
@@ -2473,7 +2375,7 @@ int main(int argc, char *argv[])
 	if (err)
 		return err;
 
-	err = open_target();
+	err = open_target(c, yes);
 	if (err)
 		return err;
 
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 08/27] ubifs: introduce a new tool ubifs_dump
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (6 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 07/27] ubifs: move more functions into io lib Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 09/27] ubifs: introduce list.h Dongsheng Yang
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Init a new tool named as ubifs_dump

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 Makefile                            |  8 ++++-
 ubifs-utils/ubifs_dump/ubifs_dump.c | 68 +++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 ubifs-utils/ubifs_dump/ubifs_dump.c

diff --git a/Makefile b/Makefile
index ad0526f..a1aaa6e 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,8 @@ UBI_BINS = \
 	ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \
 	ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol ubiblock
 UBIFS_BINS = \
-	mkfs.ubifs/mkfs.ubifs
+	mkfs.ubifs/mkfs.ubifs \
+	ubifs_dump/ubifs_dump
 JFFSX_BINS = \
 	mkfs.jffs2 sumtool jffs2reader jffs2dump
 NAND_BINS = \
@@ -128,6 +129,11 @@ $(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)
+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)
+
 obj-mkfs.ubifs = $(UBIFS_LIBS)
 LDFLAGS_mkfs.ubifs = $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(UUIDLDFLAGS)
 LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid
diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c
new file mode 100644
index 0000000..bbe1269
--- /dev/null
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -0,0 +1,68 @@
+#include "ubifs_common.h"
+#define PROGRAM_NAME "ubifs-dump"
+#include "common.h"
+#include "io.h"
+
+static const char *optstring = "";
+
+static const struct option longopts[] = {
+	{NULL, 0, NULL, 0}
+};
+
+struct ubifs_info info_;
+static struct ubifs_info *c = &info_;
+
+static int get_options(int argc, char**argv)
+{
+	int opt, i;
+
+	while (1) {
+		opt = getopt_long(argc, argv, optstring, longopts, &i);
+		if (opt == -1)
+			break;
+		switch (opt) {
+		default:
+			break;
+		}
+	}
+
+	if (optind != argc && !output)
+		output = xstrdup(argv[optind]);
+
+	if (!output)
+		return err_msg("not output device or file specified");
+
+	if (open_ubi(c, output))
+		return err_msg("open ubi (%s) failed.", output);
+
+	return 0;
+}
+
+static int dump()
+{
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int err;
+
+	err = get_options(argc, argv);
+	if (err)
+		return err;
+	err = open_target(c, 1);
+	if (err)
+		return err;
+
+	err = dump();
+	if (err) {
+		close_target();
+		return err;
+	}
+
+	err = close_target();
+	if (err)
+		return err;
+
+	return 0;
+}
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 09/27] ubifs: introduce list.h
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (7 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 08/27] ubifs: introduce a new tool ubifs_dump Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 10/27] ubifs: copy some important data in ubifs.h from kernel to ubifs-utils Dongsheng Yang
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Copy the list.h from kernel to ubifs-utils/

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/list.h | 484 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 484 insertions(+)
 create mode 100644 ubifs-utils/include/list.h

diff --git a/ubifs-utils/include/list.h b/ubifs-utils/include/list.h
new file mode 100644
index 0000000..0cffa33
--- /dev/null
+++ b/ubifs-utils/include/list.h
@@ -0,0 +1,484 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+#define LIST_POISON1  ((struct list_head *) 0x00100100)
+#define LIST_POISON2  ((struct list_head *) 0x00200200)
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_add(struct list_head *xnew,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	next->prev = xnew;
+	xnew->next = next;
+	xnew->prev = prev;
+	prev->next = xnew;
+}
+#else
+extern void __list_add(struct list_head *xnew,
+			      struct list_head *prev,
+			      struct list_head *next);
+#endif
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void list_add(struct list_head *xnew, struct list_head *head)
+{
+	__list_add(xnew, head, head->next);
+}
+#else
+extern void list_add(struct list_head *xnew, struct list_head *head);
+#endif
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *xnew, struct list_head *head)
+{
+	__list_add(xnew, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void list_del(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	entry->next = LIST_POISON1;
+	entry->prev = LIST_POISON2;
+}
+#else
+extern void list_del(struct list_head *entry);
+#endif
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ * Note: if 'old' was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+				struct list_head *xnew)
+{
+	xnew->next = old->next;
+	xnew->next->prev = xnew;
+	xnew->prev = old->prev;
+	xnew->prev->next = xnew;
+}
+
+static inline void list_replace_init(struct list_head *old,
+					struct list_head *xnew)
+{
+	list_replace(old, xnew);
+	INIT_LIST_HEAD(old);
+}
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+        __list_del(list->prev, list->next);
+        list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+				  struct list_head *head)
+{
+        __list_del(list->prev, list->next);
+        list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+				const struct list_head *head)
+{
+	return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+	struct list_head *next = head->next;
+	return (next == head) && (next == head->prev);
+}
+
+static inline void __list_splice(const struct list_head *list,
+				 struct list_head *prev,
+				 struct list_head *next)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+
+	first->prev = prev;
+	prev->next = first;
+
+	last->next = next;
+	next->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+				struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head, head->next);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+					 struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head->prev, head);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:	the list head to take the element from.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+/**
+ * list_next_entry - get the next element from a list
+ * @ptr:	the list head to take the element from.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Note, that next is expected to be not null.
+ */
+#define list_next_entry(ptr, member) \
+	list_entry((ptr)->member.next, typeof(*ptr), member)
+
+/**
+ * list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); \
+        	pos = pos->next)
+
+/**
+ * __list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev	-	iterate over a list backwards
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+	for (pos = (head)->prev; pos != (head); \
+        	pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry	-	iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)			\
+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue
+ * @pos:	the type * to use as a start point
+ * @head:	the head of the list
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue.
+ */
+#define list_prepare_entry(pos, head, member) \
+	((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) 			\
+	for (; &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
+		n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) 			\
+	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
+	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
+		n = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+#endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 10/27] ubifs: copy some important data in ubifs.h from kernel to ubifs-utils
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (8 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 09/27] ubifs: introduce list.h Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 11/27] ubifs: copy some important functions in key.h " Dongsheng Yang
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

There are some definitions in ubifs.h in kernel we need but
not in userspace currently. Then copy it here.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/ubifs.h | 96 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/ubifs-utils/include/ubifs.h b/ubifs-utils/include/ubifs.h
index 2f080a8..1678663 100644
--- a/ubifs-utils/include/ubifs.h
+++ b/ubifs-utils/include/ubifs.h
@@ -25,6 +25,10 @@
 #ifndef __UBIFS_H__
 #define __UBIFS_H__
 
+#include "defs.h"
+#include "list.h"
+#include "libubi.h"
+
 /* Maximum logical eraseblock size in bytes */
 #define UBIFS_MAX_LEB_SZ (2*1024*1024)
 
@@ -34,6 +38,7 @@
 /* Largest key size supported in this implementation */
 #define CUR_MAX_KEY_LEN UBIFS_SK_LEN
 
+#define NONDATA_JHEADS_CNT 2
 /*
  * There is no notion of truncation key because truncation nodes do not exist
  * in TNC. However, when replaying, it is handy to introduce fake "truncation"
@@ -41,6 +46,7 @@
  * %UBIFS_TRUN_KEY type.
  */
 #define UBIFS_TRUN_KEY UBIFS_KEY_TYPES_CNT
+#define UBIFS_INVALID_KEY UBIFS_KEY_TYPES_CNT
 
 /*
  * How much a directory entry/extended attribute entry adds to the parent/host
@@ -94,25 +100,34 @@ enum {
  * @free: amount of free space in bytes
  * @dirty: amount of dirty space in bytes
  * @flags: LEB properties flags (see above)
+ * @lnum: LEB number
+ * @list: list of same-category lprops (for LPROPS_EMPTY and LPROPS_FREEABLE)
+ * @hpos: heap position in heap of same-category lprops (other categories)
  */
-struct ubifs_lprops
-{
+struct ubifs_lprops {
 	int free;
 	int dirty;
 	int flags;
+	int lnum;
+	union {
+		struct list_head list;
+		int hpos;
+	};
 };
 
 /**
  * struct ubifs_lpt_lprops - LPT logical eraseblock properties.
  * @free: amount of free space in bytes
  * @dirty: amount of dirty space in bytes
+ * @tgc: trivial GC flag (1 => unmap after commit end)
+ * @cmt: commit flag (1 => reserved for commit)
  */
-struct ubifs_lpt_lprops
-{
+struct ubifs_lpt_lprops {
 	int free;
 	int dirty;
+	unsigned tgc:1;
+	unsigned cmt:1;
 };
-
 struct ubifs_nnode;
 
 /**
@@ -263,6 +278,12 @@ struct ubifs_znode
 	struct ubifs_zbranch zbranch[];
 };
 
+enum {
+	LPT_SCAN_CONTINUE = 0,
+	LPT_SCAN_ADD = 1,
+	LPT_SCAN_STOP = 2,
+};
+
 /**
  * struct ubifs_info - UBIFS file-system description data structure
  * (per-superblock).
@@ -401,6 +422,7 @@ struct ubifs_info
 	int pnode_cnt;
 	int nnode_cnt;
 	int lpt_hght;
+	void *lpt_nod_buf;
 
 	int lpt_lnum;
 	int lpt_offs;
@@ -420,8 +442,68 @@ struct ubifs_info
 	int *lsave;
 	int lscan_lnum;
 
+	struct ubifs_nnode *nroot;
+	struct ubifs_cnode *lpt_cnext;
+
+	int min_idx_node_sz;
+	int max_idx_node_sz;
+
+	int max_znode_sz;
+};
+/**
+ * struct ubifs_scan_node - UBIFS scanned node information.
+ * @list: list of scanned nodes
+ * @key: key of node scanned (if it has one)
+ * @sqnum: sequence number
+ * @type: type of node scanned
+ * @offs: offset with LEB of node scanned
+ * @len: length of node scanned
+ * @node: raw node
+ */
+struct ubifs_scan_node {
+	struct list_head list;
+	union ubifs_key key;
+	unsigned long long sqnum;
+	int type;
+	int offs;
+	int len;
+	void *node;
+};
+
+/**
+ * struct ubifs_scan_leb - UBIFS scanned LEB information.
+ * @lnum: logical eraseblock number
+ * @nodes_cnt: number of nodes scanned
+ * @nodes: list of struct ubifs_scan_node
+ * @endpt: end point (and therefore the start of empty space)
+ * @buf: buffer containing entire LEB scanned
+ */
+struct ubifs_scan_leb {
+	int lnum;
+	int nodes_cnt;
+	struct list_head nodes;
+	int endpt;
+	void *buf;
 };
 
+/*
+ * 'ubifs_scan_a_node()' return values.
+ *
+ * SCANNED_GARBAGE:  scanned garbage
+ * SCANNED_EMPTY_SPACE: scanned empty space
+ * SCANNED_A_NODE: scanned a valid node
+ * SCANNED_A_CORRUPT_NODE: scanned a corrupted node
+ * SCANNED_A_BAD_PAD_NODE: scanned a padding node with invalid pad length
+ *
+ * Greater than zero means: 'scanned that number of padding bytes'
+ */
+enum {
+	SCANNED_GARBAGE        = 0,
+	SCANNED_EMPTY_SPACE    = -1,
+	SCANNED_A_NODE         = -2,
+	SCANNED_A_CORRUPT_NODE = -3,
+	SCANNED_A_BAD_PAD_NODE = -4,
+};
 /**
  * ubifs_idx_node_sz - return index node size.
  * @c: the UBIFS file-system description object
@@ -447,4 +529,8 @@ struct ubifs_branch *ubifs_idx_branch(const struct ubifs_info *c,
 				       (UBIFS_BRANCH_SZ + c->key_len) * bnum);
 }
 
+/* Callback used by the 'ubifs_lpt_scan_nolock()' function */
+typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c,
+				       const struct ubifs_lprops *lprops,
+				       int in_tree, void *data);
 #endif /* __UBIFS_H__ */
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 11/27] ubifs: copy some important functions in key.h from kernel to ubifs-utils
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (9 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 10/27] ubifs: copy some important data in ubifs.h from kernel to ubifs-utils Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 12/27] ubifs: ubifs_dump: add dump_ch and dump_node functions Dongsheng Yang
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

We need some more functions in key.h, then copy it from kernel.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/key.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/ubifs-utils/include/key.h b/ubifs-utils/include/key.h
index 39379fd..1b61928 100644
--- a/ubifs-utils/include/key.h
+++ b/ubifs-utils/include/key.h
@@ -37,6 +37,8 @@
 #ifndef __UBIFS_KEY_H__
 #define __UBIFS_KEY_H__
 
+#include "defs.h"
+
 /**
  * key_mask_hash - mask a valid hash value.
  * @val: value to be masked
@@ -107,7 +109,7 @@ static inline void ino_key_init(union ubifs_key *key, ino_t inum)
  * @inum: parent inode number
  * @nm: direntry name and length
  */
-static inline void dent_key_init(const struct ubifs_info *c,
+static inline void dent_key_init(const struct ubifs_info *c __attribute__((unused)),
 				 union ubifs_key *key, ino_t inum,
 				 const struct qstr *nm)
 {
@@ -204,4 +206,76 @@ static inline int keys_cmp(const union ubifs_key *key1,
 	return 0;
 }
 
+/**
+ * key_read - transform a key to in-memory format.
+ * @c: UBIFS file-system description object
+ * @from: the key to transform
+ * @to: the key to store the result
+ */
+static inline void key_read(const struct ubifs_info *c __attribute__((unused)), const void *from,
+			    union ubifs_key *to)
+{
+	const union ubifs_key *f = from;
+
+	to->u32[0] = le32_to_cpu(f->j32[0]);
+	to->u32[1] = le32_to_cpu(f->j32[1]);
+}
+
+/**
+ * invalid_key_init - initialize invalid node key.
+ * @c: UBIFS file-system description object
+ * @key: key to initialize
+ *
+ * This is a helper function which marks a @key object as invalid.
+ */
+static inline void invalid_key_init(const struct ubifs_info *c __attribute__((unused)),
+				    union ubifs_key *key)
+{
+	key->u32[0] = 0xDEADBEAF;
+	key->u32[1] = UBIFS_INVALID_KEY;
+}
+/**
+ * key_type - get key type.
+ * @c: UBIFS file-system description object
+ * @key: key to get type of
+ */
+static inline int key_type(const struct ubifs_info *c __attribute__((unused)),
+			   const union ubifs_key *key)
+{
+	return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS;
+}
+
+/*
+ * key_hash - get directory entry hash.
+ * @c: UBIFS file-system description object
+ * @key: the key to get hash from
+ */
+static inline uint32_t key_hash(const struct ubifs_info *c __attribute__((unused)),
+				const union ubifs_key *key)
+{
+	return key->u32[1] & UBIFS_S_KEY_HASH_MASK;
+}
+
+/**
+ * key_inum - fetch inode number from key.
+ * @c: UBIFS file-system description object
+ * @k: key to fetch inode number from
+ */
+static inline ino_t key_inum(const struct ubifs_info *c __attribute__((unused)), const void *k)
+{
+	const union ubifs_key *key = k;
+
+	return key->u32[0];
+}
+
+/**
+ * key_block - get data block number.
+ * @c: UBIFS file-system description object
+ * @key: the key to get the block number from
+ */
+static inline unsigned int key_block(const struct ubifs_info *c __attribute__((unused)),
+				     const union ubifs_key *key)
+{
+	return key->u32[1] & UBIFS_S_KEY_BLOCK_MASK;
+}
 #endif /* !__UBIFS_KEY_H__ */
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 12/27] ubifs: ubifs_dump: add dump_ch and dump_node functions
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (10 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 11/27] ubifs: copy some important functions in key.h " Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 13/27] ubifs: defs.h: introduce some compatible definition for printk class Dongsheng Yang
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/ubifs_dump/ubifs_dump.c | 337 ++++++++++++++++++++++++++++++++++++
 1 file changed, 337 insertions(+)

diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c
index bbe1269..a510aeb 100644
--- a/ubifs-utils/ubifs_dump/ubifs_dump.c
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -1,7 +1,11 @@
 #include "ubifs_common.h"
 #define PROGRAM_NAME "ubifs-dump"
 #include "common.h"
+
 #include "io.h"
+#include "key.h"
+
+#define DBG_KEY_BUF_LEN		48
 
 static const char *optstring = "";
 
@@ -38,6 +42,339 @@ static int get_options(int argc, char**argv)
 	return 0;
 }
 
+static const char *node_type_to_str[] = {
+		"UBIFS_INO_NODE",
+		"UBIFS_DATA_NODE",
+		"UBIFS_DENT_NODE",
+		"UBIFS_XENT_NODE",
+		"UBIFS_TRUN_NODE",
+		"UBIFS_PAD_NODE",
+		"UBIFS_SB_NODE",
+		"UBIFS_MST_NODE",
+		"UBIFS_REF_NODE",
+		"UBIFS_IDX_NODE",
+		"UBIFS_CS_NODE",
+		"UBIFS_ORPH_NODE"
+};
+
+static const char *get_key_type(int type)
+{
+	return node_type_to_str[type];
+}
+
+static const char *group_type_to_str[] = {
+		"UBIFS_NO_NODE_GROUP",
+		"UBIFS_IN_NODE_GROUP",
+		"UBIFS_LAST_OF_NODE_GROUP"
+};
+
+static const char *hash_type_to_str[] = {
+		"UBIFS_KEY_HASH_R5",
+		"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"
+};
+
+const char *dbg_snprintf_key(const struct ubifs_info *c,
+			     const union ubifs_key *key, char *buffer, int len)
+{
+	char *p = buffer;
+	int type = key_type(c, key);
+
+	if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) {
+		switch (type) {
+
+		case UBIFS_INO_KEY:
+			len -= snprintf(p, len, "(%lu, %s)",
+					(unsigned long)key_inum(c, key),
+					get_key_type(type));
+			break;
+		case UBIFS_DENT_KEY:
+		case UBIFS_XENT_KEY:
+			len -= snprintf(p, len, "(%lu, %s, %#08x)",
+					(unsigned long)key_inum(c, key),
+					get_key_type(type), key_hash(c, key));
+			break;
+		case UBIFS_DATA_KEY:
+			len -= snprintf(p, len, "(%lu, %s, %u)",
+					(unsigned long)key_inum(c, key),
+					get_key_type(type), key_block(c, key));
+			break;
+		case UBIFS_TRUN_KEY:
+			len -= snprintf(p, len, "(%lu, %s)",
+					(unsigned long)key_inum(c, key),
+					get_key_type(type));
+			break;
+		default:
+			len -= snprintf(p, len, "(bad key type: %#08x, %#08x)",
+					key->u32[0], key->u32[1]);
+		}
+	} else
+		len -= snprintf(p, len, "bad key format %d", c->key_fmt);
+	ubifs_assert(len > 0);
+	return p;
+}
+
+static void show_ch(const struct ubifs_ch *ch) 
+{ 
+	printf("\tCommon header: \n");
+        printf("\tmagic \t\t\t\t%#x\n", le32_to_cpu(ch->magic)); 
+        printf("\tcrc \t\t\t\t%#x\n", le32_to_cpu(ch->crc)); 
+        printf("\tnode_type \t\t\t%d (%s)\n", ch->node_type, 
+               node_type_to_str[ch->node_type]); 
+        printf("\tgroup_type \t\t\t%d (%s)\n", ch->group_type, 
+               group_type_to_str[ch->group_type]); 
+        printf("\tsqnum \t\t\t\t%llu\n", 
+               (unsigned long long)le64_to_cpu(ch->sqnum)); 
+        printf("\tlen \t\t\t\t%u\n", le32_to_cpu(ch->len)); 
+} 
+
+void dump_node(const struct ubifs_info *c, const void *node)
+{
+	int i, n;
+	union ubifs_key key;
+	const struct ubifs_ch *ch = node;
+	char key_buf[DBG_KEY_BUF_LEN];
+
+	show_ch(node);
+
+	switch (ch->node_type) {
+	case UBIFS_PAD_NODE:
+	{
+		const struct ubifs_pad_node *pad = node;
+
+		printf("\t\tpad_len \t\t\t%u\n", le32_to_cpu(pad->pad_len));
+		break;
+	}
+	case UBIFS_SB_NODE:
+	{
+		const struct ubifs_sb_node *sup = node;
+		unsigned int sup_flags = le32_to_cpu(sup->flags);
+		char uuid[40];
+
+		uuid_unparse_upper(sup->uuid, uuid);
+		printf("\t\tUUID \t\t\t\t%s\n", uuid);
+		printf("\t\tkey_hash \t\t\t%d (%s)\n",
+		       (int)sup->key_hash, hash_type_to_str[sup->key_hash]);
+		printf("\t\tkey_fmt \t\t\t%d (%s)\n",
+		       (int)sup->key_fmt, key_fmt_to_str[sup->key_fmt]);
+		printf("\t\tflags \t\t\t\t%#x\n", sup_flags);
+		printf("\t\tbig_lpt \t\t\t%u\n",
+		       !!(sup_flags & UBIFS_FLG_BIGLPT));
+		printf("\t\tspace_fixup \t\t\t%u\n",
+		       !!(sup_flags & UBIFS_FLG_SPACE_FIXUP));
+		printf("\t\tmin_io_size \t\t\t%u\n", le32_to_cpu(sup->min_io_size));
+		printf("\t\tleb_size \t\t\t%u\n", le32_to_cpu(sup->leb_size));
+		printf("\t\tleb_cnt \t\t\t%u\n", le32_to_cpu(sup->leb_cnt));
+		printf("\t\tmax_leb_cnt \t\t\t%u\n", le32_to_cpu(sup->max_leb_cnt));
+		printf("\t\tmax_bud_bytes \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(sup->max_bud_bytes));
+		printf("\t\tlog_lebs \t\t\t%u\n", le32_to_cpu(sup->log_lebs));
+		printf("\t\tlpt_lebs \t\t\t%u\n", le32_to_cpu(sup->lpt_lebs));
+		printf("\t\torph_lebs \t\t\t%u\n", le32_to_cpu(sup->orph_lebs));
+		printf("\t\tjhead_cnt \t\t\t%u\n", le32_to_cpu(sup->jhead_cnt));
+		printf("\t\tfanout \t\t\t\t%u\n", le32_to_cpu(sup->fanout));
+		printf("\t\tlsave_cnt \t\t\t%u\n", le32_to_cpu(sup->lsave_cnt));
+		printf("\t\tdefault_compr \t\t\t%u\n",
+		       (int)le16_to_cpu(sup->default_compr));
+		printf("\t\trp_size \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(sup->rp_size));
+		printf("\t\trp_uid \t\t\t\t%u\n", le32_to_cpu(sup->rp_uid));
+		printf("\t\trp_gid \t\t\t\t%u\n", le32_to_cpu(sup->rp_gid));
+		printf("\t\tfmt_version \t\t\t%u\n", le32_to_cpu(sup->fmt_version));
+		printf("\t\ttime_gran \t\t\t%u\n", le32_to_cpu(sup->time_gran));
+		break;
+	}
+	case UBIFS_MST_NODE:
+	{
+		const struct ubifs_mst_node *mst = node;
+
+		printf("\t\thighest_inum \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->highest_inum));
+		printf("\t\tcommit number \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->cmt_no));
+		printf("\t\tflags \t\t\t\t%#x\n", le32_to_cpu(mst->flags));
+		printf("\t\tlog_lnum \t\t\t%u\n", le32_to_cpu(mst->log_lnum));
+		printf("\t\troot_lnum \t\t\t%u\n", le32_to_cpu(mst->root_lnum));
+		printf("\t\troot_offs \t\t\t%u\n", le32_to_cpu(mst->root_offs));
+		printf("\t\troot_len \t\t\t%u\n", le32_to_cpu(mst->root_len));
+		printf("\t\tgc_lnum \t\t\t%u\n", le32_to_cpu(mst->gc_lnum));
+		printf("\t\tihead_lnum \t\t\t%u\n", le32_to_cpu(mst->ihead_lnum));
+		printf("\t\tihead_offs \t\t\t%u\n", le32_to_cpu(mst->ihead_offs));
+		printf("\t\tindex_size \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->index_size));
+		printf("\t\tlpt_lnum \t\t\t%u\n", le32_to_cpu(mst->lpt_lnum));
+		printf("\t\tlpt_offs \t\t\t%u\n", le32_to_cpu(mst->lpt_offs));
+		printf("\t\tnhead_lnum \t\t\t%u\n", le32_to_cpu(mst->nhead_lnum));
+		printf("\t\tnhead_offs \t\t\t%u\n", le32_to_cpu(mst->nhead_offs));
+		printf("\t\tltab_lnum \t\t\t%u\n", le32_to_cpu(mst->ltab_lnum));
+		printf("\t\tltab_offs \t\t\t%u\n", le32_to_cpu(mst->ltab_offs));
+		printf("\t\tlsave_lnum \t\t\t%u\n", le32_to_cpu(mst->lsave_lnum));
+		printf("\t\tlsave_offs \t\t\t%u\n", le32_to_cpu(mst->lsave_offs));
+		printf("\t\tlscan_lnum \t\t\t%u\n", le32_to_cpu(mst->lscan_lnum));
+		printf("\t\tleb_cnt \t\t\t%u\n", le32_to_cpu(mst->leb_cnt));
+		printf("\t\tempty_lebs \t\t\t%u\n", le32_to_cpu(mst->empty_lebs));
+		printf("\t\tidx_lebs \t\t\t%u\n", le32_to_cpu(mst->idx_lebs));
+		printf("\t\ttotal_free \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->total_free));
+		printf("\t\ttotal_dirty \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->total_dirty));
+		printf("\t\ttotal_used \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->total_used));
+		printf("\t\ttotal_dead \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->total_dead));
+		printf("\t\ttotal_dark \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(mst->total_dark));
+		break;
+	}
+	case UBIFS_REF_NODE:
+	{
+		const struct ubifs_ref_node *ref = node;
+
+		printf("\t\tlnum \t\t\t\t%u\n", le32_to_cpu(ref->lnum));
+		printf("\t\toffs \t\t\t\t%u\n", le32_to_cpu(ref->offs));
+		printf("\t\tjhead \t\t\t\t%u\n", le32_to_cpu(ref->jhead));
+		break;
+	}
+	case UBIFS_INO_NODE:
+	{
+		const struct ubifs_ino_node *ino = node;
+
+		key_read(c, &ino->key, &key);
+		printf("\t\tkey \t\t\t%s\n",
+		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
+		printf("\t\tcreat_sqnum \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(ino->creat_sqnum));
+		printf("\t\tsize \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(ino->size));
+		printf("\t\tnlink \t\t\t%u\n", le32_to_cpu(ino->nlink));
+		printf("\t\tatime \t\t\t%lld.%u\n",
+		       (long long)le64_to_cpu(ino->atime_sec),
+		       le32_to_cpu(ino->atime_nsec));
+		printf("\t\tmtime \t\t\t%lld.%u\n",
+		       (long long)le64_to_cpu(ino->mtime_sec),
+		       le32_to_cpu(ino->mtime_nsec));
+		printf("\t\tctime \t\t\t%lld.%u\n",
+		       (long long)le64_to_cpu(ino->ctime_sec),
+		       le32_to_cpu(ino->ctime_nsec));
+		printf("\t\tuid \t\t\t%u\n", le32_to_cpu(ino->uid));
+		printf("\t\tgid \t\t\t%u\n", le32_to_cpu(ino->gid));
+		printf("\t\tmode \t\t\t%u\n", le32_to_cpu(ino->mode));
+		printf("\t\tflags \t\t\t%#x\n", le32_to_cpu(ino->flags));
+		printf("\t\txattr_cnt \t\t\t%u\n", le32_to_cpu(ino->xattr_cnt));
+		printf("\t\txattr_size \t\t\t%u\n", le32_to_cpu(ino->xattr_size));
+		printf("\t\txattr_names \t\t\t%u\n", le32_to_cpu(ino->xattr_names));
+		printf("\t\tcompr_type \t\t\t%#x\n",
+		       (int)le16_to_cpu(ino->compr_type));
+		printf("\t\tdata len \t\t\t%u\n", le32_to_cpu(ino->data_len));
+		break;
+	}
+	case UBIFS_DENT_NODE:
+	case UBIFS_XENT_NODE:
+	{
+		const struct ubifs_dent_node *dent = node;
+		int nlen = le16_to_cpu(dent->nlen);
+
+		key_read(c, &dent->key, &key);
+		printf("\t\tkey \t\t\t%s\n",
+		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
+		printf("\t\tinum \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(dent->inum));
+		printf("\t\ttype \t\t\t%d\n", (int)dent->type);
+		printf("\t\tnlen \t\t\t%d\n", nlen);
+		printf("\t\tname           ");
+
+		if (nlen > UBIFS_MAX_NLEN)
+			printf("(bad name length, not printing, bad or corrupted node)");
+		else {
+			for (i = 0; i < nlen && dent->name[i]; i++)
+				printf("%c", dent->name[i]);
+		}
+		printf("\n");
+
+		break;
+	}
+	case UBIFS_DATA_NODE:
+	{
+		const struct ubifs_data_node *dn = node;
+		int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
+
+		key_read(c, &dn->key, &key);
+		printf("\t\tkey \t\t\t%s\n",
+		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
+		printf("\t\tsize \t\t\t%u\n", le32_to_cpu(dn->size));
+		printf("\t\tcompr_typ \t\t\t%d\n",
+		       (int)le16_to_cpu(dn->compr_type));
+		printf("\t\tdata size \t\t\t%d\n", dlen);
+		break;
+	}
+	case UBIFS_TRUN_NODE:
+	{
+		const struct ubifs_trun_node *trun = node;
+
+		printf("\t\tinum \t\t\t%u\n", le32_to_cpu(trun->inum));
+		printf("\t\told_size \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(trun->old_size));
+		printf("\t\tnew_size \t\t\t%llu\n",
+		       (unsigned long long)le64_to_cpu(trun->new_size));
+		break;
+	}
+	case UBIFS_IDX_NODE:
+	{
+		const struct ubifs_idx_node *idx = node;
+
+		n = le16_to_cpu(idx->child_cnt);
+		printf("\t\tchild_cnt \t\t%d\n", n);
+		printf("\t\tlevel \t\t\t%d\n", (int)le16_to_cpu(idx->level));
+		printf("\t\tBranches:\n");
+
+		for (i = 0; i < n && i < c->fanout - 1; i++) {
+			const struct ubifs_branch *br;
+
+			br = ubifs_idx_branch(c, idx, i);
+			key_read(c, &br->key, &key);
+			printf("\t\t%d: LEB %d:%d len %d key %s\n",
+			       i, le32_to_cpu(br->lnum), le32_to_cpu(br->offs),
+			       le32_to_cpu(br->len),
+			       dbg_snprintf_key(c, &key, key_buf,
+						DBG_KEY_BUF_LEN));
+		}
+		break;
+	}
+	case UBIFS_CS_NODE:
+		break;
+	case UBIFS_ORPH_NODE:
+	{
+		const struct ubifs_orph_node *orph = node;
+
+		printf("\t\tcommit number \t\t\t%llu\n",
+		       (unsigned long long)
+				le64_to_cpu(orph->cmt_no) & LLONG_MAX);
+		printf("\t\tlast node flag \t\t\t%llu\n",
+		       (unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63);
+		n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3;
+		printf("\t\t%d orphan inode numbers:\n", n);
+		for (i = 0; i < n; i++)
+			printf("\t\t  ino \t\t\t%llu\n",
+			       (unsigned long long)le64_to_cpu(orph->inos[i]));
+		break;
+	}
+	default:
+		printf("node type \t\t\t%d was not recognized\n",
+		       (int)ch->node_type);
+	}
+	printf("\n");
+}
+
 static int dump()
 {
 	return 0;
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 13/27] ubifs: defs.h: introduce some compatible definition for printk class
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (11 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 12/27] ubifs: ubifs_dump: add dump_ch and dump_node functions Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 14/27] ubifs: io: introduce ubifs_read function to read ubi volume Dongsheng Yang
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

There are some functions of printk class in code copied from kernel.
Then add a compatible definitions in defs.h for them.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/defs.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/ubifs-utils/include/defs.h b/ubifs-utils/include/defs.h
index 1fa3316..739af7f 100644
--- a/ubifs-utils/include/defs.h
+++ b/ubifs-utils/include/defs.h
@@ -81,6 +81,15 @@ __res = ((unsigned long) n) % (unsigned) base; \
 n = ((unsigned long) n) / (unsigned) base; \
 __res; })
 
+/*
+ * printk
+ */
+#define printk(fmt, args...) fprintf(stderr, fmt, ##args)
+#define	KERN_CRIT	""
+#define KERN_ERR	""
+#define ubifs_err(c, fmt, args...) printk(fmt, ##args)
+#define pr_err(fmt, args...) printk(fmt, ##args)
+
 #if INT_MAX != 0x7fffffff
 #error : sizeof(int) must be 4 for this program
 #endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 14/27] ubifs: io: introduce ubifs_read function to read ubi volume
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (12 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 13/27] ubifs: defs.h: introduce some compatible definition for printk class Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 15/27] ubifs: ubifs_dump: dump super block Dongsheng Yang
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Implement a ubifs_read function in io lib. This function
will read the data at offset in length of len from ubi volume
to buf.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/io.h |  2 ++
 ubifs-utils/lib/io.c     | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/ubifs-utils/include/io.h b/ubifs-utils/include/io.h
index 920645d..11f568c 100644
--- a/ubifs-utils/include/io.h
+++ b/ubifs-utils/include/io.h
@@ -16,4 +16,6 @@ int write_leb(struct ubifs_info *c, int lnum, int len, void *buf);
 int close_target(void);
 int open_target(struct ubifs_info *c, int yes);
 int open_ubi(struct ubifs_info *c, const char *node);
+
+int ubifs_read(loff_t offset, int len, void *buf);
 #endif
diff --git a/ubifs-utils/lib/io.c b/ubifs-utils/lib/io.c
index 9817d2a..d05cf86 100644
--- a/ubifs-utils/lib/io.c
+++ b/ubifs-utils/lib/io.c
@@ -132,3 +132,21 @@ int write_leb(struct ubifs_info *c, int lnum, int len, void *buf)
 
 	return 0;
 }
+
+/**
+ * ubifs_read - read data from ubi volume.
+ * @offset: offset of data in volume
+ * @len: length of data in the buffer
+ * @buf: buffer (must be at least c->leb_size bytes)
+ */
+int ubifs_read(loff_t offset, int len, void *buf)
+{
+	if (lseek(out_fd, offset, SEEK_SET) != offset)
+		return sys_err_msg("lseek failed seeking %"PRIdoff_t, offset);
+
+	if (read(out_fd, buf, len) != len)
+		return sys_err_msg("write failed writing %d bytes at pos %"PRIdoff_t,
+				   len, offset);
+
+	return 0;
+}
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 15/27] ubifs: ubifs_dump: dump super block
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (13 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 14/27] ubifs: io: introduce ubifs_read function to read ubi volume Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 16/27] ubifs: introduce scan for ubifs-utils Dongsheng Yang
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Read the super block from ubi volume and dump it out.

Signed-off-by: Dongsheng Yang <yangds.fnst@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

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 16/27] ubifs: introduce scan for ubifs-utils
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (14 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 15/27] ubifs: ubifs_dump: dump super block Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 17/27] ubifs: add some more compatible definitions in defs.h Dongsheng Yang
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

It's a lib to scan a leb.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/scan.h |   8 ++
 ubifs-utils/lib/scan.c     | 318 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 326 insertions(+)
 create mode 100644 ubifs-utils/include/scan.h
 create mode 100644 ubifs-utils/lib/scan.c

diff --git a/ubifs-utils/include/scan.h b/ubifs-utils/include/scan.h
new file mode 100644
index 0000000..8447adf
--- /dev/null
+++ b/ubifs-utils/include/scan.h
@@ -0,0 +1,8 @@
+#ifndef __UBIFS_SCAN_H__
+#define __UBIFS_SCAN_H__
+
+struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
+				  int offs, void *sbuf, int quiet);
+
+void ubifs_scan_destroy(struct ubifs_scan_leb *sleb);
+#endif
diff --git a/ubifs-utils/lib/scan.c b/ubifs-utils/lib/scan.c
new file mode 100644
index 0000000..69c84d1
--- /dev/null
+++ b/ubifs-utils/lib/scan.c
@@ -0,0 +1,318 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copied from kernel
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This file implements the scan which is a general-purpose function for
+ * determining what nodes are in an eraseblock. The scan is used to replay the
+ * journal, to do garbage collection. for the TNC in-the-gaps method, and by
+ * debugging functions.
+ */
+#include "ubifs_common.h"
+
+#include "ubifs.h"
+#define PROGRAM_NAME "ubifs_scan"
+#include "common.h"
+#include "key.h"
+#include "io.h"
+#include "scan.h"
+
+/**
+ * scan_padding_bytes - scan for padding bytes.
+ * @buf: buffer to scan
+ * @len: length of buffer
+ *
+ * This function returns the number of padding bytes on success and
+ * %SCANNED_GARBAGE on failure.
+ */
+static int scan_padding_bytes(void *buf, int len)
+{
+	int pad_len = 0, max_pad_len = min_t(int, UBIFS_PAD_NODE_SZ, len);
+	int *p = buf;
+
+	while (pad_len < max_pad_len && *p++ == UBIFS_PADDING_BYTE)
+		pad_len += 1;
+
+	if (!pad_len || (pad_len & 7)) {
+		return SCANNED_GARBAGE;
+	}
+
+	return pad_len;
+}
+
+/**
+ * ubifs_scan_a_node - scan for a node or padding.
+ * @c: UBIFS file-system description object
+ * @buf: buffer to scan
+ * @len: length of buffer
+ * @lnum: logical eraseblock number
+ * @offs: offset within the logical eraseblock
+ * @quiet: print no messages
+ *
+ * This function returns a scanning code to indicate what was scanned.
+ */
+int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len,
+		      int lnum __attribute__((unused)), int offs,
+		      int quiet __attribute__((unused)))
+{
+	struct ubifs_ch *ch = buf;
+	uint32_t magic;
+
+	magic = le32_to_cpu(ch->magic);
+
+	if (magic == 0xFFFFFFFF)
+		return SCANNED_EMPTY_SPACE;
+
+	if (magic != UBIFS_NODE_MAGIC)
+		return scan_padding_bytes(buf, len);
+
+	if (len < UBIFS_CH_SZ) {
+		return SCANNED_GARBAGE;
+	}
+
+	if (ch->node_type == UBIFS_PAD_NODE) {
+		struct ubifs_pad_node *pad = buf;
+		int pad_len = le32_to_cpu(pad->pad_len);
+		int node_len = le32_to_cpu(ch->len);
+
+		/* Validate the padding node */
+		if (pad_len < 0 ||
+		    offs + node_len + pad_len > c->leb_size) {
+			return SCANNED_A_BAD_PAD_NODE;
+		}
+
+		/* Make the node pads to 8-byte boundary */
+		if ((node_len + pad_len) & 7) {
+			return SCANNED_A_BAD_PAD_NODE;
+		}
+
+		return node_len + pad_len;
+	}
+
+	return SCANNED_A_NODE;
+}
+
+/**
+ * ubifs_start_scan - create LEB scanning information at start of scan.
+ * @c: UBIFS file-system description object
+ * @lnum: logical eraseblock number
+ * @offs: offset to start at (usually zero)
+ * @sbuf: scan buffer (must be c->leb_size)
+ *
+ * This function returns the scanned information on success and a negative error
+ * code on failure.
+ */
+struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,
+					int offs, void *sbuf)
+{
+	struct ubifs_scan_leb *sleb;
+	int err;
+
+	sleb = kzalloc(sizeof(struct ubifs_scan_leb), GFP_NOFS);
+	if (!sleb)
+		return ERR_PTR(-ENOMEM);
+
+	sleb->lnum = lnum;
+	INIT_LIST_HEAD(&sleb->nodes);
+	sleb->buf = sbuf;
+
+	err = ubifs_read(lnum * c->leb_size + offs, c->leb_size - offs, sbuf + offs);
+	if (err && err != -EBADMSG) {
+		kfree(sleb);
+		return ERR_PTR(err);
+	}
+
+	/*
+	 * Note, we ignore integrity errors (EBASMSG) because all the nodes are
+	 * protected by CRC checksums.
+	 */
+	return sleb;
+}
+
+/**
+ * ubifs_end_scan - update LEB scanning information at end of scan.
+ * @c: UBIFS file-system description object
+ * @sleb: scanning information
+ * @lnum: logical eraseblock number
+ * @offs: offset to start at (usually zero)
+ */
+void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,
+		    int lnum, int offs)
+{
+	lnum = lnum;
+	ubifs_assert(offs % c->min_io_size == 0);
+
+	sleb->endpt = ALIGN(offs, c->min_io_size);
+}
+
+/**
+ * ubifs_add_snod - add a scanned node to LEB scanning information.
+ * @c: UBIFS file-system description object
+ * @sleb: scanning information
+ * @buf: buffer containing node
+ * @offs: offset of node on flash
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,
+		   void *buf, int offs)
+{
+	struct ubifs_ch *ch = buf;
+	struct ubifs_ino_node *ino = buf;
+	struct ubifs_scan_node *snod;
+
+	snod = kmalloc(sizeof(struct ubifs_scan_node), GFP_NOFS);
+	if (!snod)
+		return -ENOMEM;
+
+	snod->sqnum = le64_to_cpu(ch->sqnum);
+	snod->type = ch->node_type;
+	snod->offs = offs;
+	snod->len = le32_to_cpu(ch->len);
+	snod->node = buf;
+
+	switch (ch->node_type) {
+	case UBIFS_INO_NODE:
+	case UBIFS_DENT_NODE:
+	case UBIFS_XENT_NODE:
+	case UBIFS_DATA_NODE:
+		/*
+		 * The key is in the same place in all keyed
+		 * nodes.
+		 */
+		key_read(c, &ino->key, &snod->key);
+		break;
+	default:
+		invalid_key_init(c, &snod->key);
+		break;
+	}
+	list_add_tail(&snod->list, &sleb->nodes);
+	sleb->nodes_cnt += 1;
+	return 0;
+}
+
+/**
+ * ubifs_scan - scan a logical eraseblock.
+ * @c: UBIFS file-system description object
+ * @lnum: logical eraseblock number
+ * @offs: offset to start at (usually zero)
+ * @sbuf: scan buffer (must be of @c->leb_size bytes in size)
+ * @quiet: print no messages
+ *
+ * This function scans LEB number @lnum and returns complete information about
+ * its contents. Returns the scanned information in case of success and,
+ * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case
+ * of failure.
+ *
+ * If @quiet is non-zero, this function does not print large and scary
+ * error messages and flash dumps in case of errors.
+ */
+struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
+				  int offs, void *sbuf, int quiet)
+{
+	void *buf = sbuf + offs;
+	int err, len = c->leb_size - offs;
+	struct ubifs_scan_leb *sleb;
+
+	sleb = ubifs_start_scan(c, lnum, offs, sbuf);
+	if (IS_ERR(sleb))
+		return sleb;
+
+	while (len >= 8) {
+		struct ubifs_ch *ch = buf;
+		int node_len, ret;
+
+		cond_resched();
+
+		ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet);
+		if (ret > 0) {
+			/* Padding bytes or a valid padding node */
+			offs += ret;
+			buf += ret;
+			len -= ret;
+			continue;
+		}
+
+		if (ret == SCANNED_EMPTY_SPACE)
+			/* Empty space is checked later */
+			break;
+
+		switch (ret) {
+		case SCANNED_GARBAGE:
+			if (offs == 0)
+				break;
+			goto corrupted;
+		case SCANNED_A_NODE:
+			break;
+		case SCANNED_A_CORRUPT_NODE:
+		case SCANNED_A_BAD_PAD_NODE:
+			goto corrupted;
+		default:
+			err = -EINVAL;
+			goto error;
+		}
+
+		err = ubifs_add_snod(c, sleb, buf, offs);
+		if (err)
+			goto error;
+
+		node_len = ALIGN(le32_to_cpu(ch->len), 8);
+		offs += node_len;
+		buf += node_len;
+		len -= node_len;
+	}
+
+	if (offs % c->min_io_size) {
+		goto corrupted;
+	}
+
+	ubifs_end_scan(c, sleb, lnum, offs);
+
+	for (; len > 2; offs += 2, buf = buf + 2, len -= 2)
+		if ((*(const uint8_t *)buf) != 0xff)
+			goto corrupted;
+
+	return sleb;
+
+corrupted:
+	err = -EUCLEAN;
+	ubifs_scan_destroy(sleb);
+	return ERR_PTR(err);
+
+error:
+	ubifs_scan_destroy(sleb);
+	return ERR_PTR(err);
+}
+
+/**
+ * ubifs_scan_destroy - destroy LEB scanning information.
+ * @sleb: scanning information to free
+ */
+void ubifs_scan_destroy(struct ubifs_scan_leb *sleb)
+{
+	struct ubifs_scan_node *node;
+	struct list_head *head;
+
+	head = &sleb->nodes;
+	while (!list_empty(head)) {
+		node = list_entry(head->next, struct ubifs_scan_node, list);
+		list_del(&node->list);
+		kfree(node);
+	}
+	kfree(sleb);
+}
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 17/27] ubifs: add some more compatible definitions in defs.h
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (15 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 16/27] ubifs: introduce scan for ubifs-utils Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 18/27] ubifs: ubifs_dump: dump master node Dongsheng Yang
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Add kmalloc class compatible definitions to defs.h.
Add error pointer class compatible definitions to defs.h.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/defs.h | 84 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/ubifs-utils/include/defs.h b/ubifs-utils/include/defs.h
index 739af7f..ed42ab1 100644
--- a/ubifs-utils/include/defs.h
+++ b/ubifs-utils/include/defs.h
@@ -6,6 +6,37 @@
 #ifndef __UBIFS_DEFS_H__
 #define __UBIFS_DEFS_H__
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <assert.h>
+#include <stddef.h>
+#include <linux/types.h>
+#include <stdint.h>
+
+#include <features.h>
+
+#ifndef __GLIBC__
+#define BTRFS_DISABLE_BACKTRACE
+#define __always_inline __inline __attribute__ ((__always_inline__))
+#endif
+
+#ifndef BTRFS_DISABLE_BACKTRACE
+#include <execinfo.h>
+#endif
+
+#define ptr_to_u64(x)	((u64)(uintptr_t)x)
+#define u64_to_ptr(x)	((void *)(uintptr_t)x)
+
+#ifndef READ
+#define READ 0
+#define WRITE 1
+#define READA 2
+#endif
+
 #define t16(x) ({ \
 	uint16_t __b = (x); \
 	(__LITTLE_ENDIAN==__BYTE_ORDER) ? __b : bswap_16(__b); \
@@ -82,6 +113,41 @@ n = ((unsigned long) n) / (unsigned) base; \
 __res; })
 
 /*
+ * error pointer
+ */
+#define MAX_ERRNO	4095
+#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO)
+
+static inline void *ERR_PTR(long error)
+{
+	return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+	return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+	return IS_ERR_VALUE((unsigned long)ptr);
+}
+
+#define cond_resched()		do { } while (0)
+#define preempt_enable()	do { } while (0)
+#define preempt_disable()	do { } while (0)
+
+/*
+ * kmalloc/kfree
+ */
+#define kmalloc(x, y) malloc(x)
+#define kzalloc(x, y) calloc(1, x)
+#define kstrdup(x, y) strdup(x)
+#define kfree(x) free(x)
+#define vmalloc(x) malloc(x)
+#define vfree(x) free(x)
+
+/*
  * printk
  */
 #define printk(fmt, args...) fprintf(stderr, fmt, ##args)
@@ -90,6 +156,24 @@ __res; })
 #define ubifs_err(c, fmt, args...) printk(fmt, ##args)
 #define pr_err(fmt, args...) printk(fmt, ##args)
 
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+	        (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#define gfp_t int
+#define get_cpu_var(p) (p)
+#define __get_cpu_var(p) (p)
+#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
+#define __GFP_BITS_SHIFT 20
+#define __GFP_BITS_MASK ((int)((1 << __GFP_BITS_SHIFT) - 1))
+#define GFP_KERNEL 0
+#define GFP_NOFS 0
+#define __read_mostly
+
+#ifndef ULONG_MAX
+#define ULONG_MAX       (~0UL)
+#endif
+
 #if INT_MAX != 0x7fffffff
 #error : sizeof(int) must be 4 for this program
 #endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 18/27] ubifs: ubifs_dump: dump master node
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (16 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 17/27] ubifs: add some more compatible definitions in defs.h Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 19/27] ubifs: ubifs_dump: dump log area Dongsheng Yang
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Search the master lebs and found the latest master node.
Then dump it out.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 Makefile                            |   1 +
 ubifs-utils/ubifs_dump/ubifs_dump.c | 139 +++++++++++++++++++++++++++++-------
 2 files changed, 115 insertions(+), 25 deletions(-)

diff --git a/Makefile b/Makefile
index a1aaa6e..1d7e5f2 100644
--- a/Makefile
+++ b/Makefile
@@ -130,6 +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
 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..4f67621 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,7 +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*/
@@ -376,26 +377,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 +479,128 @@ 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;
 	int err = 0;
 
-	err = init();
-	if (err)
+	lnum = UBIFS_MST_LNUM;
+
+	sleb = ubifs_scan(c, lnum, 0, leb_buf, 1);
+	if (IS_ERR(sleb))
+		return PTR_ERR(sleb);
+	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:
+	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;
 
+	leb_buf = malloc(c->leb_size);
+	if (!leb_buf) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = dump_master();
+	if (err)
+		goto free;
+free:
+	free(leb_buf);
 out:
-	deinit();
 	return err;
 }
 
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 19/27] ubifs: ubifs_dump: dump log area
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (17 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 18/27] ubifs: ubifs_dump: dump master node Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 20/27] ubifs: introduce lprops lib Dongsheng Yang
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

scan the log lebs and dump the log nodes out.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/ubifs_dump/ubifs_dump.c | 140 ++++++++++++++++++++++++++++++++++++
 1 file changed, 140 insertions(+)

diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c
index 4f67621..d7a2951 100644
--- a/ubifs-utils/ubifs_dump/ubifs_dump.c
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -581,6 +581,142 @@ static int dump_master(void)
 	return 0;
 }
 
+static int __dump_log_leb(int leb_num)
+{
+	int err = 0;
+	struct ubifs_scan_leb *sleb;
+	struct ubifs_scan_node *snod;
+	const struct ubifs_cs_node *node;
+	static int cs_sqnum = 0;
+	int lnum = leb_num;
+	loff_t offs = 0;
+	int node_num = 0;
+
+	sleb = ubifs_scan(c, lnum, offs, leb_buf, 0);
+	if (IS_ERR(sleb)) {
+		printf("Error in scaning log leb");
+		return PTR_ERR(sleb);
+	}
+
+	if (sleb->nodes_cnt == 0) {
+		err = 1;
+		goto out;
+	}
+
+	node = sleb->buf;
+	snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list);
+	if (cs_sqnum == 0) {
+		/*
+		 * This is the first log LEB we are looking at, make sure that
+		 * the first node is a commit start node. Also record its
+		 * sequence number so that UBIFS can determine where the log
+		 * ends, because all nodes which were have higher sequence
+		 * numbers.
+		 */
+		if (snod->type != UBIFS_CS_NODE) {
+			ubifs_err(c, "first log node at LEB %d:%lu is not CS node",
+				  lnum, offs);
+			goto out_dump;
+		}
+		if (le64_to_cpu(node->cmt_no) != mst.cmt_no) {
+			ubifs_err(c, "first CS node at LEB %d:%lu has wrong commit number %llu expected %llu",
+				  lnum, offs,
+				  (unsigned long long)le64_to_cpu(node->cmt_no),
+				  mst.cmt_no);
+			goto out_dump;
+		}
+
+		cs_sqnum = le64_to_cpu(node->ch.sqnum);
+	}
+
+	if (snod->sqnum < cs_sqnum) {
+		/*
+		 * This means that we reached end of log and now
+		 * look to the older log data, which was already
+		 * committed but the eraseblock was not erased (UBIFS
+		 * only un-maps it). So this basically means we have to
+		 * exit with "end of log" code.
+		 */
+		err = 1;
+		goto out;
+	}
+
+	/* Make sure the first node sits at offset zero of the LEB */
+	if (snod->offs != 0) {
+		ubifs_err(c, "first node is not at zero offset");
+		goto out_dump;
+	}
+
+	printf("\tLOG LEB %d\n", lnum);
+	list_for_each_entry(snod, &sleb->nodes, list) {
+		if (snod->sqnum < cs_sqnum) {
+			ubifs_err(c, "bad sqnum %llu, commit sqnum %d",
+				  snod->sqnum, cs_sqnum);
+			goto out_dump;
+		}
+
+		printf("\tNODE %d", node_num++);
+		switch (snod->type) {
+		case UBIFS_CS_NODE:
+			printf(" <START COMMIT>");
+		case UBIFS_REF_NODE: {
+			printf(":\n");
+			dump_node(c, snod->node);
+			break;
+		}
+		default:
+			ubifs_err(c, "unexpected node in log");
+			goto out_dump;
+		}
+	}
+	err = !sleb->endpt;
+out:
+	ubifs_scan_destroy(sleb);
+	return err;
+
+out_dump:
+	ubifs_err(c, "log error detected while replaying the log at LEB %d:%lu",
+		  lnum, offs + snod->offs);
+	ubifs_scan_destroy(sleb);
+	return -EINVAL;
+
+}
+
+static int dump_log(void)
+{
+	int err, lnum, ltail_lnum, log_last;
+
+	lnum = ltail_lnum = mst.log_lnum;
+	log_last = UBIFS_LOG_LNUM + sup.log_lebs - 1;
+	printf("LOG AREA:\n");
+	while (lnum <= log_last) {
+		err = __dump_log_leb(lnum);
+		if (err == 1) {
+			if (lnum != mst.log_lnum)
+				/* We hit the end of the log */
+				break;
+
+			/*
+			 * The head of the log must always start with the
+			 * "commit start" node on a properly formatted UBIFS.
+			 * But we found no nodes at all, which means that
+			 * someting went wrong and we cannot proceed mounting
+			 * the file-system.
+			 */
+			ubifs_err(c, "no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted",
+				  lnum, 0);
+			err = -EINVAL;
+		}
+		if (err)
+			goto out;
+		lnum++;
+	}
+
+	err = 0;
+out:
+	return err;
+}
+
 static int dump()
 {
 	int err = 0;
@@ -598,6 +734,10 @@ static int dump()
 	err = dump_master();
 	if (err)
 		goto free;
+
+	err = dump_log();
+	if (err)
+		goto free;
 free:
 	free(leb_buf);
 out:
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 20/27] ubifs: introduce lprops lib
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (18 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 19/27] ubifs: ubifs_dump: dump log area Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 21/27] ubifs: lpt: implement functions to scan lpt Dongsheng Yang
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Copy lprops.c from kernel to ubifs-utils/.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/lprops.h |  6 ++++
 ubifs-utils/lib/lprops.c     | 79 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 ubifs-utils/include/lprops.h
 create mode 100644 ubifs-utils/lib/lprops.c

diff --git a/ubifs-utils/include/lprops.h b/ubifs-utils/include/lprops.h
new file mode 100644
index 0000000..5bf3108
--- /dev/null
+++ b/ubifs-utils/include/lprops.h
@@ -0,0 +1,6 @@
+#ifndef __UBIFS_LPROPS_H__
+#define __UBIFS_LPROPS_H__
+
+int ubifs_categorize_lprops(const struct ubifs_info *c,
+			    const struct ubifs_lprops *lprops);
+#endif
diff --git a/ubifs-utils/lib/lprops.c b/ubifs-utils/lib/lprops.c
new file mode 100644
index 0000000..818d220
--- /dev/null
+++ b/ubifs-utils/lib/lprops.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2006-2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Adrian Hunter
+ *          Artem Bityutskiy (Битюцкий Артём)
+ */
+
+/*
+ * This file implements the functions that access LEB properties and their
+ * categories. LEBs are categorized based on the needs of UBIFS, and the
+ * categories are stored as either heaps or lists to provide a fast way of
+ * finding a LEB in a particular category. For example, UBIFS may need to find
+ * an empty LEB for the journal, or a very dirty LEB for garbage collection.
+ */
+
+#include "ubifs_common.h"
+
+/* common.h requires the PROGRAM_NAME macro */
+#define PROGRAM_NAME "ubifs-lprops"
+#include "common.h"
+
+#include "ubifs.h"
+
+/**
+ * ubifs_categorize_lprops - categorize LEB properties.
+ * @c: UBIFS file-system description object
+ * @lprops: LEB properties to categorize
+ *
+ * LEB properties are categorized to enable fast find operations. This function
+ * returns the LEB category to which the LEB properties belong. Note however
+ * that if the LEB category is stored as a heap and the heap is full, the
+ * LEB properties may have their category changed to %LPROPS_UNCAT.
+ */
+int ubifs_categorize_lprops(const struct ubifs_info *c,
+			    const struct ubifs_lprops *lprops)
+{
+	if (lprops->flags & LPROPS_TAKEN)
+		return LPROPS_UNCAT;
+
+	if (lprops->free == c->leb_size) {
+		ubifs_assert(!(lprops->flags & LPROPS_INDEX));
+		return LPROPS_EMPTY;
+	}
+
+	if (lprops->free + lprops->dirty == c->leb_size) {
+		if (lprops->flags & LPROPS_INDEX)
+			return LPROPS_FRDI_IDX;
+		else
+			return LPROPS_FREEABLE;
+	}
+
+	if (lprops->flags & LPROPS_INDEX) {
+		if (lprops->dirty + lprops->free >= c->min_idx_node_sz)
+			return LPROPS_DIRTY_IDX;
+	} else {
+		if (lprops->dirty >= c->dead_wm &&
+		    lprops->dirty > lprops->free)
+			return LPROPS_DIRTY;
+		if (lprops->free > 0)
+			return LPROPS_FREE;
+	}
+
+	return LPROPS_UNCAT;
+}
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 21/27] ubifs: lpt: implement functions to scan lpt
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (19 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 20/27] ubifs: introduce lprops lib Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 22/27] ubifs: ubifs_dump: dump lpt area Dongsheng Yang
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Implement ubifs_scan_lpt_nolock() in lpt to scan lpt.
And then we can use this function to scan the lpt
and dump all lprops out.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/lpt.h |   3 +
 ubifs-utils/lib/lpt.c     | 661 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 663 insertions(+), 1 deletion(-)

diff --git a/ubifs-utils/include/lpt.h b/ubifs-utils/include/lpt.h
index e2f7348..d4264c3 100644
--- a/ubifs-utils/include/lpt.h
+++ b/ubifs-utils/include/lpt.h
@@ -25,5 +25,8 @@
 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);
+int unpack_ltab(const struct ubifs_info *c, void *buf);
+int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum,
+			  ubifs_lpt_scan_callback scan_cb, void *data);
 
 #endif
diff --git a/ubifs-utils/lib/lpt.c b/ubifs-utils/lib/lpt.c
index 26fb4dd..52fbcfa 100644
--- a/ubifs-utils/lib/lpt.c
+++ b/ubifs-utils/lib/lpt.c
@@ -29,6 +29,7 @@
 #include "crc16.h"
 #include "ubifs.h"
 #include "lpt.h"
+#include "lprops.h"
 #include "io.h"
 
 /**
@@ -402,7 +403,6 @@ int create_lpt(struct ubifs_info *c)
 	len = 0;
 	/* Number of leaf nodes (pnodes) */
 	cnt = (c->main_lebs + UBIFS_LPT_FANOUT - 1) >> UBIFS_LPT_FANOUT_SHIFT;
-	//printf("pnode_cnt=%d\n",cnt);
 
 	/*
 	 * To calculate the internal node branches, we keep information about
@@ -614,3 +614,662 @@ int ubifs_calc_lpt_geom(struct ubifs_info *c)
 	}
 	return 0;
 }
+
+/**
+ * struct lpt_scan_node - somewhere to put nodes while we scan LPT.
+ * @nnode: where to keep a nnode
+ * @pnode: where to keep a pnode
+ * @cnode: where to keep a cnode
+ * @in_tree: is the node in the tree in memory
+ * @ptr.nnode: pointer to the nnode (if it is an nnode) which may be here or in
+ * the tree
+ * @ptr.pnode: ditto for pnode
+ * @ptr.cnode: ditto for cnode
+ */
+struct lpt_scan_node {
+	union {
+		struct ubifs_nnode nnode;
+		struct ubifs_pnode pnode;
+		struct ubifs_cnode cnode;
+	};
+	int in_tree;
+	union {
+		struct ubifs_nnode *nnode;
+		struct ubifs_pnode *pnode;
+		struct ubifs_cnode *cnode;
+	} ptr;
+};
+
+/**
+ * ubifs_unpack_bits - unpack bit fields.
+ * @addr: address at which to unpack (passed and next address returned)
+ * @pos: bit position at which to unpack (passed and next position returned)
+ * @nrbits: number of bits of value to unpack (1-32)
+ *
+ * This functions returns the value unpacked.
+ */
+uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
+{
+	const int k = 32 - nrbits;
+	uint8_t *p = *addr;
+	int b = *pos;
+	uint32_t val = 0;
+	const int bytes = (nrbits + b + 7) >> 3;
+
+	ubifs_assert(nrbits > 0);
+	ubifs_assert(nrbits <= 32);
+	ubifs_assert(*pos >= 0);
+	ubifs_assert(*pos < 8);
+	if (b) {
+		switch (bytes) {
+		case 2:
+			val = p[1];
+			break;
+		case 3:
+			val = p[1] | ((uint32_t)p[2] << 8);
+			break;
+		case 4:
+			val = p[1] | ((uint32_t)p[2] << 8) |
+				     ((uint32_t)p[3] << 16);
+			break;
+		case 5:
+			val = p[1] | ((uint32_t)p[2] << 8) |
+				     ((uint32_t)p[3] << 16) |
+				     ((uint32_t)p[4] << 24);
+		}
+		val <<= (8 - b);
+		val |= *p >> b;
+		nrbits += b;
+	} else {
+		switch (bytes) {
+		case 1:
+			val = p[0];
+			break;
+		case 2:
+			val = p[0] | ((uint32_t)p[1] << 8);
+			break;
+		case 3:
+			val = p[0] | ((uint32_t)p[1] << 8) |
+				     ((uint32_t)p[2] << 16);
+			break;
+		case 4:
+			val = p[0] | ((uint32_t)p[1] << 8) |
+				     ((uint32_t)p[2] << 16) |
+				     ((uint32_t)p[3] << 24);
+			break;
+		}
+	}
+	val <<= k;
+	val >>= k;
+	b = nrbits & 7;
+	p += nrbits >> 3;
+	*addr = p;
+	*pos = b;
+	ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32);
+	return val;
+}
+/**
+ * calc_nnode_num_from_parent - calculate nnode number.
+ * @c: UBIFS file-system description object
+ * @parent: parent nnode
+ * @iip: index in parent
+ *
+ * The nnode number is a number that uniquely identifies a nnode and can be used
+ * easily to traverse the tree from the root to that nnode.
+ *
+ * This function calculates and returns the nnode number based on the parent's
+ * nnode number and the index in parent.
+ */
+static int calc_nnode_num_from_parent(const struct ubifs_info *c,
+				      struct ubifs_nnode *parent, int iip)
+{
+	int num, shft;
+
+	if (!parent)
+		return 1;
+	shft = (c->lpt_hght - parent->level) * UBIFS_LPT_FANOUT_SHIFT;
+	num = parent->num ^ (1 << shft);
+	num |= (UBIFS_LPT_FANOUT + iip) << shft;
+	return num;
+}
+
+int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
+		       struct ubifs_nnode *nnode);
+/**
+ * scan_get_nnode - for the scan, get a nnode from either the tree or flash.
+ * @c: the UBIFS file-system description object
+ * @path: where to put the nnode
+ * @parent: parent of the nnode
+ * @iip: index in parent of the nnode
+ *
+ * This function returns a pointer to the nnode on success or a negative error
+ * code on failure.
+ */
+static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c,
+					  struct lpt_scan_node *path,
+					  struct ubifs_nnode *parent, int iip)
+{
+	struct ubifs_nbranch *branch;
+	struct ubifs_nnode *nnode;
+	int i = max_t(int, c->nnode_sz, c->pnode_sz);
+	void *buf = malloc(i);;
+	int err;
+
+	branch = &parent->nbranch[iip];
+	nnode = branch->nnode;
+	if (nnode) {
+		path->in_tree = 1;
+		path->ptr.nnode = nnode;
+		free(buf);
+		return nnode;
+	}
+	nnode = &path->nnode;
+	path->in_tree = 0;
+	path->ptr.nnode = nnode;
+	memset(nnode, 0, sizeof(struct ubifs_nnode));
+	if (branch->lnum == 0) {
+		/*
+		 * This nnode was not written which just means that the LEB
+		 * properties in the subtree below it describe empty LEBs. We
+		 * make the nnode as though we had read it, which in fact means
+		 * doing almost nothing.
+		 */
+		if (c->big_lpt)
+			nnode->num = calc_nnode_num_from_parent(c, parent, iip);
+	} else {
+		err = ubifs_read(branch->lnum * c->leb_size + branch->offs, c->nnode_sz, buf);
+		if (err) {
+			free(buf);
+			return ERR_PTR(err);
+		}
+		err = ubifs_unpack_nnode(c, buf, nnode);
+		if (err) {
+			free(buf);
+			return ERR_PTR(err);
+		}
+	}
+	if (!c->big_lpt)
+		nnode->num = calc_nnode_num_from_parent(c, parent, iip);
+	nnode->level = parent->level - 1;
+	nnode->parent = parent;
+	nnode->iip = iip;
+
+	free(buf);
+	return nnode;
+}
+/**
+ * calc_pnode_num_from_parent - calculate pnode number.
+ * @c: UBIFS file-system description object
+ * @parent: parent nnode
+ * @iip: index in parent
+ *
+ * The pnode number is a number that uniquely identifies a pnode and can be used
+ * easily to traverse the tree from the root to that pnode.
+ *
+ * This function calculates and returns the pnode number based on the parent's
+ * nnode number and the index in parent.
+ */
+static int calc_pnode_num_from_parent(const struct ubifs_info *c,
+				      struct ubifs_nnode *parent, int iip)
+{
+	int i, n = c->lpt_hght - 1, pnum = parent->num, num = 0;
+
+	for (i = 0; i < n; i++) {
+		num <<= UBIFS_LPT_FANOUT_SHIFT;
+		num |= pnum & (UBIFS_LPT_FANOUT - 1);
+		pnum >>= UBIFS_LPT_FANOUT_SHIFT;
+	}
+	num <<= UBIFS_LPT_FANOUT_SHIFT;
+	num |= iip;
+	return num;
+}
+/**
+ * set_pnode_lnum - set LEB numbers on a pnode.
+ * @c: UBIFS file-system description object
+ * @pnode: pnode to update
+ *
+ * This function calculates the LEB numbers for the LEB properties it contains
+ * based on the pnode number.
+ */
+static void set_pnode_lnum(const struct ubifs_info *c,
+			   struct ubifs_pnode *pnode)
+{
+	int i, lnum;
+
+	lnum = (pnode->num << UBIFS_LPT_FANOUT_SHIFT) + c->main_first;
+	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
+		if (lnum >= c->leb_cnt)
+			return;
+		pnode->lprops[i].lnum = lnum++;
+	}
+}
+/**
+ * check_lpt_crc - check LPT node crc is correct.
+ * @c: UBIFS file-system description object
+ * @buf: buffer containing node
+ * @len: length of node
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int check_lpt_crc(const struct ubifs_info *c __attribute__((unused)), void *buf, int len)
+{
+	int pos = 0;
+	uint8_t *addr = buf;
+	uint16_t crc, calc_crc;
+
+	crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS);
+	calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
+			 len - UBIFS_LPT_CRC_BYTES);
+	if (crc != calc_crc) {
+		ubifs_err(c, "invalid crc in LPT node: crc %hx calc %hx",
+			  crc, calc_crc);
+		return -EINVAL;
+	}
+	return 0;
+}
+/**
+ * check_lpt_type - check LPT node type is correct.
+ * @c: UBIFS file-system description object
+ * @addr: address of type bit field is passed and returned updated here
+ * @pos: position of type bit field is passed and returned updated here
+ * @type: expected type
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int check_lpt_type(const struct ubifs_info *c __attribute__((unused)), uint8_t **addr,
+			  int *pos, int type)
+{
+	int node_type;
+
+	node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS);
+	if (node_type != type) {
+		ubifs_err(c, "invalid type (%d) in LPT node type %d",
+			  node_type, type);
+		return -EINVAL;
+	}
+	return 0;
+}
+/**
+ * unpack_pnode - unpack a pnode.
+ * @c: UBIFS file-system description object
+ * @buf: buffer containing packed pnode to unpack
+ * @pnode: pnode structure to fill
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+static int unpack_pnode(const struct ubifs_info *c, void *buf,
+			struct ubifs_pnode *pnode)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0, err;
+
+	err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_PNODE);
+	if (err)
+		return err;
+	if (c->big_lpt)
+		pnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
+		struct ubifs_lprops * const lprops = &pnode->lprops[i];
+
+		lprops->free = ubifs_unpack_bits(&addr, &pos, c->space_bits);
+		lprops->free <<= 3;
+		lprops->dirty = ubifs_unpack_bits(&addr, &pos, c->space_bits);
+		lprops->dirty <<= 3;
+
+		if (ubifs_unpack_bits(&addr, &pos, 1))
+			lprops->flags = LPROPS_INDEX;
+		else
+			lprops->flags = 0;
+		lprops->flags |= ubifs_categorize_lprops(c, lprops);
+	}
+	err = check_lpt_crc(c, buf, c->pnode_sz);
+	return err;
+}
+/**
+ * ubifs_unpack_nnode - unpack a nnode.
+ * @c: UBIFS file-system description object
+ * @buf: buffer containing packed nnode to unpack
+ * @nnode: nnode structure to fill
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
+		       struct ubifs_nnode *nnode)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0, err;
+
+	err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_NNODE);
+	if (err)
+		return err;
+	if (c->big_lpt)
+		nnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
+		int lnum;
+
+		lnum = ubifs_unpack_bits(&addr, &pos, c->lpt_lnum_bits) +
+		       c->lpt_first;
+		if (lnum == c->lpt_last + 1)
+			lnum = 0;
+		nnode->nbranch[i].lnum = lnum;
+		nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos,
+						     c->lpt_offs_bits);
+	}
+	err = check_lpt_crc(c, buf, c->nnode_sz);
+	return err;
+}
+/**
+ * unpack_ltab - unpack the LPT's own lprops table.
+ * @c: UBIFS file-system description object
+ * @buf: buffer from which to unpack
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int unpack_ltab(const struct ubifs_info *c, void *buf)
+{
+	uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
+	int i, pos = 0, err;
+
+	err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_LTAB);
+	if (err)
+		return err;
+	for (i = 0; i < c->lpt_lebs; i++) {
+		int free = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits);
+		int dirty = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits);
+
+		if (free < 0 || free > c->leb_size || dirty < 0 ||
+		    dirty > c->leb_size || free + dirty > c->leb_size)
+			return -EINVAL;
+
+		c->ltab[i].free = free;
+		c->ltab[i].dirty = dirty;
+		c->ltab[i].tgc = 0;
+		c->ltab[i].cmt = 0;
+	}
+	return 0;
+}
+
+/**
+ * scan_get_pnode - for the scan, get a pnode from either the tree or flash.
+ * @c: the UBIFS file-system description object
+ * @path: where to put the pnode
+ * @parent: parent of the pnode
+ * @iip: index in parent of the pnode
+ *
+ * This function returns a pointer to the pnode on success or a negative error
+ * code on failure.
+ */
+static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
+					  struct lpt_scan_node *path,
+					  struct ubifs_nnode *parent, int iip)
+{
+	struct ubifs_nbranch *branch;
+	struct ubifs_pnode *pnode;
+	int i = max_t(int, c->nnode_sz, c->pnode_sz);
+	void *buf = malloc(i);;
+	int err;
+
+	branch = &parent->nbranch[iip];
+	pnode = branch->pnode;
+	if (pnode) {
+		path->in_tree = 1;
+		path->ptr.pnode = pnode;
+		free(buf);
+		return pnode;
+	}
+	pnode = &path->pnode;
+	path->in_tree = 0;
+	path->ptr.pnode = pnode;
+	memset(pnode, 0, sizeof(struct ubifs_pnode));
+	if (branch->lnum == 0) {
+		/*
+		 * This pnode was not written which just means that the LEB
+		 * properties in it describe empty LEBs. We make the pnode as
+		 * though we had read it.
+		 */
+		int i;
+
+		if (c->big_lpt)
+			pnode->num = calc_pnode_num_from_parent(c, parent, iip);
+		for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
+			struct ubifs_lprops * const lprops = &pnode->lprops[i];
+
+			lprops->free = c->leb_size;
+			lprops->flags = ubifs_categorize_lprops(c, lprops);
+		}
+	} else {
+		ubifs_assert(branch->lnum >= c->lpt_first &&
+			     branch->lnum <= c->lpt_last);
+		ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size);
+		err = ubifs_read(branch->lnum * c->leb_size + branch->offs, c->pnode_sz, buf);
+		if (err) {
+			free(buf);
+			return ERR_PTR(err);
+		}
+		err = unpack_pnode(c, buf, pnode);
+		if (err) {
+			free(buf);
+			return ERR_PTR(err);
+		}
+	}
+	if (!c->big_lpt)
+		pnode->num = calc_pnode_num_from_parent(c, parent, iip);
+	pnode->parent = parent;
+	pnode->iip = iip;
+	set_pnode_lnum(c, pnode);
+	free(buf);
+	return pnode;
+}
+/**
+ * ubifs_read_nnode - read a nnode from flash and link it to the tree in memory.
+ * @c: UBIFS file-system description object
+ * @parent: parent nnode (or NULL for the root)
+ * @iip: index in parent
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
+{
+	struct ubifs_nbranch *branch = NULL;
+	struct ubifs_nnode *nnode = NULL;
+	void *buf = c->lpt_nod_buf;
+	int err, lnum, offs;
+
+	if (parent) {
+		branch = &parent->nbranch[iip];
+		lnum = branch->lnum;
+		offs = branch->offs;
+	} else {
+		lnum = c->lpt_lnum;
+		offs = c->lpt_offs;
+	}
+	nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_NOFS);
+	if (!nnode) {
+		err = -ENOMEM;
+		goto out;
+	}
+	if (lnum == 0) {
+		/*
+		 * This nnode was not written which just means that the LEB
+		 * properties in the subtree below it describe empty LEBs. We
+		 * make the nnode as though we had read it, which in fact means
+		 * doing almost nothing.
+		 */
+		if (c->big_lpt)
+			nnode->num = calc_nnode_num_from_parent(c, parent, iip);
+	} else {
+		err = ubifs_read(lnum * c->leb_size + offs, c->nnode_sz, buf);
+		if (err)
+			goto out;
+		err = ubifs_unpack_nnode(c, buf, nnode);
+		if (err)
+			goto out;
+	}
+	if (!c->big_lpt)
+		nnode->num = calc_nnode_num_from_parent(c, parent, iip);
+	if (parent) {
+		branch->nnode = nnode;
+		nnode->level = parent->level - 1;
+	} else {
+		c->nroot = nnode;
+		nnode->level = c->lpt_hght;
+	}
+	nnode->parent = parent;
+	nnode->iip = iip;
+	return 0;
+
+out:
+	ubifs_err(c, "error %d reading nnode at %d:%d", err, lnum, offs);
+	kfree(nnode);
+	return err;
+}
+
+/**
+ * ubifs_lpt_scan_nolock - scan the LPT.
+ * @c: the UBIFS file-system description object
+ * @start_lnum: LEB number from which to start scanning
+ * @end_lnum: LEB number at which to stop scanning
+ * @scan_cb: callback function called for each lprops
+ * @data: data to be passed to the callback function
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum,
+			  ubifs_lpt_scan_callback scan_cb, void *data)
+{
+	int err = 0, i, h, iip, shft;
+	struct ubifs_nnode *nnode;
+	struct ubifs_pnode *pnode;
+	struct lpt_scan_node *path;
+
+	if (start_lnum == -1) {
+		start_lnum = end_lnum + 1;
+		if (start_lnum >= c->leb_cnt)
+			start_lnum = c->main_first;
+	}
+
+	ubifs_assert(start_lnum >= c->main_first && start_lnum < c->leb_cnt);
+	ubifs_assert(end_lnum >= c->main_first && end_lnum < c->leb_cnt);
+
+	if (!c->nroot) {
+		err = ubifs_read_nnode(c, NULL, 0);
+		if (err)
+			return err;
+	}
+
+	path = kmalloc(sizeof(struct lpt_scan_node) * (c->lpt_hght + 1),
+		       GFP_NOFS);
+	if (!path)
+		return -ENOMEM;
+
+	path[0].ptr.nnode = c->nroot;
+	path[0].in_tree = 1;
+again:
+	/* Descend to the pnode containing start_lnum */
+	nnode = c->nroot;
+	i = start_lnum - c->main_first;
+	shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT;
+	for (h = 1; h < c->lpt_hght; h++) {
+		iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
+		shft -= UBIFS_LPT_FANOUT_SHIFT;
+		nnode = scan_get_nnode(c, path + h, nnode, iip);
+		if (IS_ERR(nnode)) {
+			err = PTR_ERR(nnode);
+			goto out;
+		}
+	}
+	iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
+	pnode = scan_get_pnode(c, path + h, nnode, iip);
+	if (IS_ERR(pnode)) {
+		err = PTR_ERR(pnode);
+		goto out;
+	}
+	iip = (i & (UBIFS_LPT_FANOUT - 1));
+
+	/* Loop for each lprops */
+	while (1) {
+		struct ubifs_lprops *lprops = &pnode->lprops[iip];
+		int ret, lnum = lprops->lnum;
+
+		ret = scan_cb(c, lprops, path[h].in_tree, data);
+		if (ret < 0) {
+			err = ret;
+			goto out;
+		}
+		if (ret & LPT_SCAN_ADD) {
+			/* Add all the nodes in path to the tree in memory */
+			for (h = 1; h < c->lpt_hght; h++) {
+				const size_t sz = sizeof(struct ubifs_nnode);
+				struct ubifs_nnode *parent;
+
+				if (path[h].in_tree)
+					continue;
+				nnode = malloc(sz);
+				if (!nnode) {
+					err = -ENOMEM;
+					goto out;
+				}
+				memcpy(nnode, &path[h].nnode, sz);
+				parent = nnode->parent;
+				parent->nbranch[nnode->iip].nnode = nnode;
+				path[h].ptr.nnode = nnode;
+				path[h].in_tree = 1;
+				path[h + 1].cnode.parent = nnode;
+			}
+		}
+		if (ret & LPT_SCAN_STOP) {
+			err = 0;
+			break;
+		}
+		/* Get the next lprops */
+		if (lnum == end_lnum) {
+			/*
+			 * We got to the end without finding what we were
+			 * looking for
+			 */
+			err = -ENOSPC;
+			goto out;
+		}
+		if (lnum + 1 >= c->leb_cnt) {
+			/* Wrap-around to the beginning */
+			start_lnum = c->main_first;
+			goto again;
+		}
+		if (iip + 1 < UBIFS_LPT_FANOUT) {
+			/* Next lprops is in the same pnode */
+			iip += 1;
+			continue;
+		}
+		/* We need to get the next pnode. Go up until we can go right */
+		iip = pnode->iip;
+		while (1) {
+			h -= 1;
+			ubifs_assert(h >= 0);
+			nnode = path[h].ptr.nnode;
+			if (iip + 1 < UBIFS_LPT_FANOUT)
+				break;
+			iip = nnode->iip;
+		}
+		/* Go right */
+		iip += 1;
+		/* Descend to the pnode */
+		h += 1;
+		for (; h < c->lpt_hght; h++) {
+			nnode = scan_get_nnode(c, path + h, nnode, iip);
+			if (IS_ERR(nnode)) {
+				err = PTR_ERR(nnode);
+				goto out;
+			}
+			iip = 0;
+		}
+		pnode = scan_get_pnode(c, path + h, nnode, iip);
+		if (IS_ERR(pnode)) {
+			err = PTR_ERR(pnode);
+			goto out;
+		}
+		iip = 0;
+	}
+out:
+	kfree(path);
+	return err;
+}
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 22/27] ubifs: ubifs_dump: dump lpt area
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (20 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 21/27] ubifs: lpt: implement functions to scan lpt Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 23/27] ubifs: ubifs_dump: dump index area Dongsheng Yang
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

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 --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:
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 23/27] ubifs: ubifs_dump: dump index area
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (21 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 22/27] ubifs: ubifs_dump: dump lpt area Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 24/27] ubifs: defs.h: introduce some compatible definitions about integer such as __u16 Dongsheng Yang
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Scan the whole index tree and dump each index node.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/ubifs_dump/ubifs_dump.c | 95 +++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c
index 4b255e3..e72b8dd 100644
--- a/ubifs-utils/ubifs_dump/ubifs_dump.c
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -883,6 +883,97 @@ static int dump_lpt(void)
 	return 0;
 }
 
+/**
+ * ubifs_read_node - read node.
+ * @c: UBIFS file-system description object
+ * @buf: buffer to read to
+ * @type: node type
+ * @len: node length (not aligned)
+ * @lnum: logical eraseblock number
+ * @offs: offset within the logical eraseblock
+ *
+ * This function reads a node of known type and and length, checks it and
+ * stores in @buf. Returns zero in case of success, %-EUCLEAN if CRC mismatched
+ * and a negative error code in case of failure.
+ */
+int ubifs_read_node(const struct ubifs_info *c, void *buf, int len,
+		    int lnum, loff_t offs)
+{
+	int err;
+
+	ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+	ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
+	ubifs_assert(!(offs & 7) && offs < c->leb_size);
+	ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
+
+	err = ubifs_read((loff_t)lnum * c->leb_size + offs, len, buf);
+	if (err && err != -EBADMSG)
+		return err;
+
+	return 0;
+}
+
+static int dump_zbr(struct ubifs_info *c, struct ubifs_zbranch *zbr)
+{
+	int i = 0;
+	int err = 0;
+	struct ubifs_idx_node *idx;
+	void *buf;
+
+	buf = malloc(zbr->len);
+	if (!buf)
+		return -ENOMEM;
+
+	err = ubifs_read_node(c, buf, zbr->len, zbr->lnum, zbr->offs);
+	if (err)
+		goto out;
+
+	dump_node(c, buf);
+
+	if (((struct ubifs_ch *)buf)->node_type != UBIFS_IDX_NODE)
+		goto out;
+
+	idx = ((struct ubifs_idx_node *)buf);
+	for (i = 0; i < le16_to_cpu(idx->child_cnt); i++) {
+		struct ubifs_branch *br;
+		struct ubifs_zbranch child;
+
+		br = ubifs_idx_branch(c, idx, i);
+		child.lnum = le32_to_cpu(br->lnum);
+		child.offs = le32_to_cpu(br->offs);
+		child.len = le32_to_cpu(br->len);
+		err = dump_zbr(c, &child);
+		if (err)
+			goto out;
+	}
+
+out:
+	free(buf);
+	return err;
+}
+
+static int dump_index()
+{
+	int err = 0;
+
+	printf("\tINDEX AREA: \n");
+	err = dump_zbr(c, &c->zroot);
+	if (err)
+		return err;
+	return 0;
+}
+
+static int dump_main()
+{
+	int err = 0;
+	printf("MAIN AREA: \n");
+	err = dump_index();
+	if (err)
+		return err;
+
+	return 0;
+}
+
 static int dump()
 {
 	int err = 0;
@@ -908,6 +999,10 @@ static int dump()
 	err = dump_lpt();
 	if (err)
 		goto free;
+
+	err = dump_main();
+	if (err)
+		goto free;
 free:
 	free(leb_buf);
 out:
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 24/27] ubifs: defs.h: introduce some compatible definitions about integer such as __u16
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (22 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 23/27] ubifs: ubifs_dump: dump index area Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 25/27] ubifs: introduce hexdump lib Dongsheng Yang
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Add __uXX class compatible definitions in defs.h

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/defs.h | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/ubifs-utils/include/defs.h b/ubifs-utils/include/defs.h
index ed42ab1..91ef175 100644
--- a/ubifs-utils/include/defs.h
+++ b/ubifs-utils/include/defs.h
@@ -174,6 +174,36 @@ static inline long IS_ERR(const void *ptr)
 #define ULONG_MAX       (~0UL)
 #endif
 
+#ifndef __CHECKER__
+/*
+ * Since we're using primitive definitions from kernel-space, we need to
+ * define __KERNEL__ so that system header files know which definitions
+ * to use.
+ */
+#define __KERNEL__
+#include <asm/types.h>
+typedef __u32 u32;
+typedef __u64 u64;
+typedef __u16 u16;
+typedef __u8 u8;
+typedef __s64 s64;
+typedef __s32 s32;
+
+/*
+ * Continuing to define __KERNEL__ breaks others parts of the code, so
+ * we can just undefine it now that we have the correct headers...
+ */
+#undef __KERNEL__
+#else
+typedef unsigned int u32;
+typedef unsigned int __u32;
+typedef unsigned long long u64;
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef long long s64;
+typedef int s32;
+#endif
+
 #if INT_MAX != 0x7fffffff
 #error : sizeof(int) must be 4 for this program
 #endif
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 25/27] ubifs: introduce hexdump lib
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (23 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 24/27] ubifs: defs.h: introduce some compatible definitions about integer such as __u16 Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 26/27] ubifs: ubifs_dump: dump data in hex format Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 27/27] gitignore: add ubifs_dump in gitignore Dongsheng Yang
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Introduce a hexdump lib to allow us to dump data in hex format

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 ubifs-utils/include/hexdump.h |  21 +++++
 ubifs-utils/lib/hexdump.c     | 200 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 221 insertions(+)
 create mode 100644 ubifs-utils/include/hexdump.h
 create mode 100644 ubifs-utils/lib/hexdump.c

diff --git a/ubifs-utils/include/hexdump.h b/ubifs-utils/include/hexdump.h
new file mode 100644
index 0000000..f5f2800
--- /dev/null
+++ b/ubifs-utils/include/hexdump.h
@@ -0,0 +1,21 @@
+#ifndef __UBIFS_HEXDUMP_H__
+#define __UBIFS_HEXDUMP_H__
+
+#include "ubifs_common.h"
+
+static const char hex_asc[] = "0123456789abcdef";
+static const char hex_asc_upper[] = "0123456789ABCDEF";
+
+#define hex_asc_lo(x)	hex_asc[((x) & 0x0f)]
+#define hex_asc_hi(x)	hex_asc[((x) & 0xf0) >> 4]
+
+enum {
+	DUMP_PREFIX_NONE,
+	DUMP_PREFIX_ADDRESS,
+	DUMP_PREFIX_OFFSET
+};
+
+void print_hex_dump(const char *prefix_str, int prefix_type,
+		    int rowsize, int groupsize,
+		    const void *buf, size_t len, int ascii);
+#endif
diff --git a/ubifs-utils/lib/hexdump.c b/ubifs-utils/lib/hexdump.c
new file mode 100644
index 0000000..c58f7cc
--- /dev/null
+++ b/ubifs-utils/lib/hexdump.c
@@ -0,0 +1,200 @@
+/*
+ * lib/hexdump.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. See README and COPYING for
+ * more details.
+ */
+#include "hexdump.h"
+#define PROGRAM_NAME "hexdump"
+#include "common.h"
+/**
+ * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
+ * @buf: data blob to dump
+ * @len: number of bytes in the @buf
+ * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
+ * @linebuf: where to put the converted data
+ * @linebuflen: total size of @linebuf, including space for terminating NUL
+ * @ascii: include ASCII after the hex output
+ *
+ * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
+ * 16 or 32 bytes of input data converted to hex + ASCII output.
+ *
+ * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
+ * to a hex + ASCII dump at the supplied memory location.
+ * The converted output is always NUL-terminated.
+ *
+ * E.g.:
+ *   hex_dump_to_buffer(frame->data, frame->len, 16, 1,
+ *			linebuf, sizeof(linebuf), true);
+ *
+ * example output buffer:
+ * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
+ *
+ * Return:
+ * The amount of bytes placed in the buffer without terminating NUL. If the
+ * output was truncated, then the return value is the number of bytes
+ * (excluding the terminating NUL) which would have been written to the final
+ * string if enough space had been available.
+ */
+int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
+		       char *linebuf, size_t linebuflen, int ascii)
+{
+	const u8 *ptr = buf;
+	int ngroups;
+	u8 ch;
+	int j, lx = 0;
+	int ascii_column;
+	int ret;
+
+	if (rowsize != 16 && rowsize != 32)
+		rowsize = 16;
+
+	if (len > rowsize)		/* limit to one line at a time */
+		len = rowsize;
+	if (!is_power_of_2(groupsize) || groupsize > 8)
+		groupsize = 1;
+	if ((len % groupsize) != 0)	/* no mixed size output */
+		groupsize = 1;
+
+	ngroups = len / groupsize;
+	ascii_column = rowsize * 2 + rowsize / groupsize + 1;
+
+	if (!linebuflen)
+		goto overflow1;
+
+	if (!len)
+		goto nil;
+
+	if (groupsize == 8) {
+		const u64 *ptr8 = buf;
+
+		for (j = 0; j < ngroups; j++) {
+			ret = snprintf(linebuf + lx, linebuflen - lx,
+				       "%s%16.16llx", j ? " " : "",
+				       (unsigned long long)*(ptr8 + j));
+			if (ret >= linebuflen - lx)
+				goto overflow1;
+			lx += ret;
+		}
+	} else if (groupsize == 4) {
+		const u32 *ptr4 = buf;
+
+		for (j = 0; j < ngroups; j++) {
+			ret = snprintf(linebuf + lx, linebuflen - lx,
+				       "%s%8.8x", j ? " " : "",
+				       *(ptr4 + j));
+			if (ret >= linebuflen - lx)
+				goto overflow1;
+			lx += ret;
+		}
+	} else if (groupsize == 2) {
+		const u16 *ptr2 = buf;
+
+		for (j = 0; j < ngroups; j++) {
+			ret = snprintf(linebuf + lx, linebuflen - lx,
+				       "%s%4.4x", j ? " " : "",
+				       *(ptr2 + j));
+			if (ret >= linebuflen - lx)
+				goto overflow1;
+			lx += ret;
+		}
+	} else {
+		for (j = 0; j < len; j++) {
+			if (linebuflen < lx + 3)
+				goto overflow2;
+			ch = ptr[j];
+			linebuf[lx++] = hex_asc_hi(ch);
+			linebuf[lx++] = hex_asc_lo(ch);
+			linebuf[lx++] = ' ';
+		}
+		if (j)
+			lx--;
+	}
+	if (!ascii)
+		goto nil;
+
+	while (lx < ascii_column) {
+		if (linebuflen < lx + 2)
+			goto overflow2;
+		linebuf[lx++] = ' ';
+	}
+	for (j = 0; j < len; j++) {
+		if (linebuflen < lx + 2)
+			goto overflow2;
+		ch = ptr[j];
+		linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
+	}
+nil:
+	linebuf[lx] = '\0';
+	return lx;
+overflow2:
+	linebuf[lx++] = '\0';
+overflow1:
+	return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1;
+}
+
+/**
+ * print_hex_dump - print a text hex dump to syslog for a binary blob of data
+ * @prefix_str: string to prefix each line with;
+ *  caller supplies trailing spaces for alignment if desired
+ * @prefix_type: controls whether prefix of an offset, address, or none
+ *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
+ * @rowsize: number of bytes to print per line; must be 16 or 32
+ * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
+ * @buf: data blob to dump
+ * @len: number of bytes in the @buf
+ * @ascii: include ASCII after the hex output
+ *
+ * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
+ * to the kernel log at the specified kernel log level, with an optional
+ * leading prefix.
+ *
+ * print_hex_dump() works on one "line" of output at a time, i.e.,
+ * 16 or 32 bytes of input data converted to hex + ASCII output.
+ * print_hex_dump() iterates over the entire input @buf, breaking it into
+ * "line size" chunks to format and print.
+ *
+ * E.g.:
+ *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
+ *		    16, 1, frame->data, frame->len, true);
+ *
+ * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
+ * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
+ * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
+ * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.
+ */
+void print_hex_dump(const char *prefix_str, int prefix_type,
+		    int rowsize, int groupsize,
+		    const void *buf, size_t len, int ascii)
+{
+	const u8 *ptr = buf;
+	int i, linelen, remaining = len;
+	char linebuf[32 * 3 + 2 + 32 + 1];
+
+	if (rowsize != 16 && rowsize != 32)
+		rowsize = 16;
+
+	for (i = 0; i < len; i += rowsize) {
+		linelen = min(remaining, rowsize);
+		remaining -= rowsize;
+
+		hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
+				   linebuf, sizeof(linebuf), ascii);
+
+		switch (prefix_type) {
+		case DUMP_PREFIX_ADDRESS:
+			printf("%s%p: %s\n",
+			       prefix_str, ptr + i, linebuf);
+			break;
+		case DUMP_PREFIX_OFFSET:
+			printf("%s%.8x: %s\n", prefix_str, i, linebuf);
+			break;
+		default:
+			printf("%s%s\n", prefix_str, linebuf);
+			break;
+		}
+	}
+}
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 26/27] ubifs: ubifs_dump: dump data in hex format
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (24 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 25/27] ubifs: introduce hexdump lib Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  2015-11-13  6:13 ` [PATCH v3 27/27] gitignore: add ubifs_dump in gitignore Dongsheng Yang
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

When we dump data node, we can dump the data in it
in hex format.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 Makefile                            |  2 +-
 ubifs-utils/ubifs_dump/ubifs_dump.c | 42 ++++++++++++++++++++-----------------
 2 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/Makefile b/Makefile
index 0be4772..c9dbc58 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 ../lib/lprops.o
+obj-ubifs_dump += ../lib/scan.o ../lib/lprops.o ../lib/hexdump.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 e72b8dd..47b0c89 100644
--- a/ubifs-utils/ubifs_dump/ubifs_dump.c
+++ b/ubifs-utils/ubifs_dump/ubifs_dump.c
@@ -7,6 +7,7 @@
 #include "key.h"
 #include "lpt.h"
 #include "scan.h"
+#include "hexdump.h"
 
 #define DBG_KEY_BUF_LEN		48
 
@@ -252,26 +253,26 @@ void dump_node(const struct ubifs_info *c, const void *node)
 		const struct ubifs_ino_node *ino = node;
 
 		key_read(c, &ino->key, &key);
-		printf("\t\tkey \t\t\t%s\n",
+		printf("\t\tkey \t\t\t\t%s\n",
 		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
 		printf("\t\tcreat_sqnum \t\t\t%llu\n",
 		       (unsigned long long)le64_to_cpu(ino->creat_sqnum));
-		printf("\t\tsize \t\t\t%llu\n",
+		printf("\t\tsize \t\t\t\t%llu\n",
 		       (unsigned long long)le64_to_cpu(ino->size));
-		printf("\t\tnlink \t\t\t%u\n", le32_to_cpu(ino->nlink));
-		printf("\t\tatime \t\t\t%lld.%u\n",
+		printf("\t\tnlink \t\t\t\t%u\n", le32_to_cpu(ino->nlink));
+		printf("\t\tatime \t\t\t\t%lld.%u\n",
 		       (long long)le64_to_cpu(ino->atime_sec),
 		       le32_to_cpu(ino->atime_nsec));
-		printf("\t\tmtime \t\t\t%lld.%u\n",
+		printf("\t\tmtime \t\t\t\t%lld.%u\n",
 		       (long long)le64_to_cpu(ino->mtime_sec),
 		       le32_to_cpu(ino->mtime_nsec));
-		printf("\t\tctime \t\t\t%lld.%u\n",
+		printf("\t\tctime \t\t\t\t%lld.%u\n",
 		       (long long)le64_to_cpu(ino->ctime_sec),
 		       le32_to_cpu(ino->ctime_nsec));
-		printf("\t\tuid \t\t\t%u\n", le32_to_cpu(ino->uid));
-		printf("\t\tgid \t\t\t%u\n", le32_to_cpu(ino->gid));
-		printf("\t\tmode \t\t\t%u\n", le32_to_cpu(ino->mode));
-		printf("\t\tflags \t\t\t%#x\n", le32_to_cpu(ino->flags));
+		printf("\t\tuid \t\t\t\t%u\n", le32_to_cpu(ino->uid));
+		printf("\t\tgid \t\t\t\t%u\n", le32_to_cpu(ino->gid));
+		printf("\t\tmode \t\t\t\t%u\n", le32_to_cpu(ino->mode));
+		printf("\t\tflags \t\t\t\t%#x\n", le32_to_cpu(ino->flags));
 		printf("\t\txattr_cnt \t\t\t%u\n", le32_to_cpu(ino->xattr_cnt));
 		printf("\t\txattr_size \t\t\t%u\n", le32_to_cpu(ino->xattr_size));
 		printf("\t\txattr_names \t\t\t%u\n", le32_to_cpu(ino->xattr_names));
@@ -287,13 +288,13 @@ void dump_node(const struct ubifs_info *c, const void *node)
 		int nlen = le16_to_cpu(dent->nlen);
 
 		key_read(c, &dent->key, &key);
-		printf("\t\tkey \t\t\t%s\n",
+		printf("\t\tkey \t\t\t\t%s\n",
 		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
-		printf("\t\tinum \t\t\t%llu\n",
+		printf("\t\tinum \t\t\t\t%llu\n",
 		       (unsigned long long)le64_to_cpu(dent->inum));
-		printf("\t\ttype \t\t\t%d\n", (int)dent->type);
-		printf("\t\tnlen \t\t\t%d\n", nlen);
-		printf("\t\tname           ");
+		printf("\t\ttype \t\t\t\t%d\n", (int)dent->type);
+		printf("\t\tnlen \t\t\t\t%d\n", nlen);
+		printf("\t\tname \t\t\t\t");
 
 		if (nlen > UBIFS_MAX_NLEN)
 			printf("(bad name length, not printing, bad or corrupted node)");
@@ -311,12 +312,15 @@ void dump_node(const struct ubifs_info *c, const void *node)
 		int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
 
 		key_read(c, &dn->key, &key);
-		printf("\t\tkey \t\t\t%s\n",
+		printf("\t\tkey \t\t\t\t%s\n",
 		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
-		printf("\t\tsize \t\t\t%u\n", le32_to_cpu(dn->size));
+		printf("\t\tsize \t\t\t\t%u\n", le32_to_cpu(dn->size));
 		printf("\t\tcompr_typ \t\t\t%d\n",
 		       (int)le16_to_cpu(dn->compr_type));
 		printf("\t\tdata size \t\t\t%d\n", dlen);
+		printf("\t\tdata:\n");
+		print_hex_dump("\t\t", DUMP_PREFIX_OFFSET, 32, 1,
+			       (void *)&dn->data, dlen, 0);
 		break;
 	}
 	case UBIFS_TRUN_NODE:
@@ -335,8 +339,8 @@ void dump_node(const struct ubifs_info *c, const void *node)
 		const struct ubifs_idx_node *idx = node;
 
 		n = le16_to_cpu(idx->child_cnt);
-		printf("\t\tchild_cnt \t\t%d\n", n);
-		printf("\t\tlevel \t\t\t%d\n", (int)le16_to_cpu(idx->level));
+		printf("\t\tchild_cnt \t\t\t%d\n", n);
+		printf("\t\tlevel \t\t\t\t%d\n", (int)le16_to_cpu(idx->level));
 		printf("\t\tBranches:\n");
 
 		for (i = 0; i < n && i < c->fanout - 1; i++) {
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v3 27/27] gitignore: add ubifs_dump in gitignore
  2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
                   ` (25 preceding siblings ...)
  2015-11-13  6:13 ` [PATCH v3 26/27] ubifs: ubifs_dump: dump data in hex format Dongsheng Yang
@ 2015-11-13  6:13 ` Dongsheng Yang
  26 siblings, 0 replies; 28+ messages in thread
From: Dongsheng Yang @ 2015-11-13  6:13 UTC (permalink / raw)
  To: computersforpeace, richard, linux-mtd; +Cc: Dongsheng Yang

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index 2aac52c..6bcac39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@
 /nor-utils/rfdformat
 /misc-utils/serve_image
 /jffsX-utils/sumtool
+/ubifs-utils/ubifs_dump/ubifs_dump
 
 #
 # Top-level generic files
-- 
1.8.4.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2015-11-13  6:24 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-13  6:13 [PATCH v3 00/27] Introduce ubifs_dump in ubifs-utils Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 01/27] ubifs: pick some common definitions into ubifs_common.h Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 02/27] ubifs: move the all io related code into io.[h|c] Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 03/27] ubifs: remove the including of mkfs.ubifs.h in lpt.c Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 04/27] ubifs: cut off the dependence from compr.o to mkfs.ubifs Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 05/27] ubifs: cut off the dependence from devtable to mkfs.ubifs.h Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 06/27] ubifs: introduce ubifs-utils/include and ubifs-utils/lib Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 07/27] ubifs: move more functions into io lib Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 08/27] ubifs: introduce a new tool ubifs_dump Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 09/27] ubifs: introduce list.h Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 10/27] ubifs: copy some important data in ubifs.h from kernel to ubifs-utils Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 11/27] ubifs: copy some important functions in key.h " Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 12/27] ubifs: ubifs_dump: add dump_ch and dump_node functions Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 13/27] ubifs: defs.h: introduce some compatible definition for printk class Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 14/27] ubifs: io: introduce ubifs_read function to read ubi volume Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 15/27] ubifs: ubifs_dump: dump super block Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 16/27] ubifs: introduce scan for ubifs-utils Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 17/27] ubifs: add some more compatible definitions in defs.h Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 18/27] ubifs: ubifs_dump: dump master node Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 19/27] ubifs: ubifs_dump: dump log area Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 20/27] ubifs: introduce lprops lib Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 21/27] ubifs: lpt: implement functions to scan lpt Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 22/27] ubifs: ubifs_dump: dump lpt area Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 23/27] ubifs: ubifs_dump: dump index area Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 24/27] ubifs: defs.h: introduce some compatible definitions about integer such as __u16 Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 25/27] ubifs: introduce hexdump lib Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 26/27] ubifs: ubifs_dump: dump data in hex format Dongsheng Yang
2015-11-13  6:13 ` [PATCH v3 27/27] gitignore: add ubifs_dump in gitignore Dongsheng Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.