aboutsummaryrefslogtreecommitdiffstats
path: root/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch')
-rw-r--r--tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch404
1 files changed, 404 insertions, 0 deletions
diff --git a/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch b/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch
new file mode 100644
index 000000000..1e44ba4c2
--- /dev/null
+++ b/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch
@@ -0,0 +1,404 @@
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+
+ # -*- sh -*-
+
+-CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -I./include/linux/lzma
++CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(XZCPPFLAGS) -I./include/linux/lzma
+
+ ifeq ($(WITHOUT_XATTR), 1)
+ CPPFLAGS += -DWITHOUT_XATTR
+--- a/mkfs.ubifs/compr.c
++++ b/mkfs.ubifs/compr.c
+@@ -127,6 +127,114 @@ static inline int lzo_init(void) { retur
+ static inline void lzo_fini(void) { }
+ #endif
+
++#ifndef WITHOUT_XZ
++
++#include <lzma.h>
++
++struct xz_ctx {
++ lzma_filter filters[3];
++ lzma_options_lzma opts;
++};
++
++static struct xz_ctx *xz_ctx;
++
++#define LZMA_COMPRESSION_LEVEL 9
++
++static struct xz_ctx *xz_ctx_init(void)
++{
++ struct xz_ctx *ctx;
++ lzma_options_lzma *opts_lzma;
++ uint32_t preset;
++ int ret;
++
++ ctx = malloc(sizeof(struct xz_ctx));
++ if (ctx == NULL)
++ goto err;
++
++ memset(ctx, 0, sizeof(struct xz_ctx));
++
++ opts_lzma = &ctx->opts;
++
++ preset = LZMA_COMPRESSION_LEVEL | LZMA_PRESET_EXTREME;
++ ret = lzma_lzma_preset(opts_lzma, preset);
++ if (ret)
++ goto err_free_ctx;
++
++ /* TODO: allow to specify LZMA options via command line */
++#if 0
++ opts_lzma->lc = 3;
++ opts_lzma->lp = 0;
++ opts_lzma->pb = 2;
++ opts_lzma->nice_len = 64;
++#else
++ opts_lzma->lc = 0;
++ opts_lzma->lp = 2;
++ opts_lzma->pb = 2;
++ opts_lzma->nice_len = 64;
++#endif
++
++ ctx->filters[0].id = LZMA_FILTER_LZMA2;
++ ctx->filters[0].options = opts_lzma;
++ ctx->filters[1].id = LZMA_VLI_UNKNOWN;
++
++ return ctx;
++
++err_free_ctx:
++ free(ctx);
++err:
++ return NULL;
++}
++
++static void xz_ctx_free(struct xz_ctx *ctx)
++{
++ free(ctx);
++}
++
++static int xz_init(void)
++{
++ xz_ctx = xz_ctx_init();
++ if (xz_ctx == NULL)
++ return -1;
++
++ return 0;
++}
++
++static void xz_fini(void)
++{
++ xz_ctx_free(xz_ctx);
++}
++
++static int xz_compress(void *in_buf, size_t in_len, void *out_buf,
++ size_t *out_len)
++{
++ size_t ret_len;
++ lzma_ret ret_xz;
++ int ret;
++
++ ret = -1;
++
++ ret_len = 0;
++ ret_xz = lzma_stream_buffer_encode(xz_ctx->filters, LZMA_CHECK_CRC32,
++ NULL, in_buf, in_len, out_buf,
++ &ret_len, *out_len);
++ if (ret_xz != LZMA_OK) {
++ fprintf(stderr, "XZ error: %d\n", (int) ret_xz);
++ goto out;
++ }
++
++ *out_len = ret_len;
++
++ ret = 0;
++out:
++ return ret;
++}
++#else
++static inline int xz_init(void) { return 0; }
++static inline void xz_fini(void) { }
++static inline int xz_compress(void *in_buf, size_t in_len, void *out_buf,
++ size_t *out_len) { return -1; }
++#endif
++
+ static int no_compress(void *in_buf, size_t in_len, void *out_buf,
+ size_t *out_len)
+ {
+@@ -199,6 +307,9 @@ int compress_data(void *in_buf, size_t i
+ case MKFS_UBIFS_COMPR_LZO:
+ ret = lzo_compress(in_buf, in_len, out_buf, out_len);
+ break;
++ case MKFS_UBIFS_COMPR_XZ:
++ ret = xz_compress(in_buf, in_len, out_buf, out_len);
++ break;
+ case MKFS_UBIFS_COMPR_ZLIB:
+ ret = zlib_deflate(in_buf, in_len, out_buf, out_len);
+ break;
+@@ -226,12 +337,18 @@ int init_compression(void)
+ if (ret)
+ goto err;
+
++ ret = xz_init();
++ if (ret)
++ goto err_lzo;
++
+ zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR);
+ if (!zlib_buf)
+- goto err_lzo;
++ goto err_xz;
+
+ return 0;
+
++err_xz:
++ xz_fini();
+ err_lzo:
+ lzo_fini();
+ err:
+@@ -241,6 +358,7 @@ err:
+ void destroy_compression(void)
+ {
+ free(zlib_buf);
++ xz_fini();
+ lzo_fini();
+ if (errcnt)
+ fprintf(stderr, "%llu compression errors occurred\n", errcnt);
+--- a/mkfs.ubifs/compr.h
++++ b/mkfs.ubifs/compr.h
+@@ -36,6 +36,7 @@ enum compression_type
+ MKFS_UBIFS_COMPR_NONE,
+ MKFS_UBIFS_COMPR_LZO,
+ MKFS_UBIFS_COMPR_ZLIB,
++ MKFS_UBIFS_COMPR_XZ,
+ };
+
+ int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
+--- a/mkfs.ubifs/Makefile
++++ b/mkfs.ubifs/Makefile
+@@ -6,21 +6,33 @@ ALL_SOURCES=*.[ch] hashtable/*.[ch]
+
+ TARGETS = mkfs.ubifs
+
++MKFS_UBIFS_OBJS = $(addprefix $(BUILDDIR)/,\
++ crc16.o lpt.o compr.o devtable.o \
++ hashtable/hashtable.o hashtable/hashtable_itr.o)
++
+ ifeq ($(WITHOUT_LZO), 1)
+ CPPFLAGS += -DWITHOUT_LZO
+ else
+ LZOLDLIBS = -llzo2
+ endif
+
+-LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
++ifeq ($(WITHOUT_XZ), 1)
++ CPPFLAGS += -DWITHOUT_XZ
++else
++ifneq ($(LZMA_STATIC_LIB),)
++ MKFS_UBIFS_OBJS += $(LZMA_STATIC_LIB)
++else
++ XZLDLIBS = -llzma
++endif
++endif
++
++LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) $(XZLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
+ LDLIBS_mkfs.ubifs += -L$(BUILDDIR)/../lib -lmtd
+-LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
++LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(XZLDFLAGS)
+
+ include ../common.mk
+
+-$(BUILDDIR)/mkfs.ubifs: $(addprefix $(BUILDDIR)/,\
+- crc16.o lpt.o compr.o devtable.o \
+- hashtable/hashtable.o hashtable/hashtable_itr.o)
++$(BUILDDIR)/mkfs.ubifs: $(MKFS_UBIFS_OBJS)
+
+ clean::
+ rm -f $(BUILDDIR)/hashtable/*.o cscope.*
+--- a/mkfs.ubifs/mkfs.ubifs.c
++++ b/mkfs.ubifs/mkfs.ubifs.c
+@@ -98,6 +98,9 @@ struct ubifs_info info_;
+ static struct ubifs_info *c = &info_;
+ static libubi_t ubi;
+
++static int force_compr_set;
++static int force_compr;
++
+ /* Debug levels are: 0 (none), 1 (statistics), 2 (files) ,3 (more details) */
+ int debug_level;
+ int verbose;
+@@ -132,7 +135,7 @@ static struct inum_mapping **hash_table;
+ /* Inode creation sequence number */
+ static unsigned long long creat_sqnum;
+
+-static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQq";
++static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:y:j:R:l:j:UQq";
+
+ static const struct option longopts[] = {
+ {"root", 1, NULL, 'r'},
+@@ -149,6 +152,7 @@ static const struct option longopts[] =
+ {"reserved", 1, NULL, 'R'},
+ {"compr", 1, NULL, 'x'},
+ {"favor-percent", 1, NULL, 'X'},
++ {"force-compr", 1, NULL, 'y'},
+ {"fanout", 1, NULL, 'f'},
+ {"space-fixup", 0, NULL, 'F'},
+ {"keyhash", 1, NULL, 'k'},
+@@ -178,11 +182,13 @@ static const char *helptext =
+ "-o, --output=FILE output to FILE\n"
+ "-j, --jrn-size=SIZE journal size\n"
+ "-R, --reserved=SIZE how much space should be reserved for the super-user\n"
+-"-x, --compr=TYPE compression type - \"lzo\", \"favor_lzo\", \"zlib\" or\n"
+-" \"none\" (default: \"lzo\")\n"
++"-x, --compr=TYPE default compression type - \"lzo\", \"favor_lzo\",\n"
++" \"zlib\" or \"none\" (default: \"lzo\")\n"
+ "-X, --favor-percent may only be used with favor LZO compression and defines\n"
+ " how many percent better zlib should compress to make\n"
+ " mkfs.ubifs use zlib instead of LZO (default 20%)\n"
++"-y, --force-compr=TYPE force to build the fs with different compression -\n"
++" \"lzo\", \"zlib\" or \"none\"\n"
+ "-f, --fanout=NUM fanout NUM (default: 8)\n"
+ "-F, --space-fixup file-system free space has to be fixed up on first mount\n"
+ " (requires kernel version 3.0 or greater)\n"
+@@ -530,6 +536,43 @@ static int open_ubi(const char *node)
+ return 0;
+ }
+
++static const char *get_compr_str(int compr)
++{
++ switch (compr) {
++ case UBIFS_COMPR_LZO:
++ return "lzo";
++ case UBIFS_COMPR_ZLIB:
++ return "zlib";
++ case UBIFS_COMPR_XZ:
++ return "xz";
++ case UBIFS_COMPR_NONE:
++ return "none";
++ }
++
++ return "unknown";
++}
++
++static int get_compr_option(char *opt, int *compr_type, int *favor_lzo)
++{
++ *compr_type = UBIFS_COMPR_LZO;
++
++ if (favor_lzo)
++ *favor_lzo = 0;
++
++ if (favor_lzo && strcmp(optarg, "favor_lzo") == 0)
++ *favor_lzo = 1;
++ else if (strcmp(optarg, "zlib") == 0)
++ *compr_type = UBIFS_COMPR_ZLIB;
++ else if (strcmp(optarg, "xz") == 0)
++ *compr_type = UBIFS_COMPR_XZ;
++ else if (strcmp(optarg, "none") == 0)
++ *compr_type = UBIFS_COMPR_NONE;
++ else if (strcmp(optarg, "lzo") != 0)
++ return -1;
++
++ return 0;
++}
++
+ static int get_options(int argc, char**argv)
+ {
+ int opt, i;
+@@ -649,14 +692,13 @@ static int get_options(int argc, char**a
+ return err_msg("bad key hash");
+ break;
+ case 'x':
+- if (strcmp(optarg, "favor_lzo") == 0)
+- c->favor_lzo = 1;
+- else if (strcmp(optarg, "zlib") == 0)
+- c->default_compr = UBIFS_COMPR_ZLIB;
+- else if (strcmp(optarg, "none") == 0)
+- c->default_compr = UBIFS_COMPR_NONE;
+- else if (strcmp(optarg, "lzo") != 0)
+- return err_msg("bad compressor name");
++ if (get_compr_option(optarg, &c->default_compr,
++ &c->favor_lzo))
++ return err_msg("bad compressor name '%s'",
++ optarg);
++ if (c->default_compr == UBIFS_COMPR_XZ)
++ return err_msg("'%s' can't be used as default compressor",
++ optarg);
+ break;
+ case 'X':
+ c->favor_percent = strtol(optarg, &endp, 0);
+@@ -665,6 +707,12 @@ static int get_options(int argc, char**a
+ return err_msg("bad favor LZO percent '%s'",
+ optarg);
+ break;
++ case 'y':
++ if (get_compr_option(optarg, &force_compr, NULL))
++ return err_msg("bad forced compressor name '%s'",
++ optarg);
++ force_compr_set = 1;
++ break;
+ case 'j':
+ c->max_bud_bytes = get_bytes(optarg);
+ if (c->max_bud_bytes <= 0)
+@@ -749,6 +797,9 @@ static int get_options(int argc, char**a
+ c->min_io_size = 8;
+ c->rp_size = add_space_overhead(c->rp_size);
+
++ if (force_compr_set == 0)
++ force_compr = c->default_compr;
++
+ if (verbose) {
+ printf("mkfs.ubifs\n");
+ printf("\troot: %s\n", root);
+@@ -758,17 +809,10 @@ static int get_options(int argc, char**a
+ printf("\toutput: %s\n", output);
+ printf("\tjrn_size: %llu\n", c->max_bud_bytes);
+ printf("\treserved: %llu\n", c->rp_size);
+- switch (c->default_compr) {
+- case UBIFS_COMPR_LZO:
+- printf("\tcompr: lzo\n");
+- break;
+- case UBIFS_COMPR_ZLIB:
+- printf("\tcompr: zlib\n");
+- break;
+- case UBIFS_COMPR_NONE:
+- printf("\tcompr: none\n");
+- break;
+- }
++ printf("\tcompr: %s\n", get_compr_str(c->default_compr));
++ if (force_compr_set)
++ printf("\tforced compr: %s\n",
++ get_compr_str(force_compr));
+ printf("\tkeyhash: %s\n", (c->key_hash == key_r5_hash) ?
+ "r5" : "test");
+ printf("\tfanout: %d\n", c->fanout);
+@@ -1353,7 +1397,7 @@ static int add_file(const char *path_nam
+ use_compr = UBIFS_COMPR_LZO;
+ else
+ #endif
+- use_compr = c->default_compr;
++ use_compr = force_compr;
+ compr_type = compress_data(buf, bytes_read, &dn->data,
+ &out_len, use_compr);
+ dn->compr_type = cpu_to_le16(compr_type);
+--- a/mkfs.ubifs/mkfs.ubifs.h
++++ b/mkfs.ubifs/mkfs.ubifs.h
+@@ -77,6 +77,9 @@
+ #if MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
+ #error MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
+ #endif
++#if MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ
++#error MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ
++#endif
+
+ extern int verbose;
+ extern int debug_level;
+--- a/mkfs.ubifs/ubifs-media.h
++++ b/mkfs.ubifs/ubifs-media.h
+@@ -303,6 +303,7 @@ enum {
+ UBIFS_COMPR_NONE,
+ UBIFS_COMPR_LZO,
+ UBIFS_COMPR_ZLIB,
++ UBIFS_COMPR_XZ,
+ UBIFS_COMPR_TYPES_CNT,
+ };
+