]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: remove the old btrfs_compress_folios() infrastructure
authorQu Wenruo <wqu@suse.com>
Thu, 29 Jan 2026 03:23:43 +0000 (13:53 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 06:59:07 +0000 (07:59 +0100)
Since it's been replaced by btrfs_compress_bio(), remove all involved
functions.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/compression.c
fs/btrfs/compression.h
fs/btrfs/inode.c
fs/btrfs/lzo.c
fs/btrfs/zlib.c
fs/btrfs/zstd.c

index 83d6103eb788e1d7d432db042ec675359ef4efcc..875e0d2bcb5d00f781022b071d07b14018020c67 100644 (file)
@@ -86,37 +86,6 @@ bool btrfs_compress_is_valid_type(const char *str, size_t len)
        return false;
 }
 
-static int compression_compress_pages(int type, struct list_head *ws,
-                                     struct btrfs_inode *inode, u64 start,
-                                     struct folio **folios, unsigned long *out_folios,
-                                     unsigned long *total_in, unsigned long *total_out)
-{
-       switch (type) {
-       case BTRFS_COMPRESS_ZLIB:
-               return zlib_compress_folios(ws, inode, start, folios,
-                                           out_folios, total_in, total_out);
-       case BTRFS_COMPRESS_LZO:
-               return lzo_compress_folios(ws, inode, start, folios,
-                                          out_folios, total_in, total_out);
-       case BTRFS_COMPRESS_ZSTD:
-               return zstd_compress_folios(ws, inode, start, folios,
-                                           out_folios, total_in, total_out);
-       case BTRFS_COMPRESS_NONE:
-       default:
-               /*
-                * This can happen when compression races with remount setting
-                * it to 'no compress', while caller doesn't call
-                * inode_need_compress() to check if we really need to
-                * compress.
-                *
-                * Not a big deal, just need to inform caller that we
-                * haven't allocated any pages yet.
-                */
-               *out_folios = 0;
-               return -E2BIG;
-       }
-}
-
 static int compression_decompress_bio(struct list_head *ws,
                                      struct compressed_bio *cb)
 {
@@ -1023,45 +992,6 @@ int btrfs_compress_filemap_get_folio(struct address_space *mapping, u64 start,
        return 0;
 }
 
-/*
- * Given an address space and start and length, compress the bytes into @pages
- * that are allocated on demand.
- *
- * @type_level is encoded algorithm and level, where level 0 means whatever
- * default the algorithm chooses and is opaque here;
- * - compression algo are 0-3
- * - the level are bits 4-7
- *
- * @out_folios is an in/out parameter, holds maximum number of folios to allocate
- * and returns number of actually allocated folios
- *
- * @total_in is used to return the number of bytes actually read.  It
- * may be smaller than the input length if we had to exit early because we
- * ran out of room in the folios array or because we cross the
- * max_out threshold.
- *
- * @total_out is an in/out parameter, must be set to the input length and will
- * be also used to return the total number of compressed bytes
- */
-int btrfs_compress_folios(unsigned int type, int level, struct btrfs_inode *inode,
-                        u64 start, struct folio **folios, unsigned long *out_folios,
-                        unsigned long *total_in, unsigned long *total_out)
-{
-       struct btrfs_fs_info *fs_info = inode->root->fs_info;
-       const unsigned long orig_len = *total_out;
-       struct list_head *workspace;
-       int ret;
-
-       level = btrfs_compress_set_level(type, level);
-       workspace = get_workspace(fs_info, type, level);
-       ret = compression_compress_pages(type, workspace, inode, start, folios,
-                                        out_folios, total_in, total_out);
-       /* The total read-in bytes should be no larger than the input. */
-       ASSERT(*total_in <= orig_len);
-       put_workspace(fs_info, type, workspace);
-       return ret;
-}
-
 /*
  * Given an address space and start and length, compress the page cache
  * contents into @cb.
index fd0cce5d07cfc2fcfd629992cf00fbb3c1ffb9d2..7dc48e5563139081dc2ecae01d48b32123cd0f5c 100644 (file)
@@ -91,9 +91,6 @@ int __init btrfs_init_compress(void);
 void __cold btrfs_exit_compress(void);
 
 bool btrfs_compress_level_valid(unsigned int type, int level);
-int btrfs_compress_folios(unsigned int type, int level, struct btrfs_inode *inode,
-                         u64 start, struct folio **folios, unsigned long *out_folios,
-                        unsigned long *total_in, unsigned long *total_out);
 int btrfs_decompress(int type, const u8 *data_in, struct folio *dest_folio,
                     unsigned long dest_pgoff, size_t srclen, size_t destlen);
 int btrfs_decompress_buf2page(const char *buf, u32 buf_len,
@@ -160,9 +157,6 @@ static inline void cleanup_compressed_bio(struct compressed_bio *cb)
        bio_put(bio);
 }
 
-int zlib_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
-                        u64 start, struct folio **folios, unsigned long *out_folios,
-               unsigned long *total_in, unsigned long *total_out);
 int zlib_compress_bio(struct list_head *ws, struct compressed_bio *cb);
 int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
 int zlib_decompress(struct list_head *ws, const u8 *data_in,
@@ -172,9 +166,6 @@ struct list_head *zlib_alloc_workspace(struct btrfs_fs_info *fs_info, unsigned i
 void zlib_free_workspace(struct list_head *ws);
 struct list_head *zlib_get_workspace(struct btrfs_fs_info *fs_info, unsigned int level);
 
-int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
-                       u64 start, struct folio **folios, unsigned long *out_folios,
-               unsigned long *total_in, unsigned long *total_out);
 int lzo_compress_bio(struct list_head *ws, struct compressed_bio *cb);
 int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
 int lzo_decompress(struct list_head *ws, const u8 *data_in,
@@ -183,9 +174,6 @@ int lzo_decompress(struct list_head *ws, const u8 *data_in,
 struct list_head *lzo_alloc_workspace(struct btrfs_fs_info *fs_info);
 void lzo_free_workspace(struct list_head *ws);
 
-int zstd_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
-                        u64 start, struct folio **folios, unsigned long *out_folios,
-               unsigned long *total_in, unsigned long *total_out);
 int zstd_compress_bio(struct list_head *ws, struct compressed_bio *cb);
 int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
 int zstd_decompress(struct list_head *ws, const u8 *data_in,
index 61b5eef7feb614dfdff41e5d9c945a18a5107052..279e048922888fbdc19af672e82d141b3cb0141a 100644 (file)
@@ -966,7 +966,7 @@ static void compress_file_range(struct btrfs_work *work)
        /*
         * All the folios should have been locked thus no failure.
         *
-        * And even if some folios are missing, btrfs_compress_folios()
+        * And even if some folios are missing, btrfs_compress_bio()
         * would handle them correctly, so here just do an ASSERT() check for
         * early logic errors.
         */
index 96e408add9b899f290453fd5f1015c04871e4028..8e20497afffeec69f4c69815100cf8b492be3cc8 100644 (file)
@@ -122,98 +122,6 @@ static inline size_t read_compress_length(const char *buf)
        return le32_to_cpu(dlen);
 }
 
-/*
- * Will do:
- *
- * - Write a segment header into the destination
- * - Copy the compressed buffer into the destination
- * - Make sure we have enough space in the last sector to fit a segment header
- *   If not, we will pad at most (LZO_LEN (4)) - 1 bytes of zeros.
- *
- * Will allocate new pages when needed.
- */
-static int copy_compressed_data_to_page(struct btrfs_fs_info *fs_info,
-                                       char *compressed_data,
-                                       size_t compressed_size,
-                                       struct folio **out_folios,
-                                       unsigned long max_nr_folio,
-                                       u32 *cur_out)
-{
-       const u32 sectorsize = fs_info->sectorsize;
-       const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order;
-       u32 sector_bytes_left;
-       u32 orig_out;
-       struct folio *cur_folio;
-       char *kaddr;
-
-       if ((*cur_out >> min_folio_shift) >= max_nr_folio)
-               return -E2BIG;
-
-       /*
-        * We never allow a segment header crossing sector boundary, previous
-        * run should ensure we have enough space left inside the sector.
-        */
-       ASSERT((*cur_out / sectorsize) == (*cur_out + LZO_LEN - 1) / sectorsize);
-
-       cur_folio = out_folios[*cur_out >> min_folio_shift];
-       /* Allocate a new page */
-       if (!cur_folio) {
-               cur_folio = btrfs_alloc_compr_folio(fs_info);
-               if (!cur_folio)
-                       return -ENOMEM;
-               out_folios[*cur_out >> min_folio_shift] = cur_folio;
-       }
-
-       kaddr = kmap_local_folio(cur_folio, offset_in_folio(cur_folio, *cur_out));
-       write_compress_length(kaddr, compressed_size);
-       *cur_out += LZO_LEN;
-
-       orig_out = *cur_out;
-
-       /* Copy compressed data */
-       while (*cur_out - orig_out < compressed_size) {
-               u32 copy_len = min_t(u32, sectorsize - *cur_out % sectorsize,
-                                    orig_out + compressed_size - *cur_out);
-
-               kunmap_local(kaddr);
-
-               if ((*cur_out >> min_folio_shift) >= max_nr_folio)
-                       return -E2BIG;
-
-               cur_folio = out_folios[*cur_out >> min_folio_shift];
-               /* Allocate a new page */
-               if (!cur_folio) {
-                       cur_folio = btrfs_alloc_compr_folio(fs_info);
-                       if (!cur_folio)
-                               return -ENOMEM;
-                       out_folios[*cur_out >> min_folio_shift] = cur_folio;
-               }
-               kaddr = kmap_local_folio(cur_folio, 0);
-
-               memcpy(kaddr + offset_in_folio(cur_folio, *cur_out),
-                      compressed_data + *cur_out - orig_out, copy_len);
-
-               *cur_out += copy_len;
-       }
-
-       /*
-        * Check if we can fit the next segment header into the remaining space
-        * of the sector.
-        */
-       sector_bytes_left = round_up(*cur_out, sectorsize) - *cur_out;
-       if (sector_bytes_left >= LZO_LEN || sector_bytes_left == 0)
-               goto out;
-
-       /* The remaining size is not enough, pad it with zeros */
-       memset(kaddr + offset_in_page(*cur_out), 0,
-              sector_bytes_left);
-       *cur_out += sector_bytes_left;
-
-out:
-       kunmap_local(kaddr);
-       return 0;
-}
-
 /*
  * Write data into @out_folio and queue it into @out_bio.
  *
@@ -365,102 +273,6 @@ static int copy_compressed_data_to_bio(struct btrfs_fs_info *fs_info,
        return write_and_queue_folio(out_bio, out_folio, total_out, sector_bytes_left);
 }
 
-int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
-                       u64 start, struct folio **folios, unsigned long *out_folios,
-                       unsigned long *total_in, unsigned long *total_out)
-{
-       struct btrfs_fs_info *fs_info = inode->root->fs_info;
-       struct workspace *workspace = list_entry(ws, struct workspace, list);
-       const u32 sectorsize = fs_info->sectorsize;
-       const u32 min_folio_size = btrfs_min_folio_size(fs_info);
-       struct address_space *mapping = inode->vfs_inode.i_mapping;
-       struct folio *folio_in = NULL;
-       char *sizes_ptr;
-       const unsigned long max_nr_folio = *out_folios;
-       int ret = 0;
-       /* Points to the file offset of input data */
-       u64 cur_in = start;
-       /* Points to the current output byte */
-       u32 cur_out = 0;
-       u32 len = *total_out;
-
-       ASSERT(max_nr_folio > 0);
-       *out_folios = 0;
-       *total_out = 0;
-       *total_in = 0;
-
-       /*
-        * Skip the header for now, we will later come back and write the total
-        * compressed size
-        */
-       cur_out += LZO_LEN;
-       while (cur_in < start + len) {
-               char *data_in;
-               const u32 sectorsize_mask = sectorsize - 1;
-               u32 sector_off = (cur_in - start) & sectorsize_mask;
-               u32 in_len;
-               size_t out_len;
-
-               /* Get the input page first */
-               if (!folio_in) {
-                       ret = btrfs_compress_filemap_get_folio(mapping, cur_in, &folio_in);
-                       if (ret < 0)
-                               goto out;
-               }
-
-               /* Compress at most one sector of data each time */
-               in_len = min_t(u32, start + len - cur_in, sectorsize - sector_off);
-               ASSERT(in_len);
-               data_in = kmap_local_folio(folio_in, offset_in_folio(folio_in, cur_in));
-               ret = lzo1x_1_compress(data_in, in_len,
-                                      workspace->cbuf, &out_len,
-                                      workspace->mem);
-               kunmap_local(data_in);
-               if (unlikely(ret < 0)) {
-                       /* lzo1x_1_compress never fails. */
-                       ret = -EIO;
-                       goto out;
-               }
-
-               ret = copy_compressed_data_to_page(fs_info, workspace->cbuf, out_len,
-                                                  folios, max_nr_folio,
-                                                  &cur_out);
-               if (ret < 0)
-                       goto out;
-
-               cur_in += in_len;
-
-               /*
-                * Check if we're making it bigger after two sectors.  And if
-                * it is so, give up.
-                */
-               if (cur_in - start > sectorsize * 2 && cur_in - start < cur_out) {
-                       ret = -E2BIG;
-                       goto out;
-               }
-
-               /* Check if we have reached folio boundary. */
-               if (IS_ALIGNED(cur_in, min_folio_size)) {
-                       folio_put(folio_in);
-                       folio_in = NULL;
-               }
-       }
-
-       /* Store the size of all chunks of compressed data */
-       sizes_ptr = kmap_local_folio(folios[0], 0);
-       write_compress_length(sizes_ptr, cur_out);
-       kunmap_local(sizes_ptr);
-
-       ret = 0;
-       *total_out = cur_out;
-       *total_in = cur_in - start;
-out:
-       if (folio_in)
-               folio_put(folio_in);
-       *out_folios = DIV_ROUND_UP(cur_out, min_folio_size);
-       return ret;
-}
-
 int lzo_compress_bio(struct list_head *ws, struct compressed_bio *cb)
 {
        struct btrfs_inode *inode = cb->bbio.inode;
index fa463e0e852767c0c393122c5c99d31ed98ece06..0a8fcee16428f31721ef84a5050a26ec9f5e34d7 100644 (file)
@@ -145,195 +145,6 @@ static int copy_data_into_buffer(struct address_space *mapping,
        return 0;
 }
 
-int zlib_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
-                        u64 start, struct folio **folios, unsigned long *out_folios,
-                        unsigned long *total_in, unsigned long *total_out)
-{
-       struct btrfs_fs_info *fs_info = inode->root->fs_info;
-       struct workspace *workspace = list_entry(ws, struct workspace, list);
-       struct address_space *mapping = inode->vfs_inode.i_mapping;
-       const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order;
-       const u32 min_folio_size = btrfs_min_folio_size(fs_info);
-       int ret;
-       char *data_in = NULL;
-       char *cfolio_out;
-       int nr_folios = 0;
-       struct folio *in_folio = NULL;
-       struct folio *out_folio = NULL;
-       unsigned long len = *total_out;
-       unsigned long nr_dest_folios = *out_folios;
-       const unsigned long max_out = nr_dest_folios << min_folio_shift;
-       const u32 blocksize = fs_info->sectorsize;
-       const u64 orig_end = start + len;
-
-       *out_folios = 0;
-       *total_out = 0;
-       *total_in = 0;
-
-       ret = zlib_deflateInit(&workspace->strm, workspace->level);
-       if (unlikely(ret != Z_OK)) {
-               btrfs_err(fs_info,
-       "zlib compression init failed, error %d root %llu inode %llu offset %llu",
-                         ret, btrfs_root_id(inode->root), btrfs_ino(inode), start);
-               ret = -EIO;
-               goto out;
-       }
-
-       workspace->strm.total_in = 0;
-       workspace->strm.total_out = 0;
-
-       out_folio = btrfs_alloc_compr_folio(fs_info);
-       if (out_folio == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       cfolio_out = folio_address(out_folio);
-       folios[0] = out_folio;
-       nr_folios = 1;
-
-       workspace->strm.next_in = workspace->buf;
-       workspace->strm.avail_in = 0;
-       workspace->strm.next_out = cfolio_out;
-       workspace->strm.avail_out = min_folio_size;
-
-       while (workspace->strm.total_in < len) {
-               /*
-                * Get next input pages and copy the contents to
-                * the workspace buffer if required.
-                */
-               if (workspace->strm.avail_in == 0) {
-                       unsigned long bytes_left = len - workspace->strm.total_in;
-                       unsigned int copy_length = min(bytes_left, workspace->buf_size);
-
-                       /*
-                        * For s390 hardware accelerated zlib, and our folio is smaller
-                        * than the copy_length, we need to fill the buffer so that
-                        * we can take full advantage of hardware acceleration.
-                        */
-                       if (need_special_buffer(fs_info)) {
-                               ret = copy_data_into_buffer(mapping, workspace,
-                                                           start, copy_length);
-                               if (ret < 0)
-                                       goto out;
-                               start += copy_length;
-                               workspace->strm.next_in = workspace->buf;
-                               workspace->strm.avail_in = copy_length;
-                       } else {
-                               unsigned int cur_len;
-
-                               if (data_in) {
-                                       kunmap_local(data_in);
-                                       folio_put(in_folio);
-                                       data_in = NULL;
-                               }
-                               ret = btrfs_compress_filemap_get_folio(mapping,
-                                               start, &in_folio);
-                               if (ret < 0)
-                                       goto out;
-                               cur_len = btrfs_calc_input_length(in_folio, orig_end, start);
-                               data_in = kmap_local_folio(in_folio,
-                                                          offset_in_folio(in_folio, start));
-                               start += cur_len;
-                               workspace->strm.next_in = data_in;
-                               workspace->strm.avail_in = cur_len;
-                       }
-               }
-
-               ret = zlib_deflate(&workspace->strm, Z_SYNC_FLUSH);
-               if (unlikely(ret != Z_OK)) {
-                       btrfs_warn(fs_info,
-               "zlib compression failed, error %d root %llu inode %llu offset %llu",
-                                  ret, btrfs_root_id(inode->root), btrfs_ino(inode),
-                                  start);
-                       zlib_deflateEnd(&workspace->strm);
-                       ret = -EIO;
-                       goto out;
-               }
-
-               /* we're making it bigger, give up */
-               if (workspace->strm.total_in > blocksize * 2 &&
-                   workspace->strm.total_in <
-                   workspace->strm.total_out) {
-                       ret = -E2BIG;
-                       goto out;
-               }
-               /* we need another page for writing out.  Test this
-                * before the total_in so we will pull in a new page for
-                * the stream end if required
-                */
-               if (workspace->strm.avail_out == 0) {
-                       if (nr_folios == nr_dest_folios) {
-                               ret = -E2BIG;
-                               goto out;
-                       }
-                       out_folio = btrfs_alloc_compr_folio(fs_info);
-                       if (out_folio == NULL) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       cfolio_out = folio_address(out_folio);
-                       folios[nr_folios] = out_folio;
-                       nr_folios++;
-                       workspace->strm.avail_out = min_folio_size;
-                       workspace->strm.next_out = cfolio_out;
-               }
-               /* we're all done */
-               if (workspace->strm.total_in >= len)
-                       break;
-               if (workspace->strm.total_out > max_out)
-                       break;
-       }
-       workspace->strm.avail_in = 0;
-       /*
-        * Call deflate with Z_FINISH flush parameter providing more output
-        * space but no more input data, until it returns with Z_STREAM_END.
-        */
-       while (ret != Z_STREAM_END) {
-               ret = zlib_deflate(&workspace->strm, Z_FINISH);
-               if (ret == Z_STREAM_END)
-                       break;
-               if (unlikely(ret != Z_OK && ret != Z_BUF_ERROR)) {
-                       zlib_deflateEnd(&workspace->strm);
-                       ret = -EIO;
-                       goto out;
-               } else if (workspace->strm.avail_out == 0) {
-                       /* Get another folio for the stream end. */
-                       if (nr_folios == nr_dest_folios) {
-                               ret = -E2BIG;
-                               goto out;
-                       }
-                       out_folio = btrfs_alloc_compr_folio(fs_info);
-                       if (out_folio == NULL) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       cfolio_out = folio_address(out_folio);
-                       folios[nr_folios] = out_folio;
-                       nr_folios++;
-                       workspace->strm.avail_out = min_folio_size;
-                       workspace->strm.next_out = cfolio_out;
-               }
-       }
-       zlib_deflateEnd(&workspace->strm);
-
-       if (workspace->strm.total_out >= workspace->strm.total_in) {
-               ret = -E2BIG;
-               goto out;
-       }
-
-       ret = 0;
-       *total_out = workspace->strm.total_out;
-       *total_in = workspace->strm.total_in;
-out:
-       *out_folios = nr_folios;
-       if (data_in) {
-               kunmap_local(data_in);
-               folio_put(in_folio);
-       }
-
-       return ret;
-}
-
 int zlib_compress_bio(struct list_head *ws, struct compressed_bio *cb)
 {
        struct btrfs_inode *inode = cb->bbio.inode;
index 135b0b32579f223e1a7174bf0c024e1b4de48063..32fd7f5454d3c4102234d5c8520e8779d8fc130a 100644 (file)
@@ -396,195 +396,6 @@ fail:
        return ERR_PTR(-ENOMEM);
 }
 
-int zstd_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
-                        u64 start, struct folio **folios, unsigned long *out_folios,
-                        unsigned long *total_in, unsigned long *total_out)
-{
-       struct btrfs_fs_info *fs_info = inode->root->fs_info;
-       struct workspace *workspace = list_entry(ws, struct workspace, list);
-       struct address_space *mapping = inode->vfs_inode.i_mapping;
-       zstd_cstream *stream;
-       int ret = 0;
-       int nr_folios = 0;
-       struct folio *in_folio = NULL;  /* The current folio to read. */
-       struct folio *out_folio = NULL; /* The current folio to write to. */
-       unsigned long tot_in = 0;
-       unsigned long tot_out = 0;
-       unsigned long len = *total_out;
-       const unsigned long nr_dest_folios = *out_folios;
-       const u64 orig_end = start + len;
-       const u32 blocksize = fs_info->sectorsize;
-       const u32 min_folio_size = btrfs_min_folio_size(fs_info);
-       unsigned long max_out = nr_dest_folios * min_folio_size;
-       unsigned int cur_len;
-
-       workspace->params = zstd_get_btrfs_parameters(workspace->req_level, len);
-       *out_folios = 0;
-       *total_out = 0;
-       *total_in = 0;
-
-       /* Initialize the stream */
-       stream = zstd_init_cstream(&workspace->params, len, workspace->mem,
-                       workspace->size);
-       if (unlikely(!stream)) {
-               btrfs_err(fs_info,
-       "zstd compression init level %d failed, root %llu inode %llu offset %llu",
-                         workspace->req_level, btrfs_root_id(inode->root),
-                         btrfs_ino(inode), start);
-               ret = -EIO;
-               goto out;
-       }
-
-       /* map in the first page of input data */
-       ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
-       if (ret < 0)
-               goto out;
-       cur_len = btrfs_calc_input_length(in_folio, orig_end, start);
-       workspace->in_buf.src = kmap_local_folio(in_folio, offset_in_folio(in_folio, start));
-       workspace->in_buf.pos = 0;
-       workspace->in_buf.size = cur_len;
-
-       /* Allocate and map in the output buffer */
-       out_folio = btrfs_alloc_compr_folio(fs_info);
-       if (out_folio == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       folios[nr_folios++] = out_folio;
-       workspace->out_buf.dst = folio_address(out_folio);
-       workspace->out_buf.pos = 0;
-       workspace->out_buf.size = min_t(size_t, max_out, min_folio_size);
-
-       while (1) {
-               size_t ret2;
-
-               ret2 = zstd_compress_stream(stream, &workspace->out_buf,
-                               &workspace->in_buf);
-               if (unlikely(zstd_is_error(ret2))) {
-                       btrfs_warn(fs_info,
-"zstd compression level %d failed, error %d root %llu inode %llu offset %llu",
-                                  workspace->req_level, zstd_get_error_code(ret2),
-                                  btrfs_root_id(inode->root), btrfs_ino(inode),
-                                  start);
-                       ret = -EIO;
-                       goto out;
-               }
-
-               /* Check to see if we are making it bigger */
-               if (tot_in + workspace->in_buf.pos > blocksize * 2 &&
-                               tot_in + workspace->in_buf.pos <
-                               tot_out + workspace->out_buf.pos) {
-                       ret = -E2BIG;
-                       goto out;
-               }
-
-               /* We've reached the end of our output range */
-               if (workspace->out_buf.pos >= max_out) {
-                       tot_out += workspace->out_buf.pos;
-                       ret = -E2BIG;
-                       goto out;
-               }
-
-               /* Check if we need more output space */
-               if (workspace->out_buf.pos == workspace->out_buf.size) {
-                       tot_out += min_folio_size;
-                       max_out -= min_folio_size;
-                       if (nr_folios == nr_dest_folios) {
-                               ret = -E2BIG;
-                               goto out;
-                       }
-                       out_folio = btrfs_alloc_compr_folio(fs_info);
-                       if (out_folio == NULL) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       folios[nr_folios++] = out_folio;
-                       workspace->out_buf.dst = folio_address(out_folio);
-                       workspace->out_buf.pos = 0;
-                       workspace->out_buf.size = min_t(size_t, max_out, min_folio_size);
-               }
-
-               /* We've reached the end of the input */
-               if (workspace->in_buf.pos >= len) {
-                       tot_in += workspace->in_buf.pos;
-                       break;
-               }
-
-               /* Check if we need more input */
-               if (workspace->in_buf.pos == workspace->in_buf.size) {
-                       tot_in += workspace->in_buf.size;
-                       kunmap_local(workspace->in_buf.src);
-                       workspace->in_buf.src = NULL;
-                       folio_put(in_folio);
-                       start += cur_len;
-                       len -= cur_len;
-                       ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
-                       if (ret < 0)
-                               goto out;
-                       cur_len = btrfs_calc_input_length(in_folio, orig_end, start);
-                       workspace->in_buf.src = kmap_local_folio(in_folio,
-                                                        offset_in_folio(in_folio, start));
-                       workspace->in_buf.pos = 0;
-                       workspace->in_buf.size = cur_len;
-               }
-       }
-       while (1) {
-               size_t ret2;
-
-               ret2 = zstd_end_stream(stream, &workspace->out_buf);
-               if (unlikely(zstd_is_error(ret2))) {
-                       btrfs_err(fs_info,
-"zstd compression end level %d failed, error %d root %llu inode %llu offset %llu",
-                                 workspace->req_level, zstd_get_error_code(ret2),
-                                 btrfs_root_id(inode->root), btrfs_ino(inode),
-                                 start);
-                       ret = -EIO;
-                       goto out;
-               }
-               if (ret2 == 0) {
-                       tot_out += workspace->out_buf.pos;
-                       break;
-               }
-               if (workspace->out_buf.pos >= max_out) {
-                       tot_out += workspace->out_buf.pos;
-                       ret = -E2BIG;
-                       goto out;
-               }
-
-               tot_out += min_folio_size;
-               max_out -= min_folio_size;
-               if (nr_folios == nr_dest_folios) {
-                       ret = -E2BIG;
-                       goto out;
-               }
-               out_folio = btrfs_alloc_compr_folio(fs_info);
-               if (out_folio == NULL) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               folios[nr_folios++] = out_folio;
-               workspace->out_buf.dst = folio_address(out_folio);
-               workspace->out_buf.pos = 0;
-               workspace->out_buf.size = min_t(size_t, max_out, min_folio_size);
-       }
-
-       if (tot_out >= tot_in) {
-               ret = -E2BIG;
-               goto out;
-       }
-
-       ret = 0;
-       *total_in = tot_in;
-       *total_out = tot_out;
-out:
-       *out_folios = nr_folios;
-       if (workspace->in_buf.src) {
-               kunmap_local(workspace->in_buf.src);
-               folio_put(in_folio);
-       }
-       return ret;
-}
-
 int zstd_compress_bio(struct list_head *ws, struct compressed_bio *cb)
 {
        struct btrfs_inode *inode = cb->bbio.inode;