mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
btrfs: add workspace manager initialization for zstd
This involves: - Add zstd_alloc_workspace_manager() and zstd_free_workspace_manager() Those two functions will accept an fs_info pointer, and alloc/free fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] pointer. - Add btrfs_alloc_compress_wsm() and btrfs_free_compress_wsm() Those are helpers allocating the workspace managers for all algorithms. For now only zstd is supported, and the timing is a little unusual, the btrfs_alloc_compress_wsm() should only be called after the sectorsize being initialized. Meanwhile btrfs_free_fs_info_compress() is called in btrfs_free_fs_info(). - Move the definition of btrfs_compression_type to "fs.h" The reason is that "compression.h" has already included "fs.h", thus we can not just include "compression.h" to get the definition of BTRFS_NR_COMPRESS_TYPES to define fs_info::compr_wsm[]. For now the per-fs zstd workspace manager won't really have any effect, and all compression is still going through the global workspace manager. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
2c5cca03c1
commit
330f02b136
|
|
@ -1097,6 +1097,24 @@ int btrfs_decompress(int type, const u8 *data_in, struct folio *dest_folio,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = zstd_alloc_workspace_manager(fs_info);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return 0;
|
||||
error:
|
||||
btrfs_free_compress_wsm(fs_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void btrfs_free_compress_wsm(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
zstd_free_workspace_manager(fs_info);
|
||||
}
|
||||
|
||||
int __init btrfs_init_compress(void)
|
||||
{
|
||||
if (bioset_init(&btrfs_compressed_bioset, BIO_POOL_SIZE,
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ static inline u32 btrfs_calc_input_length(struct folio *folio, u64 range_end, u6
|
|||
return min(range_end, folio_end(folio)) - cur;
|
||||
}
|
||||
|
||||
int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info);
|
||||
void btrfs_free_compress_wsm(struct btrfs_fs_info *fs_info);
|
||||
|
||||
int __init btrfs_init_compress(void);
|
||||
void __cold btrfs_exit_compress(void);
|
||||
|
||||
|
|
@ -112,16 +115,6 @@ int btrfs_compress_str2level(unsigned int type, const char *str, int *level_ret)
|
|||
struct folio *btrfs_alloc_compr_folio(void);
|
||||
void btrfs_free_compr_folio(struct folio *folio);
|
||||
|
||||
enum btrfs_compression_type {
|
||||
BTRFS_COMPRESS_NONE = 0,
|
||||
BTRFS_COMPRESS_ZLIB = 1,
|
||||
BTRFS_COMPRESS_LZO = 2,
|
||||
BTRFS_COMPRESS_ZSTD = 3,
|
||||
BTRFS_NR_COMPRESS_TYPES = 4,
|
||||
|
||||
BTRFS_DEFRAG_DONT_COMPRESS,
|
||||
};
|
||||
|
||||
struct workspace_manager {
|
||||
struct list_head idle_ws;
|
||||
spinlock_t ws_lock;
|
||||
|
|
@ -188,6 +181,8 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
|
|||
int zstd_decompress(struct list_head *ws, const u8 *data_in,
|
||||
struct folio *dest_folio, unsigned long dest_pgoff, size_t srclen,
|
||||
size_t destlen);
|
||||
int zstd_alloc_workspace_manager(struct btrfs_fs_info *fs_info);
|
||||
void zstd_free_workspace_manager(struct btrfs_fs_info *fs_info);
|
||||
void zstd_init_workspace_manager(struct btrfs_fs_info *fs_info);
|
||||
void zstd_cleanup_workspace_manager(void);
|
||||
struct list_head *zstd_alloc_workspace(struct btrfs_fs_info *fs_info, int level);
|
||||
|
|
|
|||
|
|
@ -1248,6 +1248,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
|
|||
|
||||
if (fs_info->fs_devices)
|
||||
btrfs_close_devices(fs_info->fs_devices);
|
||||
btrfs_free_compress_wsm(fs_info);
|
||||
percpu_counter_destroy(&fs_info->stats_read_blocks);
|
||||
percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
|
||||
percpu_counter_destroy(&fs_info->delalloc_bytes);
|
||||
|
|
@ -3407,6 +3408,9 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
|||
*/
|
||||
fs_info->max_inline = min_t(u64, fs_info->max_inline, fs_info->sectorsize);
|
||||
|
||||
ret = btrfs_alloc_compress_wsm(fs_info);
|
||||
if (ret)
|
||||
goto fail_sb_buffer;
|
||||
ret = btrfs_init_workqueues(fs_info);
|
||||
if (ret)
|
||||
goto fail_sb_buffer;
|
||||
|
|
|
|||
|
|
@ -306,6 +306,16 @@ enum {
|
|||
#define BTRFS_WARNING_COMMIT_INTERVAL (300)
|
||||
#define BTRFS_DEFAULT_MAX_INLINE (2048)
|
||||
|
||||
enum btrfs_compression_type {
|
||||
BTRFS_COMPRESS_NONE = 0,
|
||||
BTRFS_COMPRESS_ZLIB = 1,
|
||||
BTRFS_COMPRESS_LZO = 2,
|
||||
BTRFS_COMPRESS_ZSTD = 3,
|
||||
BTRFS_NR_COMPRESS_TYPES = 4,
|
||||
|
||||
BTRFS_DEFRAG_DONT_COMPRESS,
|
||||
};
|
||||
|
||||
struct btrfs_dev_replace {
|
||||
/* See #define above */
|
||||
u64 replace_state;
|
||||
|
|
@ -508,6 +518,9 @@ struct btrfs_fs_info {
|
|||
u64 last_trans_log_full_commit;
|
||||
unsigned long long mount_opt;
|
||||
|
||||
/* Compress related structures. */
|
||||
void *compr_wsm[BTRFS_NR_COMPRESS_TYPES];
|
||||
|
||||
int compress_type;
|
||||
int compress_level;
|
||||
u32 commit_interval;
|
||||
|
|
|
|||
|
|
@ -182,6 +182,36 @@ static void zstd_calc_ws_mem_sizes(void)
|
|||
}
|
||||
}
|
||||
|
||||
int zstd_alloc_workspace_manager(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct zstd_workspace_manager *zwsm;
|
||||
struct list_head *ws;
|
||||
|
||||
ASSERT(fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] == NULL);
|
||||
zwsm = kzalloc(sizeof(*zwsm), GFP_KERNEL);
|
||||
if (!zwsm)
|
||||
return -ENOMEM;
|
||||
zstd_calc_ws_mem_sizes();
|
||||
zwsm->ops = &btrfs_zstd_compress;
|
||||
spin_lock_init(&zwsm->lock);
|
||||
init_waitqueue_head(&zwsm->wait);
|
||||
timer_setup(&zwsm->timer, zstd_reclaim_timer_fn, 0);
|
||||
|
||||
INIT_LIST_HEAD(&zwsm->lru_list);
|
||||
for (int i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++)
|
||||
INIT_LIST_HEAD(&zwsm->idle_ws[i]);
|
||||
fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] = zwsm;
|
||||
|
||||
ws = zstd_alloc_workspace(fs_info, ZSTD_BTRFS_MAX_LEVEL);
|
||||
if (IS_ERR(ws)) {
|
||||
btrfs_warn(NULL, "cannot preallocate zstd compression workspace");
|
||||
} else {
|
||||
set_bit(ZSTD_BTRFS_MAX_LEVEL - 1, &zwsm->active_map);
|
||||
list_add(ws, &zwsm->idle_ws[ZSTD_BTRFS_MAX_LEVEL - 1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zstd_init_workspace_manager(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct list_head *ws;
|
||||
|
|
@ -207,6 +237,29 @@ void zstd_init_workspace_manager(struct btrfs_fs_info *fs_info)
|
|||
}
|
||||
}
|
||||
|
||||
void zstd_free_workspace_manager(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
|
||||
struct workspace *workspace;
|
||||
|
||||
if (!zwsm)
|
||||
return;
|
||||
fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] = NULL;
|
||||
spin_lock_bh(&zwsm->lock);
|
||||
for (int i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++) {
|
||||
while (!list_empty(&zwsm->idle_ws[i])) {
|
||||
workspace = container_of(zwsm->idle_ws[i].next,
|
||||
struct workspace, list);
|
||||
list_del(&workspace->list);
|
||||
list_del(&workspace->lru_list);
|
||||
zstd_free_workspace(&workspace->list);
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&zwsm->lock);
|
||||
timer_delete_sync(&zwsm->timer);
|
||||
kfree(zwsm);
|
||||
}
|
||||
|
||||
void zstd_cleanup_workspace_manager(void)
|
||||
{
|
||||
struct workspace *workspace;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user