Skip to content

Commit afac362

Browse files
adam900710kdave
authored andcommitted
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 <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 0588d0a commit afac362

File tree

5 files changed

+93
-10
lines changed

5 files changed

+93
-10
lines changed

fs/btrfs/compression.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,24 @@ int btrfs_decompress(int type, const u8 *data_in, struct folio *dest_folio,
10971097
return ret;
10981098
}
10991099

1100+
int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info)
1101+
{
1102+
int ret;
1103+
1104+
ret = zstd_alloc_workspace_manager(fs_info);
1105+
if (ret < 0)
1106+
goto error;
1107+
return 0;
1108+
error:
1109+
btrfs_free_compress_wsm(fs_info);
1110+
return ret;
1111+
}
1112+
1113+
void btrfs_free_compress_wsm(struct btrfs_fs_info *fs_info)
1114+
{
1115+
zstd_free_workspace_manager(fs_info);
1116+
}
1117+
11001118
int __init btrfs_init_compress(void)
11011119
{
11021120
if (bioset_init(&btrfs_compressed_bioset, BIO_POOL_SIZE,

fs/btrfs/compression.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ static inline u32 btrfs_calc_input_length(struct folio *folio, u64 range_end, u6
8989
return min(range_end, folio_end(folio)) - cur;
9090
}
9191

92+
int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info);
93+
void btrfs_free_compress_wsm(struct btrfs_fs_info *fs_info);
94+
9295
int __init btrfs_init_compress(void);
9396
void __cold btrfs_exit_compress(void);
9497

@@ -112,16 +115,6 @@ int btrfs_compress_str2level(unsigned int type, const char *str);
112115
struct folio *btrfs_alloc_compr_folio(void);
113116
void btrfs_free_compr_folio(struct folio *folio);
114117

115-
enum btrfs_compression_type {
116-
BTRFS_COMPRESS_NONE = 0,
117-
BTRFS_COMPRESS_ZLIB = 1,
118-
BTRFS_COMPRESS_LZO = 2,
119-
BTRFS_COMPRESS_ZSTD = 3,
120-
BTRFS_NR_COMPRESS_TYPES = 4,
121-
122-
BTRFS_DEFRAG_DONT_COMPRESS,
123-
};
124-
125118
struct workspace_manager {
126119
struct list_head idle_ws;
127120
spinlock_t ws_lock;
@@ -188,6 +181,8 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
188181
int zstd_decompress(struct list_head *ws, const u8 *data_in,
189182
struct folio *dest_folio, unsigned long dest_pgoff, size_t srclen,
190183
size_t destlen);
184+
int zstd_alloc_workspace_manager(struct btrfs_fs_info *fs_info);
185+
void zstd_free_workspace_manager(struct btrfs_fs_info *fs_info);
191186
void zstd_init_workspace_manager(struct btrfs_fs_info *fs_info);
192187
void zstd_cleanup_workspace_manager(void);
193188
struct list_head *zstd_alloc_workspace(struct btrfs_fs_info *fs_info, int level);

fs/btrfs/disk-io.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
12481248

12491249
if (fs_info->fs_devices)
12501250
btrfs_close_devices(fs_info->fs_devices);
1251+
btrfs_free_compress_wsm(fs_info);
12511252
percpu_counter_destroy(&fs_info->stats_read_blocks);
12521253
percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
12531254
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
34073408
*/
34083409
fs_info->max_inline = min_t(u64, fs_info->max_inline, fs_info->sectorsize);
34093410

3411+
ret = btrfs_alloc_compress_wsm(fs_info);
3412+
if (ret)
3413+
goto fail_sb_buffer;
34103414
ret = btrfs_init_workqueues(fs_info);
34113415
if (ret)
34123416
goto fail_sb_buffer;

fs/btrfs/fs.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,16 @@ enum {
306306
#define BTRFS_WARNING_COMMIT_INTERVAL (300)
307307
#define BTRFS_DEFAULT_MAX_INLINE (2048)
308308

309+
enum btrfs_compression_type {
310+
BTRFS_COMPRESS_NONE = 0,
311+
BTRFS_COMPRESS_ZLIB = 1,
312+
BTRFS_COMPRESS_LZO = 2,
313+
BTRFS_COMPRESS_ZSTD = 3,
314+
BTRFS_NR_COMPRESS_TYPES = 4,
315+
316+
BTRFS_DEFRAG_DONT_COMPRESS,
317+
};
318+
309319
struct btrfs_dev_replace {
310320
/* See #define above */
311321
u64 replace_state;
@@ -508,6 +518,9 @@ struct btrfs_fs_info {
508518
u64 last_trans_log_full_commit;
509519
unsigned long long mount_opt;
510520

521+
/* Compress related structures. */
522+
void *compr_wsm[BTRFS_NR_COMPRESS_TYPES];
523+
511524
int compress_type;
512525
int compress_level;
513526
u32 commit_interval;

fs/btrfs/zstd.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,36 @@ static void zstd_calc_ws_mem_sizes(void)
182182
}
183183
}
184184

185+
int zstd_alloc_workspace_manager(struct btrfs_fs_info *fs_info)
186+
{
187+
struct zstd_workspace_manager *zwsm;
188+
struct list_head *ws;
189+
190+
ASSERT(fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] == NULL);
191+
zwsm = kzalloc(sizeof(*zwsm), GFP_KERNEL);
192+
if (!zwsm)
193+
return -ENOMEM;
194+
zstd_calc_ws_mem_sizes();
195+
zwsm->ops = &btrfs_zstd_compress;
196+
spin_lock_init(&zwsm->lock);
197+
init_waitqueue_head(&zwsm->wait);
198+
timer_setup(&zwsm->timer, zstd_reclaim_timer_fn, 0);
199+
200+
INIT_LIST_HEAD(&zwsm->lru_list);
201+
for (int i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++)
202+
INIT_LIST_HEAD(&zwsm->idle_ws[i]);
203+
fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] = zwsm;
204+
205+
ws = zstd_alloc_workspace(fs_info, ZSTD_BTRFS_MAX_LEVEL);
206+
if (IS_ERR(ws)) {
207+
btrfs_warn(NULL, "cannot preallocate zstd compression workspace");
208+
} else {
209+
set_bit(ZSTD_BTRFS_MAX_LEVEL - 1, &zwsm->active_map);
210+
list_add(ws, &zwsm->idle_ws[ZSTD_BTRFS_MAX_LEVEL - 1]);
211+
}
212+
return 0;
213+
}
214+
185215
void zstd_init_workspace_manager(struct btrfs_fs_info *fs_info)
186216
{
187217
struct list_head *ws;
@@ -207,6 +237,29 @@ void zstd_init_workspace_manager(struct btrfs_fs_info *fs_info)
207237
}
208238
}
209239

240+
void zstd_free_workspace_manager(struct btrfs_fs_info *fs_info)
241+
{
242+
struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
243+
struct workspace *workspace;
244+
245+
if (!zwsm)
246+
return;
247+
fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] = NULL;
248+
spin_lock_bh(&zwsm->lock);
249+
for (int i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++) {
250+
while (!list_empty(&zwsm->idle_ws[i])) {
251+
workspace = container_of(zwsm->idle_ws[i].next,
252+
struct workspace, list);
253+
list_del(&workspace->list);
254+
list_del(&workspace->lru_list);
255+
zstd_free_workspace(&workspace->list);
256+
}
257+
}
258+
spin_unlock_bh(&zwsm->lock);
259+
timer_delete_sync(&zwsm->timer);
260+
kfree(zwsm);
261+
}
262+
210263
void zstd_cleanup_workspace_manager(void)
211264
{
212265
struct workspace *workspace;

0 commit comments

Comments
 (0)