decompressor_deflate.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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(sizeof(*strm), GFP_KERNEL);
  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. erofs_info(sb, "EXPERIMENTAL DEFLATE feature in use. Use at your own risk!");
  80. return 0;
  81. failed:
  82. mutex_unlock(&deflate_resize_mutex);
  83. z_erofs_deflate_exit();
  84. return -ENOMEM;
  85. }
  86. static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
  87. struct page **pgpl)
  88. {
  89. struct super_block *sb = rq->sb;
  90. struct z_erofs_stream_dctx dctx = {
  91. .rq = rq,
  92. .inpages = PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT,
  93. .outpages = PAGE_ALIGN(rq->pageofs_out + rq->outputsize)
  94. >> PAGE_SHIFT,
  95. .no = -1, .ni = 0,
  96. };
  97. struct z_erofs_deflate *strm;
  98. int zerr, err;
  99. /* 1. get the exact DEFLATE compressed size */
  100. dctx.kin = kmap_local_page(*rq->in);
  101. err = z_erofs_fixup_insize(rq, dctx.kin + rq->pageofs_in,
  102. min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
  103. if (err) {
  104. kunmap_local(dctx.kin);
  105. return err;
  106. }
  107. /* 2. get an available DEFLATE context */
  108. again:
  109. spin_lock(&z_erofs_deflate_lock);
  110. strm = z_erofs_deflate_head;
  111. if (!strm) {
  112. spin_unlock(&z_erofs_deflate_lock);
  113. wait_event(z_erofs_deflate_wq, READ_ONCE(z_erofs_deflate_head));
  114. goto again;
  115. }
  116. z_erofs_deflate_head = strm->next;
  117. spin_unlock(&z_erofs_deflate_lock);
  118. /* 3. multi-call decompress */
  119. zerr = zlib_inflateInit2(&strm->z, -MAX_WBITS);
  120. if (zerr != Z_OK) {
  121. err = -EIO;
  122. goto failed_zinit;
  123. }
  124. rq->fillgaps = true; /* DEFLATE doesn't support NULL output buffer */
  125. strm->z.avail_in = min(rq->inputsize, PAGE_SIZE - rq->pageofs_in);
  126. rq->inputsize -= strm->z.avail_in;
  127. strm->z.next_in = dctx.kin + rq->pageofs_in;
  128. strm->z.avail_out = 0;
  129. dctx.bounce = strm->bounce;
  130. while (1) {
  131. dctx.avail_out = strm->z.avail_out;
  132. dctx.inbuf_sz = strm->z.avail_in;
  133. err = z_erofs_stream_switch_bufs(&dctx,
  134. (void **)&strm->z.next_out,
  135. (void **)&strm->z.next_in, pgpl);
  136. if (err)
  137. break;
  138. strm->z.avail_out = dctx.avail_out;
  139. strm->z.avail_in = dctx.inbuf_sz;
  140. zerr = zlib_inflate(&strm->z, Z_SYNC_FLUSH);
  141. if (zerr != Z_OK || !(rq->outputsize + strm->z.avail_out)) {
  142. if (zerr == Z_OK && rq->partial_decoding)
  143. break;
  144. if (zerr == Z_STREAM_END && !rq->outputsize)
  145. break;
  146. erofs_err(sb, "failed to decompress %d in[%u] out[%u]",
  147. zerr, rq->inputsize, rq->outputsize);
  148. err = -EFSCORRUPTED;
  149. break;
  150. }
  151. }
  152. if (zlib_inflateEnd(&strm->z) != Z_OK && !err)
  153. err = -EIO;
  154. if (dctx.kout)
  155. kunmap_local(dctx.kout);
  156. failed_zinit:
  157. kunmap_local(dctx.kin);
  158. /* 4. push back DEFLATE stream context to the global list */
  159. spin_lock(&z_erofs_deflate_lock);
  160. strm->next = z_erofs_deflate_head;
  161. z_erofs_deflate_head = strm;
  162. spin_unlock(&z_erofs_deflate_lock);
  163. wake_up(&z_erofs_deflate_wq);
  164. return err;
  165. }
  166. const struct z_erofs_decompressor z_erofs_deflate_decomp = {
  167. .config = z_erofs_load_deflate_config,
  168. .decompress = z_erofs_deflate_decompress,
  169. .init = z_erofs_deflate_init,
  170. .exit = z_erofs_deflate_exit,
  171. .name = "deflate",
  172. };