decompressor_deflate.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <linux/zlib.h>
  3. #include "compress.h"
  4. struct z_erofs_deflate {
  5. struct z_erofs_deflate *next;
  6. struct z_stream_s z;
  7. u8 bounce[PAGE_SIZE];
  8. };
  9. static DEFINE_SPINLOCK(z_erofs_deflate_lock);
  10. static unsigned int z_erofs_deflate_nstrms, z_erofs_deflate_avail_strms;
  11. static struct z_erofs_deflate *z_erofs_deflate_head;
  12. static DECLARE_WAIT_QUEUE_HEAD(z_erofs_deflate_wq);
  13. module_param_named(deflate_streams, z_erofs_deflate_nstrms, uint, 0444);
  14. static void z_erofs_deflate_exit(void)
  15. {
  16. /* there should be no running fs instance */
  17. while (z_erofs_deflate_avail_strms) {
  18. struct z_erofs_deflate *strm;
  19. spin_lock(&z_erofs_deflate_lock);
  20. strm = z_erofs_deflate_head;
  21. if (!strm) {
  22. spin_unlock(&z_erofs_deflate_lock);
  23. continue;
  24. }
  25. z_erofs_deflate_head = NULL;
  26. spin_unlock(&z_erofs_deflate_lock);
  27. while (strm) {
  28. struct z_erofs_deflate *n = strm->next;
  29. vfree(strm->z.workspace);
  30. kfree(strm);
  31. --z_erofs_deflate_avail_strms;
  32. strm = n;
  33. }
  34. }
  35. }
  36. static int __init z_erofs_deflate_init(void)
  37. {
  38. /* by default, use # of possible CPUs instead */
  39. if (!z_erofs_deflate_nstrms)
  40. z_erofs_deflate_nstrms = num_possible_cpus();
  41. return 0;
  42. }
  43. static int z_erofs_load_deflate_config(struct super_block *sb,
  44. struct erofs_super_block *dsb, void *data, int size)
  45. {
  46. struct z_erofs_deflate_cfgs *dfl = data;
  47. static DEFINE_MUTEX(deflate_resize_mutex);
  48. static bool inited;
  49. if (!dfl || size < sizeof(struct z_erofs_deflate_cfgs)) {
  50. erofs_err(sb, "invalid deflate cfgs, size=%u", size);
  51. return -EINVAL;
  52. }
  53. if (dfl->windowbits > MAX_WBITS) {
  54. erofs_err(sb, "unsupported windowbits %u", dfl->windowbits);
  55. return -EOPNOTSUPP;
  56. }
  57. mutex_lock(&deflate_resize_mutex);
  58. if (!inited) {
  59. for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
  60. ++z_erofs_deflate_avail_strms) {
  61. struct z_erofs_deflate *strm;
  62. strm = kzalloc_obj(*strm);
  63. if (!strm)
  64. goto failed;
  65. /* XXX: in-kernel zlib cannot customize windowbits */
  66. strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
  67. if (!strm->z.workspace) {
  68. kfree(strm);
  69. goto failed;
  70. }
  71. spin_lock(&z_erofs_deflate_lock);
  72. strm->next = z_erofs_deflate_head;
  73. z_erofs_deflate_head = strm;
  74. spin_unlock(&z_erofs_deflate_lock);
  75. }
  76. inited = true;
  77. }
  78. mutex_unlock(&deflate_resize_mutex);
  79. return 0;
  80. failed:
  81. mutex_unlock(&deflate_resize_mutex);
  82. z_erofs_deflate_exit();
  83. return -ENOMEM;
  84. }
  85. static const char *__z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
  86. struct page **pgpl)
  87. {
  88. struct super_block *sb = rq->sb;
  89. struct z_erofs_stream_dctx dctx = { .rq = rq, .no = -1, .ni = 0 };
  90. struct z_erofs_deflate *strm;
  91. const char *reason;
  92. int zerr;
  93. /* 1. get the exact DEFLATE compressed size */
  94. dctx.kin = kmap_local_page(*rq->in);
  95. reason = z_erofs_fixup_insize(rq, dctx.kin + rq->pageofs_in,
  96. min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
  97. if (reason) {
  98. kunmap_local(dctx.kin);
  99. return reason;
  100. }
  101. /* 2. get an available DEFLATE context */
  102. again:
  103. spin_lock(&z_erofs_deflate_lock);
  104. strm = z_erofs_deflate_head;
  105. if (!strm) {
  106. spin_unlock(&z_erofs_deflate_lock);
  107. wait_event(z_erofs_deflate_wq, READ_ONCE(z_erofs_deflate_head));
  108. goto again;
  109. }
  110. z_erofs_deflate_head = strm->next;
  111. spin_unlock(&z_erofs_deflate_lock);
  112. /* 3. multi-call decompress */
  113. zerr = zlib_inflateInit2(&strm->z, -MAX_WBITS);
  114. if (zerr != Z_OK) {
  115. reason = ERR_PTR(-EINVAL);
  116. goto failed_zinit;
  117. }
  118. rq->fillgaps = true; /* DEFLATE doesn't support NULL output buffer */
  119. strm->z.avail_in = min(rq->inputsize, PAGE_SIZE - rq->pageofs_in);
  120. rq->inputsize -= strm->z.avail_in;
  121. strm->z.next_in = dctx.kin + rq->pageofs_in;
  122. strm->z.avail_out = 0;
  123. dctx.bounce = strm->bounce;
  124. while (1) {
  125. dctx.avail_out = strm->z.avail_out;
  126. dctx.inbuf_sz = strm->z.avail_in;
  127. reason = z_erofs_stream_switch_bufs(&dctx,
  128. (void **)&strm->z.next_out,
  129. (void **)&strm->z.next_in, pgpl);
  130. if (reason)
  131. break;
  132. strm->z.avail_out = dctx.avail_out;
  133. strm->z.avail_in = dctx.inbuf_sz;
  134. zerr = zlib_inflate(&strm->z, Z_SYNC_FLUSH);
  135. if (zerr != Z_OK || !(rq->outputsize + strm->z.avail_out)) {
  136. if (zerr == Z_OK && rq->partial_decoding)
  137. break;
  138. if (zerr == Z_STREAM_END && !rq->outputsize)
  139. break;
  140. reason = (zerr == Z_DATA_ERROR ?
  141. "corrupted compressed data" :
  142. "unexpected end of stream");
  143. break;
  144. }
  145. }
  146. if (zlib_inflateEnd(&strm->z) != Z_OK && !reason)
  147. reason = ERR_PTR(-EIO);
  148. if (dctx.kout)
  149. kunmap_local(dctx.kout);
  150. failed_zinit:
  151. kunmap_local(dctx.kin);
  152. /* 4. push back DEFLATE stream context to the global list */
  153. spin_lock(&z_erofs_deflate_lock);
  154. strm->next = z_erofs_deflate_head;
  155. z_erofs_deflate_head = strm;
  156. spin_unlock(&z_erofs_deflate_lock);
  157. wake_up(&z_erofs_deflate_wq);
  158. return reason;
  159. }
  160. static const char *z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
  161. struct page **pgpl)
  162. {
  163. #ifdef CONFIG_EROFS_FS_ZIP_ACCEL
  164. int err;
  165. if (!rq->partial_decoding) {
  166. err = z_erofs_crypto_decompress(rq, pgpl);
  167. if (err != -EOPNOTSUPP)
  168. return ERR_PTR(err);
  169. }
  170. #endif
  171. return __z_erofs_deflate_decompress(rq, pgpl);
  172. }
  173. const struct z_erofs_decompressor z_erofs_deflate_decomp = {
  174. .config = z_erofs_load_deflate_config,
  175. .decompress = z_erofs_deflate_decompress,
  176. .init = z_erofs_deflate_init,
  177. .exit = z_erofs_deflate_exit,
  178. .name = "deflate",
  179. };