mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
btrfs: defrag: add flag to force no-compression
Currently the defrag ioctl cannot rewrite the extents without
compression. Add a new flag for that, as setting compression to 0 (or
"no compression") means to do no changes to compression so take what is
the current default, like mount options or properties.
The defrag setting overrides mount or properties. The compression
BTRFS_DEFRAG_DONT_COMPRESS is only used for in-memory operations and
does not need to have a fixed value.
Mount with zstd:9, copy test file from /usr/bin/ (about 260KB):
$ mount -o compress=zstd:9 /dev/vda /mnt
$ filefrag -vsb testfile
filefrag: -b needs a blocksize option, assuming 1024-byte blocks.
Filesystem type is: 9123683e
File size of testfile is 297704 (292 blocks of 1024 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 127: 13312.. 13439: 128: encoded
1: 128.. 255: 13364.. 13491: 128: 13440: encoded
2: 256.. 291: 13424.. 13459: 36: 13492: last,encoded,eof
testfile: 3 extents found
$ compsize testfile
Processed 1 file, 3 regular extents (3 refs), 0 inline, 1 fragments.
Type Perc Disk Usage Uncompressed Referenced
TOTAL 42% 124K 292K 292K
zstd 42% 124K 292K 292K
Defrag to uncompressed:
$ btrfs fi defrag --nocomp testfile
$ filefrag -vsb testfile
filefrag: -b needs a blocksize option, assuming 1024-byte blocks.
Filesystem type is: 9123683e
File size of testfile is 297704 (292 blocks of 1024 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 291: 291840.. 292131: 292: last,eof
testfile: 1 extent found
$ compsize testfile
Processed 1 file, 1 regular extents (1 refs), 0 inline, 1 fragments.
Type Perc Disk Usage Uncompressed Referenced
TOTAL 100% 292K 292K 292K
none 100% 292K 292K 292K
Compress again with LZO:
$ btrfs fi defrag -clzo testfile
$ filefrag -vsb testfile
filefrag: -b needs a blocksize option, assuming 1024-byte blocks.
Filesystem type is: 9123683e
File size of testfile is 297704 (292 blocks of 1024 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 127: 13312.. 13439: 128: encoded
1: 128.. 255: 13392.. 13519: 128: 13440: encoded
2: 256.. 291: 13480.. 13515: 36: 13520: last,encoded,eof
testfile: 3 extents found
$ compsize testfile
Processed 1 file, 3 regular extents (3 refs), 0 inline, 1 fragments.
Type Perc Disk Usage Uncompressed Referenced
TOTAL 64% 188K 292K 292K
lzo 64% 188K 292K 292K
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
@@ -113,6 +113,8 @@ enum btrfs_compression_type {
|
||||
BTRFS_COMPRESS_LZO = 2,
|
||||
BTRFS_COMPRESS_ZSTD = 3,
|
||||
BTRFS_NR_COMPRESS_TYPES = 4,
|
||||
|
||||
BTRFS_DEFRAG_DONT_COMPRESS,
|
||||
};
|
||||
|
||||
struct workspace_manager {
|
||||
|
||||
+9
-4
@@ -947,7 +947,7 @@ struct defrag_target_range {
|
||||
* @extent_thresh: file extent size threshold, any extent size >= this value
|
||||
* will be ignored
|
||||
* @newer_than: only defrag extents newer than this value
|
||||
* @do_compress: whether the defrag is doing compression
|
||||
* @do_compress: whether the defrag is doing compression or no-compression
|
||||
* if true, @extent_thresh will be ignored and all regular
|
||||
* file extents meeting @newer_than will be targets.
|
||||
* @locked: if the range has already held extent lock
|
||||
@@ -1364,6 +1364,7 @@ int btrfs_defrag_file(struct btrfs_inode *inode, struct file_ra_state *ra,
|
||||
u64 cur;
|
||||
u64 last_byte;
|
||||
bool do_compress = (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS);
|
||||
bool no_compress = (range->flags & BTRFS_DEFRAG_RANGE_NOCOMPRESS);
|
||||
int compress_type = BTRFS_COMPRESS_ZLIB;
|
||||
int compress_level = 0;
|
||||
int ret = 0;
|
||||
@@ -1394,6 +1395,9 @@ int btrfs_defrag_file(struct btrfs_inode *inode, struct file_ra_state *ra,
|
||||
if (range->compress_type)
|
||||
compress_type = range->compress_type;
|
||||
}
|
||||
} else if (range->flags & BTRFS_DEFRAG_RANGE_NOCOMPRESS) {
|
||||
compress_type = BTRFS_DEFRAG_DONT_COMPRESS;
|
||||
compress_level = 1;
|
||||
}
|
||||
|
||||
if (extent_thresh == 0)
|
||||
@@ -1444,13 +1448,14 @@ int btrfs_defrag_file(struct btrfs_inode *inode, struct file_ra_state *ra,
|
||||
btrfs_inode_unlock(inode, 0);
|
||||
break;
|
||||
}
|
||||
if (do_compress) {
|
||||
if (do_compress || no_compress) {
|
||||
inode->defrag_compress = compress_type;
|
||||
inode->defrag_compress_level = compress_level;
|
||||
}
|
||||
ret = defrag_one_cluster(inode, ra, cur,
|
||||
cluster_end + 1 - cur, extent_thresh,
|
||||
newer_than, do_compress, §ors_defragged,
|
||||
newer_than, do_compress || no_compress,
|
||||
§ors_defragged,
|
||||
max_to_defrag, &last_scanned);
|
||||
|
||||
if (sectors_defragged > prev_sectors_defragged)
|
||||
@@ -1489,7 +1494,7 @@ int btrfs_defrag_file(struct btrfs_inode *inode, struct file_ra_state *ra,
|
||||
btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
|
||||
ret = sectors_defragged;
|
||||
}
|
||||
if (do_compress) {
|
||||
if (do_compress || no_compress) {
|
||||
btrfs_inode_lock(inode, 0);
|
||||
inode->defrag_compress = BTRFS_COMPRESS_NONE;
|
||||
btrfs_inode_unlock(inode, 0);
|
||||
|
||||
+7
-4
@@ -781,12 +781,15 @@ static inline int inode_need_compress(struct btrfs_inode *inode, u64 start,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Defrag ioctl takes precedence over mount options and properties. */
|
||||
if (inode->defrag_compress == BTRFS_DEFRAG_DONT_COMPRESS)
|
||||
return 0;
|
||||
if (BTRFS_COMPRESS_NONE < inode->defrag_compress &&
|
||||
inode->defrag_compress < BTRFS_NR_COMPRESS_TYPES)
|
||||
return 1;
|
||||
/* force compress */
|
||||
if (btrfs_test_opt(fs_info, FORCE_COMPRESS))
|
||||
return 1;
|
||||
/* defrag ioctl */
|
||||
if (inode->defrag_compress)
|
||||
return 1;
|
||||
/* bad compression ratios */
|
||||
if (inode->flags & BTRFS_INODE_NOCOMPRESS)
|
||||
return 0;
|
||||
@@ -942,7 +945,7 @@ again:
|
||||
goto cleanup_and_bail_uncompressed;
|
||||
}
|
||||
|
||||
if (inode->defrag_compress) {
|
||||
if (0 < inode->defrag_compress && inode->defrag_compress < BTRFS_NR_COMPRESS_TYPES) {
|
||||
compress_type = inode->defrag_compress;
|
||||
compress_level = inode->defrag_compress_level;
|
||||
} else if (inode->prop_compress) {
|
||||
|
||||
+8
-2
@@ -2554,8 +2554,14 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
/* compression requires us to start the IO */
|
||||
if ((range.flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
|
||||
if ((range.flags & BTRFS_DEFRAG_RANGE_COMPRESS) &&
|
||||
(range.flags & BTRFS_DEFRAG_RANGE_NOCOMPRESS)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
/* Compression or no-compression require to start the IO. */
|
||||
if ((range.flags & BTRFS_DEFRAG_RANGE_COMPRESS) ||
|
||||
(range.flags & BTRFS_DEFRAG_RANGE_NOCOMPRESS)) {
|
||||
range.flags |= BTRFS_DEFRAG_RANGE_START_IO;
|
||||
range.extent_thresh = (u32)-1;
|
||||
}
|
||||
|
||||
@@ -616,8 +616,11 @@ struct btrfs_ioctl_clone_range_args {
|
||||
#define BTRFS_DEFRAG_RANGE_COMPRESS 1
|
||||
#define BTRFS_DEFRAG_RANGE_START_IO 2
|
||||
#define BTRFS_DEFRAG_RANGE_COMPRESS_LEVEL 4
|
||||
/* Request no compression on the range (uncompress if necessary). */
|
||||
#define BTRFS_DEFRAG_RANGE_NOCOMPRESS 8
|
||||
#define BTRFS_DEFRAG_RANGE_FLAGS_SUPP (BTRFS_DEFRAG_RANGE_COMPRESS | \
|
||||
BTRFS_DEFRAG_RANGE_COMPRESS_LEVEL | \
|
||||
BTRFS_DEFRAG_RANGE_NOCOMPRESS | \
|
||||
BTRFS_DEFRAG_RANGE_START_IO)
|
||||
|
||||
struct btrfs_ioctl_defrag_range_args {
|
||||
|
||||
Reference in New Issue
Block a user