diff options
author | Dennis Zhou <dennis@kernel.org> | 2019-02-04 15:20:04 -0500 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2019-02-25 08:13:32 -0500 |
commit | 7bf4994304e27454c5cf99de1d43033cb29b34fd (patch) | |
tree | 573166fb907ca78db50dfcad60921bf09a9f4923 /fs/btrfs/compression.c | |
parent | 92ee55303616a18135be91deff51799a5de81f9a (diff) |
btrfs: plumb level through the compression interface
Zlib compression supports multiple levels, but doesn't require changing
in how a workspace itself is created and managed. Zstd introduces a
different memory requirement such that higher levels of compression
require more memory.
This requires changes in how the alloc()/get() methods work for zstd.
This pach plumbs compression level through the interface as a parameter
in preparation for zstd compression levels. This gives the compression
types opportunity to create/manage based on the compression level.
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Dennis Zhou <dennis@kernel.org>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r-- | fs/btrfs/compression.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 7240f8df0ea2..ccd6bb2061f6 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -742,9 +742,9 @@ static void heuristic_cleanup_workspace_manager(void) | |||
742 | btrfs_cleanup_workspace_manager(&heuristic_wsm); | 742 | btrfs_cleanup_workspace_manager(&heuristic_wsm); |
743 | } | 743 | } |
744 | 744 | ||
745 | static struct list_head *heuristic_get_workspace(void) | 745 | static struct list_head *heuristic_get_workspace(unsigned int level) |
746 | { | 746 | { |
747 | return btrfs_get_workspace(&heuristic_wsm); | 747 | return btrfs_get_workspace(&heuristic_wsm, level); |
748 | } | 748 | } |
749 | 749 | ||
750 | static void heuristic_put_workspace(struct list_head *ws) | 750 | static void heuristic_put_workspace(struct list_head *ws) |
@@ -764,7 +764,7 @@ static void free_heuristic_ws(struct list_head *ws) | |||
764 | kfree(workspace); | 764 | kfree(workspace); |
765 | } | 765 | } |
766 | 766 | ||
767 | static struct list_head *alloc_heuristic_ws(void) | 767 | static struct list_head *alloc_heuristic_ws(unsigned int level) |
768 | { | 768 | { |
769 | struct heuristic_ws *ws; | 769 | struct heuristic_ws *ws; |
770 | 770 | ||
@@ -824,7 +824,7 @@ void btrfs_init_workspace_manager(struct workspace_manager *wsm, | |||
824 | * Preallocate one workspace for each compression type so we can | 824 | * Preallocate one workspace for each compression type so we can |
825 | * guarantee forward progress in the worst case | 825 | * guarantee forward progress in the worst case |
826 | */ | 826 | */ |
827 | workspace = wsm->ops->alloc_workspace(); | 827 | workspace = wsm->ops->alloc_workspace(0); |
828 | if (IS_ERR(workspace)) { | 828 | if (IS_ERR(workspace)) { |
829 | pr_warn( | 829 | pr_warn( |
830 | "BTRFS: cannot preallocate compression workspace, will try later\n"); | 830 | "BTRFS: cannot preallocate compression workspace, will try later\n"); |
@@ -853,7 +853,8 @@ void btrfs_cleanup_workspace_manager(struct workspace_manager *wsman) | |||
853 | * Preallocation makes a forward progress guarantees and we do not return | 853 | * Preallocation makes a forward progress guarantees and we do not return |
854 | * errors. | 854 | * errors. |
855 | */ | 855 | */ |
856 | struct list_head *btrfs_get_workspace(struct workspace_manager *wsm) | 856 | struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, |
857 | unsigned int level) | ||
857 | { | 858 | { |
858 | struct list_head *workspace; | 859 | struct list_head *workspace; |
859 | int cpus = num_online_cpus(); | 860 | int cpus = num_online_cpus(); |
@@ -899,7 +900,7 @@ again: | |||
899 | * context of btrfs_compress_bio/btrfs_compress_pages | 900 | * context of btrfs_compress_bio/btrfs_compress_pages |
900 | */ | 901 | */ |
901 | nofs_flag = memalloc_nofs_save(); | 902 | nofs_flag = memalloc_nofs_save(); |
902 | workspace = wsm->ops->alloc_workspace(); | 903 | workspace = wsm->ops->alloc_workspace(level); |
903 | memalloc_nofs_restore(nofs_flag); | 904 | memalloc_nofs_restore(nofs_flag); |
904 | 905 | ||
905 | if (IS_ERR(workspace)) { | 906 | if (IS_ERR(workspace)) { |
@@ -930,9 +931,9 @@ again: | |||
930 | return workspace; | 931 | return workspace; |
931 | } | 932 | } |
932 | 933 | ||
933 | static struct list_head *get_workspace(int type) | 934 | static struct list_head *get_workspace(int type, int level) |
934 | { | 935 | { |
935 | return btrfs_compress_op[type]->get_workspace(); | 936 | return btrfs_compress_op[type]->get_workspace(level); |
936 | } | 937 | } |
937 | 938 | ||
938 | /* | 939 | /* |
@@ -1003,12 +1004,13 @@ int btrfs_compress_pages(unsigned int type_level, struct address_space *mapping, | |||
1003 | unsigned long *total_out) | 1004 | unsigned long *total_out) |
1004 | { | 1005 | { |
1005 | int type = btrfs_compress_type(type_level); | 1006 | int type = btrfs_compress_type(type_level); |
1007 | int level = btrfs_compress_level(type_level); | ||
1006 | struct list_head *workspace; | 1008 | struct list_head *workspace; |
1007 | int ret; | 1009 | int ret; |
1008 | 1010 | ||
1009 | workspace = get_workspace(type); | 1011 | workspace = get_workspace(type, level); |
1010 | 1012 | ||
1011 | btrfs_compress_op[type]->set_level(workspace, type_level); | 1013 | btrfs_compress_op[type]->set_level(workspace, level); |
1012 | ret = btrfs_compress_op[type]->compress_pages(workspace, mapping, | 1014 | ret = btrfs_compress_op[type]->compress_pages(workspace, mapping, |
1013 | start, pages, | 1015 | start, pages, |
1014 | out_pages, | 1016 | out_pages, |
@@ -1037,7 +1039,7 @@ static int btrfs_decompress_bio(struct compressed_bio *cb) | |||
1037 | int ret; | 1039 | int ret; |
1038 | int type = cb->compress_type; | 1040 | int type = cb->compress_type; |
1039 | 1041 | ||
1040 | workspace = get_workspace(type); | 1042 | workspace = get_workspace(type, 0); |
1041 | ret = btrfs_compress_op[type]->decompress_bio(workspace, cb); | 1043 | ret = btrfs_compress_op[type]->decompress_bio(workspace, cb); |
1042 | put_workspace(type, workspace); | 1044 | put_workspace(type, workspace); |
1043 | 1045 | ||
@@ -1055,13 +1057,12 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, | |||
1055 | struct list_head *workspace; | 1057 | struct list_head *workspace; |
1056 | int ret; | 1058 | int ret; |
1057 | 1059 | ||
1058 | workspace = get_workspace(type); | 1060 | workspace = get_workspace(type, 0); |
1059 | |||
1060 | ret = btrfs_compress_op[type]->decompress(workspace, data_in, | 1061 | ret = btrfs_compress_op[type]->decompress(workspace, data_in, |
1061 | dest_page, start_byte, | 1062 | dest_page, start_byte, |
1062 | srclen, destlen); | 1063 | srclen, destlen); |
1063 | |||
1064 | put_workspace(type, workspace); | 1064 | put_workspace(type, workspace); |
1065 | |||
1065 | return ret; | 1066 | return ret; |
1066 | } | 1067 | } |
1067 | 1068 | ||
@@ -1489,7 +1490,7 @@ static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end, | |||
1489 | */ | 1490 | */ |
1490 | int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end) | 1491 | int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end) |
1491 | { | 1492 | { |
1492 | struct list_head *ws_list = get_workspace(0); | 1493 | struct list_head *ws_list = get_workspace(0, 0); |
1493 | struct heuristic_ws *ws; | 1494 | struct heuristic_ws *ws; |
1494 | u32 i; | 1495 | u32 i; |
1495 | u8 byte; | 1496 | u8 byte; |