btrfs: zstd use the passed through level instead of default
[sfrench/cifs-2.6.git] / fs / btrfs / zstd.c
index af6ec59972f5160e24c7499f3ea384b4ee298c9d..a951d4fe77f7de51607c42c91d2dd5820bb26932 100644 (file)
 #define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG)
 #define ZSTD_BTRFS_DEFAULT_LEVEL 3
 
-static ZSTD_parameters zstd_get_btrfs_parameters(size_t src_len)
+static ZSTD_parameters zstd_get_btrfs_parameters(unsigned int level,
+                                                size_t src_len)
 {
-       ZSTD_parameters params = ZSTD_getParams(ZSTD_BTRFS_DEFAULT_LEVEL,
-                                               src_len, 0);
+       ZSTD_parameters params = ZSTD_getParams(level, src_len, 0);
 
        if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG)
                params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG;
@@ -36,11 +36,39 @@ struct workspace {
        void *mem;
        size_t size;
        char *buf;
+       unsigned int req_level;
        struct list_head list;
        ZSTD_inBuffer in_buf;
        ZSTD_outBuffer out_buf;
 };
 
+static struct workspace_manager wsm;
+
+static void zstd_init_workspace_manager(void)
+{
+       btrfs_init_workspace_manager(&wsm, &btrfs_zstd_compress);
+}
+
+static void zstd_cleanup_workspace_manager(void)
+{
+       btrfs_cleanup_workspace_manager(&wsm);
+}
+
+static struct list_head *zstd_get_workspace(unsigned int level)
+{
+       struct list_head *ws = btrfs_get_workspace(&wsm, level);
+       struct workspace *workspace = list_entry(ws, struct workspace, list);
+
+       workspace->req_level = level;
+
+       return ws;
+}
+
+static void zstd_put_workspace(struct list_head *ws)
+{
+       btrfs_put_workspace(&wsm, ws);
+}
+
 static void zstd_free_workspace(struct list_head *ws)
 {
        struct workspace *workspace = list_entry(ws, struct workspace, list);
@@ -50,10 +78,10 @@ static void zstd_free_workspace(struct list_head *ws)
        kfree(workspace);
 }
 
-static struct list_head *zstd_alloc_workspace(void)
+static struct list_head *zstd_alloc_workspace(unsigned int level)
 {
        ZSTD_parameters params =
-                       zstd_get_btrfs_parameters(ZSTD_BTRFS_MAX_INPUT);
+                       zstd_get_btrfs_parameters(level, ZSTD_BTRFS_MAX_INPUT);
        struct workspace *workspace;
 
        workspace = kzalloc(sizeof(*workspace), GFP_KERNEL);
@@ -95,7 +123,8 @@ static int zstd_compress_pages(struct list_head *ws,
        unsigned long len = *total_out;
        const unsigned long nr_dest_pages = *out_pages;
        unsigned long max_out = nr_dest_pages * PAGE_SIZE;
-       ZSTD_parameters params = zstd_get_btrfs_parameters(len);
+       ZSTD_parameters params = zstd_get_btrfs_parameters(workspace->req_level,
+                                                          len);
 
        *out_pages = 0;
        *total_out = 0;
@@ -419,11 +448,16 @@ finish:
        return ret;
 }
 
-static void zstd_set_level(struct list_head *ws, unsigned int type)
+static unsigned int zstd_set_level(unsigned int level)
 {
+       return ZSTD_BTRFS_DEFAULT_LEVEL;
 }
 
 const struct btrfs_compress_op btrfs_zstd_compress = {
+       .init_workspace_manager = zstd_init_workspace_manager,
+       .cleanup_workspace_manager = zstd_cleanup_workspace_manager,
+       .get_workspace = zstd_get_workspace,
+       .put_workspace = zstd_put_workspace,
        .alloc_workspace = zstd_alloc_workspace,
        .free_workspace = zstd_free_workspace,
        .compress_pages = zstd_compress_pages,