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

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