136-mkfs.ubifs-xz-support.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. --- a/Makefile
  2. +++ b/Makefile
  3. @@ -1,7 +1,7 @@
  4. # -*- sh -*-
  5. -CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -I./include/linux/lzma
  6. +CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(XZCPPFLAGS) -I./include/linux/lzma
  7. ifeq ($(WITHOUT_XATTR), 1)
  8. CPPFLAGS += -DWITHOUT_XATTR
  9. --- a/mkfs.ubifs/compr.c
  10. +++ b/mkfs.ubifs/compr.c
  11. @@ -127,6 +127,114 @@ static inline int lzo_init(void) { retur
  12. static inline void lzo_fini(void) { }
  13. #endif
  14. +#ifndef WITHOUT_XZ
  15. +
  16. +#include <lzma.h>
  17. +
  18. +struct xz_ctx {
  19. + lzma_filter filters[3];
  20. + lzma_options_lzma opts;
  21. +};
  22. +
  23. +static struct xz_ctx *xz_ctx;
  24. +
  25. +#define LZMA_COMPRESSION_LEVEL 9
  26. +
  27. +static struct xz_ctx *xz_ctx_init(void)
  28. +{
  29. + struct xz_ctx *ctx;
  30. + lzma_options_lzma *opts_lzma;
  31. + uint32_t preset;
  32. + int ret;
  33. +
  34. + ctx = malloc(sizeof(struct xz_ctx));
  35. + if (ctx == NULL)
  36. + goto err;
  37. +
  38. + memset(ctx, 0, sizeof(struct xz_ctx));
  39. +
  40. + opts_lzma = &ctx->opts;
  41. +
  42. + preset = LZMA_COMPRESSION_LEVEL | LZMA_PRESET_EXTREME;
  43. + ret = lzma_lzma_preset(opts_lzma, preset);
  44. + if (ret)
  45. + goto err_free_ctx;
  46. +
  47. + /* TODO: allow to specify LZMA options via command line */
  48. +#if 0
  49. + opts_lzma->lc = 3;
  50. + opts_lzma->lp = 0;
  51. + opts_lzma->pb = 2;
  52. + opts_lzma->nice_len = 64;
  53. +#else
  54. + opts_lzma->lc = 0;
  55. + opts_lzma->lp = 2;
  56. + opts_lzma->pb = 2;
  57. + opts_lzma->nice_len = 64;
  58. +#endif
  59. +
  60. + ctx->filters[0].id = LZMA_FILTER_LZMA2;
  61. + ctx->filters[0].options = opts_lzma;
  62. + ctx->filters[1].id = LZMA_VLI_UNKNOWN;
  63. +
  64. + return ctx;
  65. +
  66. +err_free_ctx:
  67. + free(ctx);
  68. +err:
  69. + return NULL;
  70. +}
  71. +
  72. +static void xz_ctx_free(struct xz_ctx *ctx)
  73. +{
  74. + free(ctx);
  75. +}
  76. +
  77. +static int xz_init(void)
  78. +{
  79. + xz_ctx = xz_ctx_init();
  80. + if (xz_ctx == NULL)
  81. + return -1;
  82. +
  83. + return 0;
  84. +}
  85. +
  86. +static void xz_fini(void)
  87. +{
  88. + xz_ctx_free(xz_ctx);
  89. +}
  90. +
  91. +static int xz_compress(void *in_buf, size_t in_len, void *out_buf,
  92. + size_t *out_len)
  93. +{
  94. + size_t ret_len;
  95. + lzma_ret ret_xz;
  96. + int ret;
  97. +
  98. + ret = -1;
  99. +
  100. + ret_len = 0;
  101. + ret_xz = lzma_stream_buffer_encode(xz_ctx->filters, LZMA_CHECK_CRC32,
  102. + NULL, in_buf, in_len, out_buf,
  103. + &ret_len, *out_len);
  104. + if (ret_xz != LZMA_OK) {
  105. + fprintf(stderr, "XZ error: %d\n", (int) ret_xz);
  106. + goto out;
  107. + }
  108. +
  109. + *out_len = ret_len;
  110. +
  111. + ret = 0;
  112. +out:
  113. + return ret;
  114. +}
  115. +#else
  116. +static inline int xz_init(void) { return 0; }
  117. +static inline void xz_fini(void) { }
  118. +static inline int xz_compress(void *in_buf, size_t in_len, void *out_buf,
  119. + size_t *out_len) { return -1; }
  120. +#endif
  121. +
  122. static int no_compress(void *in_buf, size_t in_len, void *out_buf,
  123. size_t *out_len)
  124. {
  125. @@ -199,6 +307,9 @@ int compress_data(void *in_buf, size_t i
  126. case MKFS_UBIFS_COMPR_LZO:
  127. ret = lzo_compress(in_buf, in_len, out_buf, out_len);
  128. break;
  129. + case MKFS_UBIFS_COMPR_XZ:
  130. + ret = xz_compress(in_buf, in_len, out_buf, out_len);
  131. + break;
  132. case MKFS_UBIFS_COMPR_ZLIB:
  133. ret = zlib_deflate(in_buf, in_len, out_buf, out_len);
  134. break;
  135. @@ -226,12 +337,18 @@ int init_compression(void)
  136. if (ret)
  137. goto err;
  138. + ret = xz_init();
  139. + if (ret)
  140. + goto err_lzo;
  141. +
  142. zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR);
  143. if (!zlib_buf)
  144. - goto err_lzo;
  145. + goto err_xz;
  146. return 0;
  147. +err_xz:
  148. + xz_fini();
  149. err_lzo:
  150. lzo_fini();
  151. err:
  152. @@ -241,6 +358,7 @@ err:
  153. void destroy_compression(void)
  154. {
  155. free(zlib_buf);
  156. + xz_fini();
  157. lzo_fini();
  158. if (errcnt)
  159. fprintf(stderr, "%llu compression errors occurred\n", errcnt);
  160. --- a/mkfs.ubifs/compr.h
  161. +++ b/mkfs.ubifs/compr.h
  162. @@ -36,6 +36,7 @@ enum compression_type
  163. MKFS_UBIFS_COMPR_NONE,
  164. MKFS_UBIFS_COMPR_LZO,
  165. MKFS_UBIFS_COMPR_ZLIB,
  166. + MKFS_UBIFS_COMPR_XZ,
  167. };
  168. int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
  169. --- a/mkfs.ubifs/Makefile
  170. +++ b/mkfs.ubifs/Makefile
  171. @@ -6,21 +6,33 @@ ALL_SOURCES=*.[ch] hashtable/*.[ch]
  172. TARGETS = mkfs.ubifs
  173. +MKFS_UBIFS_OBJS = $(addprefix $(BUILDDIR)/,\
  174. + crc16.o lpt.o compr.o devtable.o \
  175. + hashtable/hashtable.o hashtable/hashtable_itr.o)
  176. +
  177. ifeq ($(WITHOUT_LZO), 1)
  178. CPPFLAGS += -DWITHOUT_LZO
  179. else
  180. LZOLDLIBS = -llzo2
  181. endif
  182. -LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
  183. +ifeq ($(WITHOUT_XZ), 1)
  184. + CPPFLAGS += -DWITHOUT_XZ
  185. +else
  186. +ifneq ($(LZMA_STATIC_LIB),)
  187. + MKFS_UBIFS_OBJS += $(LZMA_STATIC_LIB)
  188. +else
  189. + XZLDLIBS = -llzma
  190. +endif
  191. +endif
  192. +
  193. +LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) $(XZLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
  194. LDLIBS_mkfs.ubifs += -L$(BUILDDIR)/../lib -lmtd
  195. -LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
  196. +LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(XZLDFLAGS)
  197. include ../common.mk
  198. -$(BUILDDIR)/mkfs.ubifs: $(addprefix $(BUILDDIR)/,\
  199. - crc16.o lpt.o compr.o devtable.o \
  200. - hashtable/hashtable.o hashtable/hashtable_itr.o)
  201. +$(BUILDDIR)/mkfs.ubifs: $(MKFS_UBIFS_OBJS)
  202. clean::
  203. rm -f $(BUILDDIR)/hashtable/*.o cscope.*
  204. --- a/mkfs.ubifs/mkfs.ubifs.c
  205. +++ b/mkfs.ubifs/mkfs.ubifs.c
  206. @@ -98,6 +98,9 @@ struct ubifs_info info_;
  207. static struct ubifs_info *c = &info_;
  208. static libubi_t ubi;
  209. +static int force_compr_set;
  210. +static int force_compr;
  211. +
  212. /* Debug levels are: 0 (none), 1 (statistics), 2 (files) ,3 (more details) */
  213. int debug_level;
  214. int verbose;
  215. @@ -132,7 +135,7 @@ static struct inum_mapping **hash_table;
  216. /* Inode creation sequence number */
  217. static unsigned long long creat_sqnum;
  218. -static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQq";
  219. +static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:y:j:R:l:j:UQq";
  220. static const struct option longopts[] = {
  221. {"root", 1, NULL, 'r'},
  222. @@ -149,6 +152,7 @@ static const struct option longopts[] =
  223. {"reserved", 1, NULL, 'R'},
  224. {"compr", 1, NULL, 'x'},
  225. {"favor-percent", 1, NULL, 'X'},
  226. + {"force-compr", 1, NULL, 'y'},
  227. {"fanout", 1, NULL, 'f'},
  228. {"space-fixup", 0, NULL, 'F'},
  229. {"keyhash", 1, NULL, 'k'},
  230. @@ -178,11 +182,13 @@ static const char *helptext =
  231. "-o, --output=FILE output to FILE\n"
  232. "-j, --jrn-size=SIZE journal size\n"
  233. "-R, --reserved=SIZE how much space should be reserved for the super-user\n"
  234. -"-x, --compr=TYPE compression type - \"lzo\", \"favor_lzo\", \"zlib\" or\n"
  235. -" \"none\" (default: \"lzo\")\n"
  236. +"-x, --compr=TYPE default compression type - \"lzo\", \"favor_lzo\",\n"
  237. +" \"zlib\" or \"none\" (default: \"lzo\")\n"
  238. "-X, --favor-percent may only be used with favor LZO compression and defines\n"
  239. " how many percent better zlib should compress to make\n"
  240. " mkfs.ubifs use zlib instead of LZO (default 20%)\n"
  241. +"-y, --force-compr=TYPE force to build the fs with different compression -\n"
  242. +" \"lzo\", \"zlib\" or \"none\"\n"
  243. "-f, --fanout=NUM fanout NUM (default: 8)\n"
  244. "-F, --space-fixup file-system free space has to be fixed up on first mount\n"
  245. " (requires kernel version 3.0 or greater)\n"
  246. @@ -530,6 +536,43 @@ static int open_ubi(const char *node)
  247. return 0;
  248. }
  249. +static const char *get_compr_str(int compr)
  250. +{
  251. + switch (compr) {
  252. + case UBIFS_COMPR_LZO:
  253. + return "lzo";
  254. + case UBIFS_COMPR_ZLIB:
  255. + return "zlib";
  256. + case UBIFS_COMPR_XZ:
  257. + return "xz";
  258. + case UBIFS_COMPR_NONE:
  259. + return "none";
  260. + }
  261. +
  262. + return "unknown";
  263. +}
  264. +
  265. +static int get_compr_option(char *opt, int *compr_type, int *favor_lzo)
  266. +{
  267. + *compr_type = UBIFS_COMPR_LZO;
  268. +
  269. + if (favor_lzo)
  270. + *favor_lzo = 0;
  271. +
  272. + if (favor_lzo && strcmp(optarg, "favor_lzo") == 0)
  273. + *favor_lzo = 1;
  274. + else if (strcmp(optarg, "zlib") == 0)
  275. + *compr_type = UBIFS_COMPR_ZLIB;
  276. + else if (strcmp(optarg, "xz") == 0)
  277. + *compr_type = UBIFS_COMPR_XZ;
  278. + else if (strcmp(optarg, "none") == 0)
  279. + *compr_type = UBIFS_COMPR_NONE;
  280. + else if (strcmp(optarg, "lzo") != 0)
  281. + return -1;
  282. +
  283. + return 0;
  284. +}
  285. +
  286. static int get_options(int argc, char**argv)
  287. {
  288. int opt, i;
  289. @@ -649,14 +692,13 @@ static int get_options(int argc, char**a
  290. return err_msg("bad key hash");
  291. break;
  292. case 'x':
  293. - if (strcmp(optarg, "favor_lzo") == 0)
  294. - c->favor_lzo = 1;
  295. - else if (strcmp(optarg, "zlib") == 0)
  296. - c->default_compr = UBIFS_COMPR_ZLIB;
  297. - else if (strcmp(optarg, "none") == 0)
  298. - c->default_compr = UBIFS_COMPR_NONE;
  299. - else if (strcmp(optarg, "lzo") != 0)
  300. - return err_msg("bad compressor name");
  301. + if (get_compr_option(optarg, &c->default_compr,
  302. + &c->favor_lzo))
  303. + return err_msg("bad compressor name '%s'",
  304. + optarg);
  305. + if (c->default_compr == UBIFS_COMPR_XZ)
  306. + return err_msg("'%s' can't be used as default compressor",
  307. + optarg);
  308. break;
  309. case 'X':
  310. c->favor_percent = strtol(optarg, &endp, 0);
  311. @@ -665,6 +707,12 @@ static int get_options(int argc, char**a
  312. return err_msg("bad favor LZO percent '%s'",
  313. optarg);
  314. break;
  315. + case 'y':
  316. + if (get_compr_option(optarg, &force_compr, NULL))
  317. + return err_msg("bad forced compressor name '%s'",
  318. + optarg);
  319. + force_compr_set = 1;
  320. + break;
  321. case 'j':
  322. c->max_bud_bytes = get_bytes(optarg);
  323. if (c->max_bud_bytes <= 0)
  324. @@ -749,6 +797,9 @@ static int get_options(int argc, char**a
  325. c->min_io_size = 8;
  326. c->rp_size = add_space_overhead(c->rp_size);
  327. + if (force_compr_set == 0)
  328. + force_compr = c->default_compr;
  329. +
  330. if (verbose) {
  331. printf("mkfs.ubifs\n");
  332. printf("\troot: %s\n", root);
  333. @@ -758,17 +809,10 @@ static int get_options(int argc, char**a
  334. printf("\toutput: %s\n", output);
  335. printf("\tjrn_size: %llu\n", c->max_bud_bytes);
  336. printf("\treserved: %llu\n", c->rp_size);
  337. - switch (c->default_compr) {
  338. - case UBIFS_COMPR_LZO:
  339. - printf("\tcompr: lzo\n");
  340. - break;
  341. - case UBIFS_COMPR_ZLIB:
  342. - printf("\tcompr: zlib\n");
  343. - break;
  344. - case UBIFS_COMPR_NONE:
  345. - printf("\tcompr: none\n");
  346. - break;
  347. - }
  348. + printf("\tcompr: %s\n", get_compr_str(c->default_compr));
  349. + if (force_compr_set)
  350. + printf("\tforced compr: %s\n",
  351. + get_compr_str(force_compr));
  352. printf("\tkeyhash: %s\n", (c->key_hash == key_r5_hash) ?
  353. "r5" : "test");
  354. printf("\tfanout: %d\n", c->fanout);
  355. @@ -1353,7 +1397,7 @@ static int add_file(const char *path_nam
  356. use_compr = UBIFS_COMPR_LZO;
  357. else
  358. #endif
  359. - use_compr = c->default_compr;
  360. + use_compr = force_compr;
  361. compr_type = compress_data(buf, bytes_read, &dn->data,
  362. &out_len, use_compr);
  363. dn->compr_type = cpu_to_le16(compr_type);
  364. --- a/mkfs.ubifs/mkfs.ubifs.h
  365. +++ b/mkfs.ubifs/mkfs.ubifs.h
  366. @@ -77,6 +77,9 @@
  367. #if MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
  368. #error MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
  369. #endif
  370. +#if MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ
  371. +#error MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ
  372. +#endif
  373. extern int verbose;
  374. extern int debug_level;
  375. --- a/mkfs.ubifs/ubifs-media.h
  376. +++ b/mkfs.ubifs/ubifs-media.h
  377. @@ -303,6 +303,7 @@ enum {
  378. UBIFS_COMPR_NONE,
  379. UBIFS_COMPR_LZO,
  380. UBIFS_COMPR_ZLIB,
  381. + UBIFS_COMPR_XZ,
  382. UBIFS_COMPR_TYPES_CNT,
  383. };