Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

btrfs: zstd: support nagetive compress level. #8

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ static void free_heuristic_ws(struct list_head *ws)
kfree(workspace);
}

static struct list_head *alloc_heuristic_ws(unsigned int level)
static struct list_head *alloc_heuristic_ws(int level)
{
struct heuristic_ws *ws;

Expand Down Expand Up @@ -921,7 +921,7 @@ static const struct btrfs_compress_op * const btrfs_compress_op[] = {
&btrfs_zstd_compress,
};

static struct list_head *alloc_workspace(int type, unsigned int level)
static struct list_head *alloc_workspace(int type, int level)
{
switch (type) {
case BTRFS_COMPRESS_NONE: return alloc_heuristic_ws(level);
Expand Down Expand Up @@ -999,7 +999,7 @@ static void btrfs_cleanup_workspace_manager(int type)
* Preallocation makes a forward progress guarantees and we do not return
* errors.
*/
struct list_head *btrfs_get_workspace(int type, unsigned int level)
struct list_head *btrfs_get_workspace(int type, int level)
{
struct workspace_manager *wsm;
struct list_head *workspace;
Expand Down Expand Up @@ -1149,7 +1149,7 @@ static void put_workspace(int type, struct list_head *ws)
* Adjust @level according to the limits of the compression algorithm or
* fallback to default
*/
static unsigned int btrfs_compress_set_level(int type, unsigned level)
static int btrfs_compress_set_level(int type, int level)
{
const struct btrfs_compress_op *ops = btrfs_compress_op[type];

Expand Down Expand Up @@ -1716,16 +1716,19 @@ int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end)
* Convert the compression suffix (eg. after "zlib" starting with ":") to
* level, unrecognized string will set the default level
*/
unsigned int btrfs_compress_str2level(unsigned int type, const char *str)
int btrfs_compress_str2level(unsigned int type, const char *str)
{
unsigned int level = 0;
int level = 0;
int ret;

if (!type)
return 0;

if (type == BTRFS_COMPRESS_ZLIB && level < 1)
level = 1;

if (str[0] == ':') {
ret = kstrtouint(str + 1, 10, &level);
ret = kstrtoint(str + 1, 10, &level);
if (ret)
level = 0;
}
Expand Down
20 changes: 10 additions & 10 deletions fs/btrfs/compression.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static inline unsigned int btrfs_compress_type(unsigned int type_level)
return (type_level & 0xF);
}

static inline unsigned int btrfs_compress_level(unsigned int type_level)
static inline int btrfs_compress_level(unsigned int type_level)
{
return ((type_level & 0xF0) >> 4);
}
Expand Down Expand Up @@ -101,7 +101,7 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
void btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
int mirror_num);

unsigned int btrfs_compress_str2level(unsigned int type, const char *str);
int btrfs_compress_str2level(unsigned int type, const char *str);

enum btrfs_compression_type {
BTRFS_COMPRESS_NONE = 0,
Expand All @@ -122,14 +122,14 @@ struct workspace_manager {
wait_queue_head_t ws_wait;
};

struct list_head *btrfs_get_workspace(int type, unsigned int level);
struct list_head *btrfs_get_workspace(int type, int level);
void btrfs_put_workspace(int type, struct list_head *ws);

struct btrfs_compress_op {
struct workspace_manager *workspace_manager;
/* Maximum level supported by the compression algorithm */
unsigned int max_level;
unsigned int default_level;
int max_level;
int default_level;
};

/* The heuristic workspaces are managed via the 0th workspace manager */
Expand All @@ -152,9 +152,9 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
int zlib_decompress(struct list_head *ws, unsigned char *data_in,
struct page *dest_page, unsigned long start_byte, size_t srclen,
size_t destlen);
struct list_head *zlib_alloc_workspace(unsigned int level);
struct list_head *zlib_alloc_workspace(int level);
void zlib_free_workspace(struct list_head *ws);
struct list_head *zlib_get_workspace(unsigned int level);
struct list_head *zlib_get_workspace(int level);

int lzo_compress_pages(struct list_head *ws, struct address_space *mapping,
u64 start, struct page **pages, unsigned long *out_pages,
Expand All @@ -163,7 +163,7 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb);
int lzo_decompress(struct list_head *ws, unsigned char *data_in,
struct page *dest_page, unsigned long start_byte, size_t srclen,
size_t destlen);
struct list_head *lzo_alloc_workspace(unsigned int level);
struct list_head *lzo_alloc_workspace(int level);
void lzo_free_workspace(struct list_head *ws);

int zstd_compress_pages(struct list_head *ws, struct address_space *mapping,
Expand All @@ -175,9 +175,9 @@ int zstd_decompress(struct list_head *ws, unsigned char *data_in,
size_t destlen);
void zstd_init_workspace_manager(void);
void zstd_cleanup_workspace_manager(void);
struct list_head *zstd_alloc_workspace(unsigned int level);
struct list_head *zstd_alloc_workspace(int level);
void zstd_free_workspace(struct list_head *ws);
struct list_head *zstd_get_workspace(unsigned int level);
struct list_head *zstd_get_workspace(int level);
void zstd_put_workspace(struct list_head *ws);

#endif
2 changes: 1 addition & 1 deletion fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ struct btrfs_fs_info {
*/
unsigned long pending_changes;
unsigned long compress_type:4;
unsigned int compress_level;
int compress_level;
u32 commit_interval;
/*
* It is a suggestive number, the read side is safe even it gets a
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/lzo.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void lzo_free_workspace(struct list_head *ws)
kfree(workspace);
}

struct list_head *lzo_alloc_workspace(unsigned int level)
struct list_head *lzo_alloc_workspace(int level)
{
struct workspace *workspace;

Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct workspace {

static struct workspace_manager wsm;

struct list_head *zlib_get_workspace(unsigned int level)
struct list_head *zlib_get_workspace(int level)
{
struct list_head *ws = btrfs_get_workspace(BTRFS_COMPRESS_ZLIB, level);
struct workspace *workspace = list_entry(ws, struct workspace, list);
Expand All @@ -52,7 +52,7 @@ void zlib_free_workspace(struct list_head *ws)
kfree(workspace);
}

struct list_head *zlib_alloc_workspace(unsigned int level)
struct list_head *zlib_alloc_workspace(int level)
{
struct workspace *workspace;
int workspacesize;
Expand Down
25 changes: 13 additions & 12 deletions fs/btrfs/zstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG)
#define ZSTD_BTRFS_DEFAULT_LEVEL 3
#define ZSTD_BTRFS_MAX_LEVEL 15
#define ZSTD_BTRFS_MIN_LEVEL -15
/* 307s to avoid pathologically clashing with transaction commit */
#define ZSTD_BTRFS_RECLAIM_JIFFIES (307 * HZ)

static zstd_parameters zstd_get_btrfs_parameters(unsigned int level,
static zstd_parameters zstd_get_btrfs_parameters(int level,
size_t src_len)
{
zstd_parameters params = zstd_get_params(level, src_len);
Expand All @@ -43,8 +44,8 @@ struct workspace {
void *mem;
size_t size;
char *buf;
unsigned int level;
unsigned int req_level;
int level;
int req_level;
unsigned long last_used; /* jiffies */
struct list_head list;
struct list_head lru_list;
Expand Down Expand Up @@ -92,7 +93,7 @@ static inline struct workspace *list_to_workspace(struct list_head *list)
}

void zstd_free_workspace(struct list_head *ws);
struct list_head *zstd_alloc_workspace(unsigned int level);
struct list_head *zstd_alloc_workspace(int level);

/**
* Timer callback to free unused workspaces.
Expand All @@ -119,7 +120,7 @@ static void zstd_reclaim_timer_fn(struct timer_list *timer)
list_for_each_prev_safe(pos, next, &wsm.lru_list) {
struct workspace *victim = container_of(pos, struct workspace,
lru_list);
unsigned int level;
int level;

if (time_after(victim->last_used, reclaim_threshold))
break;
Expand Down Expand Up @@ -156,9 +157,9 @@ static void zstd_reclaim_timer_fn(struct timer_list *timer)
static void zstd_calc_ws_mem_sizes(void)
{
size_t max_size = 0;
unsigned int level;
int level;

for (level = 1; level <= ZSTD_BTRFS_MAX_LEVEL; level++) {
for (level = ZSTD_BTRFS_MIN_LEVEL; level <= ZSTD_BTRFS_MAX_LEVEL; level++) {
zstd_parameters params =
zstd_get_btrfs_parameters(level, ZSTD_BTRFS_MAX_INPUT);
size_t level_size =
Expand All @@ -184,7 +185,7 @@ void zstd_init_workspace_manager(void)
timer_setup(&wsm.timer, zstd_reclaim_timer_fn, 0);

INIT_LIST_HEAD(&wsm.lru_list);
for (i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++)
for (i = ZSTD_BTRFS_MIN_LEVEL; i < ZSTD_BTRFS_MAX_LEVEL; i++)
INIT_LIST_HEAD(&wsm.idle_ws[i]);

ws = zstd_alloc_workspace(ZSTD_BTRFS_MAX_LEVEL);
Expand All @@ -203,7 +204,7 @@ void zstd_cleanup_workspace_manager(void)
int i;

spin_lock_bh(&wsm.lock);
for (i = 0; i < ZSTD_BTRFS_MAX_LEVEL; i++) {
for (i = ZSTD_BTRFS_MIN_LEVEL; i < ZSTD_BTRFS_MAX_LEVEL; i++) {
while (!list_empty(&wsm.idle_ws[i])) {
workspace = container_of(wsm.idle_ws[i].next,
struct workspace, list);
Expand All @@ -228,7 +229,7 @@ void zstd_cleanup_workspace_manager(void)
* offer the opportunity to reclaim the workspace in favor of allocating an
* appropriately sized one in the future.
*/
static struct list_head *zstd_find_workspace(unsigned int level)
static struct list_head *zstd_find_workspace(int level)
{
struct list_head *ws;
struct workspace *workspace;
Expand Down Expand Up @@ -264,7 +265,7 @@ static struct list_head *zstd_find_workspace(unsigned int level)
* attempt to allocate a new workspace. If we fail to allocate one due to
* memory pressure, go to sleep waiting for the max level workspace to free up.
*/
struct list_head *zstd_get_workspace(unsigned int level)
struct list_head *zstd_get_workspace(int level)
{
struct list_head *ws;
unsigned int nofs_flag;
Expand Down Expand Up @@ -344,7 +345,7 @@ void zstd_free_workspace(struct list_head *ws)
kfree(workspace);
}

struct list_head *zstd_alloc_workspace(unsigned int level)
struct list_head *zstd_alloc_workspace(int level)
{
struct workspace *workspace;

Expand Down