Skip to content

Commit c511732

Browse files
adam900710kdave
authored andcommitted
btrfs: introduce btrfs_compress_bio() helper
The helper will allocate a new compressed_bio, do the compression, and return it to the caller. This greatly simplifies the compression path, as we no longer need to allocate a folio array thus no extra error path, furthermore the compressed bio structure can be utilized for submission with very minor modifications (like rounding up the bi_size and populate the bi_sector). 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>
1 parent 3d74a75 commit c511732

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

fs/btrfs/compression.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,74 @@ int btrfs_compress_folios(unsigned int type, int level, struct btrfs_inode *inod
10641064
return ret;
10651065
}
10661066

1067+
/*
1068+
* Given an address space and start and length, compress the page cache
1069+
* contents into @cb.
1070+
*
1071+
* @type_level: is encoded algorithm and level, where level 0 means whatever
1072+
* default the algorithm chooses and is opaque here;
1073+
* - compression algo are 0-3
1074+
* - the level are bits 4-7
1075+
*
1076+
* @cb->bbio.bio.bi_iter.bi_size will indicate the compressed data size.
1077+
* The bi_size may not be sectorsize aligned, thus the caller still need
1078+
* to do the round up before submission.
1079+
*
1080+
* This function will allocate compressed folios with btrfs_alloc_compr_folio(),
1081+
* thus callers must make sure the endio function and error handling are using
1082+
* btrfs_free_compr_folio() to release those folios.
1083+
* This is already done in end_bbio_compressed_write() and cleanup_compressed_bio().
1084+
*/
1085+
struct compressed_bio *btrfs_compress_bio(struct btrfs_inode *inode,
1086+
u64 start, u32 len, unsigned int type,
1087+
int level, blk_opf_t write_flags)
1088+
{
1089+
struct btrfs_fs_info *fs_info = inode->root->fs_info;
1090+
struct list_head *workspace;
1091+
struct compressed_bio *cb;
1092+
int ret;
1093+
1094+
cb = alloc_compressed_bio(inode, start, REQ_OP_WRITE | write_flags,
1095+
end_bbio_compressed_write);
1096+
cb->start = start;
1097+
cb->len = len;
1098+
cb->writeback = true;
1099+
cb->compress_type = type;
1100+
1101+
level = btrfs_compress_set_level(type, level);
1102+
workspace = get_workspace(fs_info, type, level);
1103+
switch (type) {
1104+
case BTRFS_COMPRESS_ZLIB:
1105+
ret = zlib_compress_bio(workspace, cb);
1106+
break;
1107+
case BTRFS_COMPRESS_LZO:
1108+
ret = lzo_compress_bio(workspace, cb);
1109+
break;
1110+
case BTRFS_COMPRESS_ZSTD:
1111+
ret = zstd_compress_bio(workspace, cb);
1112+
break;
1113+
case BTRFS_COMPRESS_NONE:
1114+
default:
1115+
/*
1116+
* This can happen when compression races with remount setting
1117+
* it to 'no compress', while caller doesn't call
1118+
* inode_need_compress() to check if we really need to
1119+
* compress.
1120+
*
1121+
* Not a big deal, just need to inform caller that we
1122+
* haven't allocated any pages yet.
1123+
*/
1124+
ret = -E2BIG;
1125+
}
1126+
1127+
put_workspace(fs_info, type, workspace);
1128+
if (ret < 0) {
1129+
cleanup_compressed_bio(cb);
1130+
return ERR_PTR(ret);
1131+
}
1132+
return cb;
1133+
}
1134+
10671135
static int btrfs_decompress_bio(struct compressed_bio *cb)
10681136
{
10691137
struct btrfs_fs_info *fs_info = cb_to_fs_info(cb);

fs/btrfs/compression.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ int btrfs_compress_heuristic(struct btrfs_inode *inode, u64 start, u64 end);
146146

147147
int btrfs_compress_filemap_get_folio(struct address_space *mapping, u64 start,
148148
struct folio **in_folio_ret);
149+
struct compressed_bio *btrfs_compress_bio(struct btrfs_inode *inode,
150+
u64 start, u32 len, unsigned int type,
151+
int level, blk_opf_t write_flags);
152+
153+
static inline void cleanup_compressed_bio(struct compressed_bio *cb)
154+
{
155+
struct bio *bio = &cb->bbio.bio;
156+
struct folio_iter fi;
157+
158+
bio_for_each_folio_all(fi, bio)
159+
btrfs_free_compr_folio(fi.folio);
160+
bio_put(bio);
161+
}
149162

150163
int zlib_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
151164
u64 start, struct folio **folios, unsigned long *out_folios,

0 commit comments

Comments
 (0)