zstd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2016-present, Facebook, Inc.
  4. * All rights reserved.
  5. *
  6. */
  7. #include <linux/bio.h>
  8. #include <linux/bitmap.h>
  9. #include <linux/err.h>
  10. #include <linux/init.h>
  11. #include <linux/kernel.h>
  12. #include <linux/mm.h>
  13. #include <linux/sched/mm.h>
  14. #include <linux/pagemap.h>
  15. #include <linux/refcount.h>
  16. #include <linux/sched.h>
  17. #include <linux/slab.h>
  18. #include <linux/zstd.h>
  19. #include "misc.h"
  20. #include "fs.h"
  21. #include "btrfs_inode.h"
  22. #include "compression.h"
  23. #include "super.h"
  24. #define ZSTD_BTRFS_MAX_WINDOWLOG 17
  25. #define ZSTD_BTRFS_MAX_INPUT (1U << ZSTD_BTRFS_MAX_WINDOWLOG)
  26. #define ZSTD_BTRFS_DEFAULT_LEVEL 3
  27. #define ZSTD_BTRFS_MIN_LEVEL -15
  28. #define ZSTD_BTRFS_MAX_LEVEL 15
  29. /* 307s to avoid pathologically clashing with transaction commit */
  30. #define ZSTD_BTRFS_RECLAIM_JIFFIES (307 * HZ)
  31. static zstd_parameters zstd_get_btrfs_parameters(int level,
  32. size_t src_len)
  33. {
  34. zstd_parameters params = zstd_get_params(level, src_len);
  35. if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG)
  36. params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG;
  37. WARN_ON(src_len > ZSTD_BTRFS_MAX_INPUT);
  38. return params;
  39. }
  40. struct workspace {
  41. void *mem;
  42. size_t size;
  43. char *buf;
  44. int level;
  45. int req_level;
  46. unsigned long last_used; /* jiffies */
  47. struct list_head list;
  48. struct list_head lru_list;
  49. zstd_in_buffer in_buf;
  50. zstd_out_buffer out_buf;
  51. zstd_parameters params;
  52. };
  53. /*
  54. * Zstd Workspace Management
  55. *
  56. * Zstd workspaces have different memory requirements depending on the level.
  57. * The zstd workspaces are managed by having individual lists for each level
  58. * and a global lru. Forward progress is maintained by protecting a max level
  59. * workspace.
  60. *
  61. * Getting a workspace is done by using the bitmap to identify the levels that
  62. * have available workspaces and scans up. This lets us recycle higher level
  63. * workspaces because of the monotonic memory guarantee. A workspace's
  64. * last_used is only updated if it is being used by the corresponding memory
  65. * level. Putting a workspace involves adding it back to the appropriate places
  66. * and adding it back to the lru if necessary.
  67. *
  68. * A timer is used to reclaim workspaces if they have not been used for
  69. * ZSTD_BTRFS_RECLAIM_JIFFIES. This helps keep only active workspaces around.
  70. * The upper bound is provided by the workqueue limit which is 2 (percpu limit).
  71. */
  72. struct zstd_workspace_manager {
  73. spinlock_t lock;
  74. struct list_head lru_list;
  75. struct list_head idle_ws[ZSTD_BTRFS_MAX_LEVEL];
  76. unsigned long active_map;
  77. wait_queue_head_t wait;
  78. struct timer_list timer;
  79. };
  80. static size_t zstd_ws_mem_sizes[ZSTD_BTRFS_MAX_LEVEL];
  81. static inline struct workspace *list_to_workspace(struct list_head *list)
  82. {
  83. return container_of(list, struct workspace, list);
  84. }
  85. static inline int clip_level(int level)
  86. {
  87. return max(0, level - 1);
  88. }
  89. /*
  90. * Timer callback to free unused workspaces.
  91. *
  92. * @t: timer
  93. *
  94. * This scans the lru_list and attempts to reclaim any workspace that hasn't
  95. * been used for ZSTD_BTRFS_RECLAIM_JIFFIES.
  96. *
  97. * The context is softirq and does not need the _bh locking primitives.
  98. */
  99. static void zstd_reclaim_timer_fn(struct timer_list *timer)
  100. {
  101. struct zstd_workspace_manager *zwsm =
  102. container_of(timer, struct zstd_workspace_manager, timer);
  103. unsigned long reclaim_threshold = jiffies - ZSTD_BTRFS_RECLAIM_JIFFIES;
  104. struct list_head *pos, *next;
  105. spin_lock(&zwsm->lock);
  106. if (list_empty(&zwsm->lru_list)) {
  107. spin_unlock(&zwsm->lock);
  108. return;
  109. }
  110. list_for_each_prev_safe(pos, next, &zwsm->lru_list) {
  111. struct workspace *victim = container_of(pos, struct workspace,
  112. lru_list);
  113. int level;
  114. if (time_after(victim->last_used, reclaim_threshold))
  115. break;
  116. /* workspace is in use */
  117. if (victim->req_level)
  118. continue;
  119. level = victim->level;
  120. list_del(&victim->lru_list);
  121. list_del(&victim->list);
  122. zstd_free_workspace(&victim->list);
  123. if (list_empty(&zwsm->idle_ws[level]))
  124. clear_bit(level, &zwsm->active_map);
  125. }
  126. if (!list_empty(&zwsm->lru_list))
  127. mod_timer(&zwsm->timer, jiffies + ZSTD_BTRFS_RECLAIM_JIFFIES);
  128. spin_unlock(&zwsm->lock);
  129. }
  130. /*
  131. * Calculate monotonic memory bounds.
  132. *
  133. * It is possible based on the level configurations that a higher level
  134. * workspace uses less memory than a lower level workspace. In order to reuse
  135. * workspaces, this must be made a monotonic relationship. This precomputes
  136. * the required memory for each level and enforces the monotonicity between
  137. * level and memory required.
  138. */
  139. static void zstd_calc_ws_mem_sizes(void)
  140. {
  141. size_t max_size = 0;
  142. int level;
  143. for (level = ZSTD_BTRFS_MIN_LEVEL; level <= ZSTD_BTRFS_MAX_LEVEL; level++) {
  144. if (level == 0)
  145. continue;
  146. zstd_parameters params =
  147. zstd_get_btrfs_parameters(level, ZSTD_BTRFS_MAX_INPUT);
  148. size_t level_size =
  149. max_t(size_t,
  150. zstd_cstream_workspace_bound(&params.cParams),
  151. zstd_dstream_workspace_bound(ZSTD_BTRFS_MAX_INPUT));
  152. max_size = max_t(size_t, max_size, level_size);
  153. /* Use level 1 workspace size for all the fast mode negative levels. */
  154. zstd_ws_mem_sizes[clip_level(level)] = max_size;
  155. }
  156. }
  157. int zstd_alloc_workspace_manager(struct btrfs_fs_info *fs_info)
  158. {
  159. struct zstd_workspace_manager *zwsm;
  160. struct list_head *ws;
  161. ASSERT(fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] == NULL);
  162. zwsm = kzalloc_obj(*zwsm);
  163. if (!zwsm)
  164. return -ENOMEM;
  165. zstd_calc_ws_mem_sizes();
  166. spin_lock_init(&zwsm->lock);
  167. init_waitqueue_head(&zwsm->wait);
  168. timer_setup(&zwsm->timer, zstd_reclaim_timer_fn, 0);
  169. INIT_LIST_HEAD(&zwsm->lru_list);
  170. for (int i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++)
  171. INIT_LIST_HEAD(&zwsm->idle_ws[i]);
  172. fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] = zwsm;
  173. ws = zstd_alloc_workspace(fs_info, ZSTD_BTRFS_MAX_LEVEL);
  174. if (IS_ERR(ws)) {
  175. btrfs_warn(NULL, "cannot preallocate zstd compression workspace");
  176. } else {
  177. set_bit(ZSTD_BTRFS_MAX_LEVEL - 1, &zwsm->active_map);
  178. list_add(ws, &zwsm->idle_ws[ZSTD_BTRFS_MAX_LEVEL - 1]);
  179. }
  180. return 0;
  181. }
  182. void zstd_free_workspace_manager(struct btrfs_fs_info *fs_info)
  183. {
  184. struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
  185. struct workspace *workspace;
  186. if (!zwsm)
  187. return;
  188. fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] = NULL;
  189. spin_lock_bh(&zwsm->lock);
  190. for (int i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++) {
  191. while (!list_empty(&zwsm->idle_ws[i])) {
  192. workspace = container_of(zwsm->idle_ws[i].next,
  193. struct workspace, list);
  194. list_del(&workspace->list);
  195. list_del(&workspace->lru_list);
  196. zstd_free_workspace(&workspace->list);
  197. }
  198. }
  199. spin_unlock_bh(&zwsm->lock);
  200. timer_delete_sync(&zwsm->timer);
  201. kfree(zwsm);
  202. }
  203. /*
  204. * Find workspace for given level.
  205. *
  206. * @level: compression level
  207. *
  208. * This iterates over the set bits in the active_map beginning at the requested
  209. * compression level. This lets us utilize already allocated workspaces before
  210. * allocating a new one. If the workspace is of a larger size, it is used, but
  211. * the place in the lru_list and last_used times are not updated. This is to
  212. * offer the opportunity to reclaim the workspace in favor of allocating an
  213. * appropriately sized one in the future.
  214. */
  215. static struct list_head *zstd_find_workspace(struct btrfs_fs_info *fs_info, int level)
  216. {
  217. struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
  218. struct list_head *ws;
  219. struct workspace *workspace;
  220. int i = clip_level(level);
  221. ASSERT(zwsm);
  222. spin_lock_bh(&zwsm->lock);
  223. for_each_set_bit_from(i, &zwsm->active_map, ZSTD_BTRFS_MAX_LEVEL) {
  224. if (!list_empty(&zwsm->idle_ws[i])) {
  225. ws = zwsm->idle_ws[i].next;
  226. workspace = list_to_workspace(ws);
  227. list_del_init(ws);
  228. /* keep its place if it's a lower level using this */
  229. workspace->req_level = level;
  230. if (clip_level(level) == workspace->level)
  231. list_del(&workspace->lru_list);
  232. if (list_empty(&zwsm->idle_ws[i]))
  233. clear_bit(i, &zwsm->active_map);
  234. spin_unlock_bh(&zwsm->lock);
  235. return ws;
  236. }
  237. }
  238. spin_unlock_bh(&zwsm->lock);
  239. return NULL;
  240. }
  241. /*
  242. * Zstd get_workspace for level.
  243. *
  244. * @level: compression level
  245. *
  246. * If @level is 0, then any compression level can be used. Therefore, we begin
  247. * scanning from 1. We first scan through possible workspaces and then after
  248. * attempt to allocate a new workspace. If we fail to allocate one due to
  249. * memory pressure, go to sleep waiting for the max level workspace to free up.
  250. */
  251. struct list_head *zstd_get_workspace(struct btrfs_fs_info *fs_info, int level)
  252. {
  253. struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
  254. struct list_head *ws;
  255. unsigned int nofs_flag;
  256. ASSERT(zwsm);
  257. /* level == 0 means we can use any workspace */
  258. if (!level)
  259. level = 1;
  260. again:
  261. ws = zstd_find_workspace(fs_info, level);
  262. if (ws)
  263. return ws;
  264. nofs_flag = memalloc_nofs_save();
  265. ws = zstd_alloc_workspace(fs_info, level);
  266. memalloc_nofs_restore(nofs_flag);
  267. if (IS_ERR(ws)) {
  268. DEFINE_WAIT(wait);
  269. prepare_to_wait(&zwsm->wait, &wait, TASK_UNINTERRUPTIBLE);
  270. schedule();
  271. finish_wait(&zwsm->wait, &wait);
  272. goto again;
  273. }
  274. return ws;
  275. }
  276. /*
  277. * Zstd put_workspace.
  278. *
  279. * @ws: list_head for the workspace
  280. *
  281. * When putting back a workspace, we only need to update the LRU if we are of
  282. * the requested compression level. Here is where we continue to protect the
  283. * max level workspace or update last_used accordingly. If the reclaim timer
  284. * isn't set, it is also set here. Only the max level workspace tries and wakes
  285. * up waiting workspaces.
  286. */
  287. void zstd_put_workspace(struct btrfs_fs_info *fs_info, struct list_head *ws)
  288. {
  289. struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
  290. struct workspace *workspace = list_to_workspace(ws);
  291. ASSERT(zwsm);
  292. spin_lock_bh(&zwsm->lock);
  293. /* A node is only taken off the lru if we are the corresponding level */
  294. if (clip_level(workspace->req_level) == workspace->level) {
  295. /* Hide a max level workspace from reclaim */
  296. if (list_empty(&zwsm->idle_ws[ZSTD_BTRFS_MAX_LEVEL - 1])) {
  297. INIT_LIST_HEAD(&workspace->lru_list);
  298. } else {
  299. workspace->last_used = jiffies;
  300. list_add(&workspace->lru_list, &zwsm->lru_list);
  301. if (!timer_pending(&zwsm->timer))
  302. mod_timer(&zwsm->timer,
  303. jiffies + ZSTD_BTRFS_RECLAIM_JIFFIES);
  304. }
  305. }
  306. set_bit(workspace->level, &zwsm->active_map);
  307. list_add(&workspace->list, &zwsm->idle_ws[workspace->level]);
  308. workspace->req_level = 0;
  309. spin_unlock_bh(&zwsm->lock);
  310. if (workspace->level == clip_level(ZSTD_BTRFS_MAX_LEVEL))
  311. cond_wake_up(&zwsm->wait);
  312. }
  313. void zstd_free_workspace(struct list_head *ws)
  314. {
  315. struct workspace *workspace = list_entry(ws, struct workspace, list);
  316. kvfree(workspace->mem);
  317. kfree(workspace->buf);
  318. kfree(workspace);
  319. }
  320. struct list_head *zstd_alloc_workspace(struct btrfs_fs_info *fs_info, int level)
  321. {
  322. const u32 blocksize = fs_info->sectorsize;
  323. struct workspace *workspace;
  324. workspace = kzalloc_obj(*workspace);
  325. if (!workspace)
  326. return ERR_PTR(-ENOMEM);
  327. /* Use level 1 workspace size for all the fast mode negative levels. */
  328. workspace->size = zstd_ws_mem_sizes[clip_level(level)];
  329. workspace->level = clip_level(level);
  330. workspace->req_level = level;
  331. workspace->last_used = jiffies;
  332. workspace->mem = kvmalloc(workspace->size, GFP_KERNEL | __GFP_NOWARN);
  333. workspace->buf = kmalloc(blocksize, GFP_KERNEL);
  334. if (!workspace->mem || !workspace->buf)
  335. goto fail;
  336. INIT_LIST_HEAD(&workspace->list);
  337. INIT_LIST_HEAD(&workspace->lru_list);
  338. return &workspace->list;
  339. fail:
  340. zstd_free_workspace(&workspace->list);
  341. return ERR_PTR(-ENOMEM);
  342. }
  343. int zstd_compress_bio(struct list_head *ws, struct compressed_bio *cb)
  344. {
  345. struct btrfs_inode *inode = cb->bbio.inode;
  346. struct btrfs_fs_info *fs_info = inode->root->fs_info;
  347. struct workspace *workspace = list_entry(ws, struct workspace, list);
  348. struct address_space *mapping = inode->vfs_inode.i_mapping;
  349. struct bio *bio = &cb->bbio.bio;
  350. zstd_cstream *stream;
  351. int ret = 0;
  352. /* The current folio to read. */
  353. struct folio *in_folio = NULL;
  354. /* The current folio to write to. */
  355. struct folio *out_folio = NULL;
  356. unsigned long tot_in = 0;
  357. unsigned long tot_out = 0;
  358. const u64 start = cb->start;
  359. const u32 len = cb->len;
  360. const u64 end = start + len;
  361. const u32 blocksize = fs_info->sectorsize;
  362. const u32 min_folio_size = btrfs_min_folio_size(fs_info);
  363. workspace->params = zstd_get_btrfs_parameters(workspace->req_level, len);
  364. /* Initialize the stream. */
  365. stream = zstd_init_cstream(&workspace->params, len, workspace->mem, workspace->size);
  366. if (unlikely(!stream)) {
  367. btrfs_err(fs_info,
  368. "zstd compression init level %d failed, root %llu inode %llu offset %llu",
  369. workspace->req_level, btrfs_root_id(inode->root),
  370. btrfs_ino(inode), start);
  371. ret = -EIO;
  372. goto out;
  373. }
  374. /* Map in the first page of input data. */
  375. ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
  376. if (ret < 0)
  377. goto out;
  378. workspace->in_buf.src = kmap_local_folio(in_folio, offset_in_folio(in_folio, start));
  379. workspace->in_buf.pos = 0;
  380. workspace->in_buf.size = btrfs_calc_input_length(in_folio, end, start);
  381. /* Allocate and map in the output buffer. */
  382. out_folio = btrfs_alloc_compr_folio(fs_info);
  383. if (out_folio == NULL) {
  384. ret = -ENOMEM;
  385. goto out;
  386. }
  387. workspace->out_buf.dst = folio_address(out_folio);
  388. workspace->out_buf.pos = 0;
  389. workspace->out_buf.size = min_folio_size;
  390. while (1) {
  391. size_t ret2;
  392. ret2 = zstd_compress_stream(stream, &workspace->out_buf, &workspace->in_buf);
  393. if (unlikely(zstd_is_error(ret2))) {
  394. btrfs_warn(fs_info,
  395. "zstd compression level %d failed, error %d root %llu inode %llu offset %llu",
  396. workspace->req_level, zstd_get_error_code(ret2),
  397. btrfs_root_id(inode->root), btrfs_ino(inode),
  398. start + tot_in);
  399. ret = -EIO;
  400. goto out;
  401. }
  402. /* Check to see if we are making it bigger. */
  403. if (tot_in + workspace->in_buf.pos > blocksize * 2 &&
  404. tot_in + workspace->in_buf.pos < tot_out + workspace->out_buf.pos) {
  405. ret = -E2BIG;
  406. goto out;
  407. }
  408. /* Check if we need more output space. */
  409. if (workspace->out_buf.pos >= workspace->out_buf.size) {
  410. tot_out += min_folio_size;
  411. if (tot_out >= len) {
  412. ret = -E2BIG;
  413. goto out;
  414. }
  415. /* Queue the current foliot into the bio. */
  416. if (!bio_add_folio(bio, out_folio, folio_size(out_folio), 0)) {
  417. ret = -E2BIG;
  418. goto out;
  419. }
  420. out_folio = btrfs_alloc_compr_folio(fs_info);
  421. if (out_folio == NULL) {
  422. ret = -ENOMEM;
  423. goto out;
  424. }
  425. workspace->out_buf.dst = folio_address(out_folio);
  426. workspace->out_buf.pos = 0;
  427. workspace->out_buf.size = min_folio_size;
  428. }
  429. /* We've reached the end of the input. */
  430. if (tot_in + workspace->in_buf.pos >= len) {
  431. tot_in += workspace->in_buf.pos;
  432. break;
  433. }
  434. /* Check if we need more input. */
  435. if (workspace->in_buf.pos >= workspace->in_buf.size) {
  436. u64 cur;
  437. tot_in += workspace->in_buf.size;
  438. cur = start + tot_in;
  439. kunmap_local(workspace->in_buf.src);
  440. workspace->in_buf.src = NULL;
  441. folio_put(in_folio);
  442. ret = btrfs_compress_filemap_get_folio(mapping, cur, &in_folio);
  443. if (ret < 0)
  444. goto out;
  445. workspace->in_buf.src = kmap_local_folio(in_folio,
  446. offset_in_folio(in_folio, cur));
  447. workspace->in_buf.pos = 0;
  448. workspace->in_buf.size = btrfs_calc_input_length(in_folio, end, cur);
  449. }
  450. }
  451. while (1) {
  452. size_t ret2;
  453. ret2 = zstd_end_stream(stream, &workspace->out_buf);
  454. if (unlikely(zstd_is_error(ret2))) {
  455. btrfs_err(fs_info,
  456. "zstd compression end level %d failed, error %d root %llu inode %llu offset %llu",
  457. workspace->req_level, zstd_get_error_code(ret2),
  458. btrfs_root_id(inode->root), btrfs_ino(inode),
  459. start + tot_in);
  460. ret = -EIO;
  461. goto out;
  462. }
  463. /* Queue the remaining part of the output folio into bio. */
  464. if (ret2 == 0) {
  465. tot_out += workspace->out_buf.pos;
  466. if (tot_out >= len) {
  467. ret = -E2BIG;
  468. goto out;
  469. }
  470. if (!bio_add_folio(bio, out_folio, workspace->out_buf.pos, 0)) {
  471. ret = -E2BIG;
  472. goto out;
  473. }
  474. out_folio = NULL;
  475. break;
  476. }
  477. tot_out += min_folio_size;
  478. if (tot_out >= len) {
  479. ret = -E2BIG;
  480. goto out;
  481. }
  482. if (!bio_add_folio(bio, out_folio, folio_size(out_folio), 0)) {
  483. ret = -E2BIG;
  484. goto out;
  485. }
  486. out_folio = btrfs_alloc_compr_folio(fs_info);
  487. if (out_folio == NULL) {
  488. ret = -ENOMEM;
  489. goto out;
  490. }
  491. workspace->out_buf.dst = folio_address(out_folio);
  492. workspace->out_buf.pos = 0;
  493. workspace->out_buf.size = min_folio_size;
  494. }
  495. if (tot_out >= tot_in) {
  496. ret = -E2BIG;
  497. goto out;
  498. }
  499. ret = 0;
  500. ASSERT(tot_out == bio->bi_iter.bi_size);
  501. out:
  502. if (out_folio)
  503. btrfs_free_compr_folio(out_folio);
  504. if (workspace->in_buf.src) {
  505. kunmap_local(workspace->in_buf.src);
  506. folio_put(in_folio);
  507. }
  508. return ret;
  509. }
  510. int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
  511. {
  512. struct btrfs_fs_info *fs_info = cb_to_fs_info(cb);
  513. struct workspace *workspace = list_entry(ws, struct workspace, list);
  514. struct folio_iter fi;
  515. size_t srclen = cb->compressed_len;
  516. zstd_dstream *stream;
  517. int ret = 0;
  518. const u32 blocksize = fs_info->sectorsize;
  519. const unsigned int min_folio_size = btrfs_min_folio_size(fs_info);
  520. unsigned long folio_in_index = 0;
  521. unsigned long total_folios_in = DIV_ROUND_UP(srclen, min_folio_size);
  522. unsigned long buf_start;
  523. unsigned long total_out = 0;
  524. bio_first_folio(&fi, &cb->bbio.bio, 0);
  525. if (unlikely(!fi.folio))
  526. return -EINVAL;
  527. ASSERT(folio_size(fi.folio) == min_folio_size);
  528. stream = zstd_init_dstream(
  529. ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size);
  530. if (unlikely(!stream)) {
  531. struct btrfs_inode *inode = cb->bbio.inode;
  532. btrfs_err(inode->root->fs_info,
  533. "zstd decompression init failed, root %llu inode %llu offset %llu",
  534. btrfs_root_id(inode->root), btrfs_ino(inode), cb->start);
  535. ret = -EIO;
  536. goto done;
  537. }
  538. workspace->in_buf.src = kmap_local_folio(fi.folio, 0);
  539. workspace->in_buf.pos = 0;
  540. workspace->in_buf.size = min_t(size_t, srclen, min_folio_size);
  541. workspace->out_buf.dst = workspace->buf;
  542. workspace->out_buf.pos = 0;
  543. workspace->out_buf.size = blocksize;
  544. while (1) {
  545. size_t ret2;
  546. ret2 = zstd_decompress_stream(stream, &workspace->out_buf,
  547. &workspace->in_buf);
  548. if (unlikely(zstd_is_error(ret2))) {
  549. struct btrfs_inode *inode = cb->bbio.inode;
  550. btrfs_err(inode->root->fs_info,
  551. "zstd decompression failed, error %d root %llu inode %llu offset %llu",
  552. zstd_get_error_code(ret2), btrfs_root_id(inode->root),
  553. btrfs_ino(inode), cb->start);
  554. ret = -EIO;
  555. goto done;
  556. }
  557. buf_start = total_out;
  558. total_out += workspace->out_buf.pos;
  559. workspace->out_buf.pos = 0;
  560. ret = btrfs_decompress_buf2page(workspace->out_buf.dst,
  561. total_out - buf_start, cb, buf_start);
  562. if (ret == 0)
  563. break;
  564. if (workspace->in_buf.pos >= srclen)
  565. break;
  566. /* Check if we've hit the end of a frame */
  567. if (ret2 == 0)
  568. break;
  569. if (workspace->in_buf.pos == workspace->in_buf.size) {
  570. kunmap_local(workspace->in_buf.src);
  571. folio_in_index++;
  572. if (unlikely(folio_in_index >= total_folios_in)) {
  573. workspace->in_buf.src = NULL;
  574. ret = -EIO;
  575. goto done;
  576. }
  577. srclen -= min_folio_size;
  578. bio_next_folio(&fi, &cb->bbio.bio);
  579. ASSERT(fi.folio);
  580. workspace->in_buf.src = kmap_local_folio(fi.folio, 0);
  581. workspace->in_buf.pos = 0;
  582. workspace->in_buf.size = min_t(size_t, srclen, min_folio_size);
  583. }
  584. }
  585. ret = 0;
  586. done:
  587. if (workspace->in_buf.src)
  588. kunmap_local(workspace->in_buf.src);
  589. return ret;
  590. }
  591. int zstd_decompress(struct list_head *ws, const u8 *data_in,
  592. struct folio *dest_folio, unsigned long dest_pgoff, size_t srclen,
  593. size_t destlen)
  594. {
  595. struct workspace *workspace = list_entry(ws, struct workspace, list);
  596. struct btrfs_fs_info *fs_info = btrfs_sb(folio_inode(dest_folio)->i_sb);
  597. const u32 sectorsize = fs_info->sectorsize;
  598. zstd_dstream *stream;
  599. int ret = 0;
  600. unsigned long to_copy = 0;
  601. stream = zstd_init_dstream(
  602. ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size);
  603. if (unlikely(!stream)) {
  604. struct btrfs_inode *inode = folio_to_inode(dest_folio);
  605. btrfs_err(inode->root->fs_info,
  606. "zstd decompression init failed, root %llu inode %llu offset %llu",
  607. btrfs_root_id(inode->root), btrfs_ino(inode),
  608. folio_pos(dest_folio));
  609. ret = -EIO;
  610. goto finish;
  611. }
  612. workspace->in_buf.src = data_in;
  613. workspace->in_buf.pos = 0;
  614. workspace->in_buf.size = srclen;
  615. workspace->out_buf.dst = workspace->buf;
  616. workspace->out_buf.pos = 0;
  617. workspace->out_buf.size = sectorsize;
  618. /*
  619. * Since both input and output buffers should not exceed one sector,
  620. * one call should end the decompression.
  621. */
  622. ret = zstd_decompress_stream(stream, &workspace->out_buf, &workspace->in_buf);
  623. if (unlikely(zstd_is_error(ret))) {
  624. struct btrfs_inode *inode = folio_to_inode(dest_folio);
  625. btrfs_err(inode->root->fs_info,
  626. "zstd decompression failed, error %d root %llu inode %llu offset %llu",
  627. zstd_get_error_code(ret), btrfs_root_id(inode->root),
  628. btrfs_ino(inode), folio_pos(dest_folio));
  629. goto finish;
  630. }
  631. to_copy = workspace->out_buf.pos;
  632. memcpy_to_folio(dest_folio, dest_pgoff, workspace->out_buf.dst, to_copy);
  633. finish:
  634. /* Error or early end. */
  635. if (unlikely(to_copy < destlen)) {
  636. ret = -EIO;
  637. folio_zero_range(dest_folio, dest_pgoff + to_copy, destlen - to_copy);
  638. }
  639. return ret;
  640. }
  641. const struct btrfs_compress_levels btrfs_zstd_compress = {
  642. .min_level = ZSTD_BTRFS_MIN_LEVEL,
  643. .max_level = ZSTD_BTRFS_MAX_LEVEL,
  644. .default_level = ZSTD_BTRFS_DEFAULT_LEVEL,
  645. };