Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f51d2b59 authored by David Sterba's avatar David Sterba
Browse files

btrfs: allow to set compression level for zlib



Preliminary support for setting compression level for zlib, the
following works:

$ mount -o compess=zlib                 # default
$ mount -o compess=zlib0                # same
$ mount -o compess=zlib9                # level 9, slower sync, less data
$ mount -o compess=zlib1                # level 1, faster sync, more data
$ mount -o remount,compress=zlib3	# level set by remount

The compress-force works the same as compress'.  The level is visible in
the same format in /proc/mounts. Level set via file property does not
work yet.

Required patch: "btrfs: prepare for extensions in compression options"

Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent d4417e22
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -884,6 +884,11 @@ static void free_workspaces(void)
 * Given an address space and start and length, compress the bytes into @pages
 * that are allocated on demand.
 *
 * @type_level is encoded algorithm and level, where level 0 means whatever
 * default the algorithm chooses and is opaque here;
 * - compression algo are 0-3
 * - the level are bits 4-7
 *
 * @out_pages is an in/out parameter, holds maximum number of pages to allocate
 * and returns number of actually allocated pages
 *
@@ -898,7 +903,7 @@ static void free_workspaces(void)
 * @max_out tells us the max number of bytes that we're allowed to
 * stuff into pages
 */
int btrfs_compress_pages(int type, struct address_space *mapping,
int btrfs_compress_pages(unsigned int type_level, struct address_space *mapping,
			 u64 start, struct page **pages,
			 unsigned long *out_pages,
			 unsigned long *total_in,
@@ -906,9 +911,11 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
{
	struct list_head *workspace;
	int ret;
	int type = type_level & 0xF;

	workspace = find_workspace(type);

	btrfs_compress_op[type - 1]->set_level(workspace, type_level);
	ret = btrfs_compress_op[type-1]->compress_pages(workspace, mapping,
						      start, pages,
						      out_pages,
@@ -1098,3 +1105,14 @@ int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end)

	return ret;
}

unsigned int btrfs_compress_str2level(const char *str)
{
	if (strncmp(str, "zlib", 4) != 0)
		return 0;

	if ('1' <= str[4] && str[4] <= '9' )
		return str[4] - '0';

	return 0;
}
+5 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ struct compressed_bio {
void btrfs_init_compress(void);
void btrfs_exit_compress(void);

int btrfs_compress_pages(int type, struct address_space *mapping,
int btrfs_compress_pages(unsigned int type_level, struct address_space *mapping,
			 u64 start, struct page **pages,
			 unsigned long *out_pages,
			 unsigned long *total_in,
@@ -95,6 +95,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
				 int mirror_num, unsigned long bio_flags);

unsigned btrfs_compress_str2level(const char *str);

enum btrfs_compression_type {
	BTRFS_COMPRESS_NONE  = 0,
	BTRFS_COMPRESS_ZLIB  = 1,
@@ -124,6 +126,8 @@ struct btrfs_compress_op {
			  struct page *dest_page,
			  unsigned long start_byte,
			  size_t srclen, size_t destlen);

	void (*set_level)(struct list_head *ws, unsigned int type);
};

extern const struct btrfs_compress_op btrfs_zlib_compress;
+1 −0
Original line number Diff line number Diff line
@@ -790,6 +790,7 @@ struct btrfs_fs_info {
	 */
	unsigned long pending_changes;
	unsigned long compress_type:4;
	unsigned int compress_level;
	int commit_interval;
	/*
	 * It is a suggestive number, the read side is safe even it gets a
+4 −1
Original line number Diff line number Diff line
@@ -539,7 +539,10 @@ static noinline void compress_file_range(struct inode *inode,
		 */
		extent_range_clear_dirty_for_io(inode, start, end);
		redirty = 1;
		ret = btrfs_compress_pages(compress_type,

		/* Compression level is applied here and only here */
		ret = btrfs_compress_pages(
			compress_type | (fs_info->compress_level << 4),
					   inode->i_mapping, start,
					   pages,
					   &nr_pages,
+5 −0
Original line number Diff line number Diff line
@@ -430,10 +430,15 @@ static int lzo_decompress(struct list_head *ws, unsigned char *data_in,
	return ret;
}

static void lzo_set_level(struct list_head *ws, unsigned int type)
{
}

const struct btrfs_compress_op btrfs_lzo_compress = {
	.alloc_workspace	= lzo_alloc_workspace,
	.free_workspace		= lzo_free_workspace,
	.compress_pages		= lzo_compress_pages,
	.decompress_bio		= lzo_decompress_bio,
	.decompress		= lzo_decompress,
	.set_level		= lzo_set_level,
};
Loading