Skip to content

Commit 56e77fc

Browse files
adam900710kdave
authored andcommitted
btrfs: add generic workspace manager initialization
This involves: - Add (alloc|free)_workspace_manager helpers. These are the helper to alloc/free workspace_manager structure. The allocator will allocate a workspace_manager structure, initialize it, and pre-allocate one workspace for it. The freer will do the cleanup and set the manager pointer to NULL. - Call alloc_workspace_manager() inside btrfs_alloc_compress_wsm() - Call alloc_workspace_manager() inside btrfs_free_compress_wsm() For none, zlib and lzo compression algorithms. For now the generic per-fs workspace managers 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 afac362 commit 56e77fc

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

fs/btrfs/compression.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,40 @@ static void free_workspace(int type, struct list_head *ws)
773773
}
774774
}
775775

776+
static int alloc_workspace_manager(struct btrfs_fs_info *fs_info,
777+
enum btrfs_compression_type type)
778+
{
779+
struct workspace_manager *gwsm;
780+
struct list_head *workspace;
781+
782+
ASSERT(fs_info->compr_wsm[type] == NULL);
783+
gwsm = kzalloc(sizeof(*gwsm), GFP_KERNEL);
784+
if (!gwsm)
785+
return -ENOMEM;
786+
787+
INIT_LIST_HEAD(&gwsm->idle_ws);
788+
spin_lock_init(&gwsm->ws_lock);
789+
atomic_set(&gwsm->total_ws, 0);
790+
init_waitqueue_head(&gwsm->ws_wait);
791+
fs_info->compr_wsm[type] = gwsm;
792+
793+
/*
794+
* Preallocate one workspace for each compression type so we can
795+
* guarantee forward progress in the worst case
796+
*/
797+
workspace = alloc_workspace(fs_info, type, 0);
798+
if (IS_ERR(workspace)) {
799+
btrfs_warn(fs_info,
800+
"cannot preallocate compression workspace for %s, will try later",
801+
btrfs_compress_type2str(type));
802+
} else {
803+
atomic_set(&gwsm->total_ws, 1);
804+
gwsm->free_ws = 1;
805+
list_add(workspace, &gwsm->idle_ws);
806+
}
807+
return 0;
808+
}
809+
776810
static void btrfs_init_workspace_manager(struct btrfs_fs_info *fs_info, int type)
777811
{
778812
struct workspace_manager *wsm;
@@ -799,6 +833,26 @@ static void btrfs_init_workspace_manager(struct btrfs_fs_info *fs_info, int type
799833
}
800834
}
801835

836+
static void free_workspace_manager(struct btrfs_fs_info *fs_info,
837+
enum btrfs_compression_type type)
838+
{
839+
struct list_head *ws;
840+
struct workspace_manager *gwsm = fs_info->compr_wsm[type];
841+
842+
/* ZSTD uses its own workspace manager, should enter here. */
843+
ASSERT(type != BTRFS_COMPRESS_ZSTD && type < BTRFS_NR_COMPRESS_TYPES);
844+
if (!gwsm)
845+
return;
846+
fs_info->compr_wsm[type] = NULL;
847+
while (!list_empty(&gwsm->idle_ws)) {
848+
ws = gwsm->idle_ws.next;
849+
list_del(ws);
850+
free_workspace(type, ws);
851+
atomic_dec(&gwsm->total_ws);
852+
}
853+
kfree(gwsm);
854+
}
855+
802856
static void btrfs_cleanup_workspace_manager(int type)
803857
{
804858
struct workspace_manager *wsman;
@@ -1101,6 +1155,15 @@ int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info)
11011155
{
11021156
int ret;
11031157

1158+
ret = alloc_workspace_manager(fs_info, BTRFS_COMPRESS_NONE);
1159+
if (ret < 0)
1160+
goto error;
1161+
ret = alloc_workspace_manager(fs_info, BTRFS_COMPRESS_ZLIB);
1162+
if (ret < 0)
1163+
goto error;
1164+
ret = alloc_workspace_manager(fs_info, BTRFS_COMPRESS_LZO);
1165+
if (ret < 0)
1166+
goto error;
11041167
ret = zstd_alloc_workspace_manager(fs_info);
11051168
if (ret < 0)
11061169
goto error;
@@ -1112,6 +1175,9 @@ int btrfs_alloc_compress_wsm(struct btrfs_fs_info *fs_info)
11121175

11131176
void btrfs_free_compress_wsm(struct btrfs_fs_info *fs_info)
11141177
{
1178+
free_workspace_manager(fs_info, BTRFS_COMPRESS_NONE);
1179+
free_workspace_manager(fs_info, BTRFS_COMPRESS_ZLIB);
1180+
free_workspace_manager(fs_info, BTRFS_COMPRESS_LZO);
11151181
zstd_free_workspace_manager(fs_info);
11161182
}
11171183

0 commit comments

Comments
 (0)