From: David Sterba <dsterba@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: David Sterba <dsterba@suse.com>
Subject: [PATCH] btrfs-progs: defrag: new option --nocomp to do no-compression defrag
Date: Wed, 9 Jul 2025 17:29:28 +0200 [thread overview]
Message-ID: <20250709152928.1055-1-dsterba@suse.com> (raw)
Add new option --nocomp to set flag which will tell kernel to defragment
file extents without compression and decompress existing extents if
needed. The defrag setting will override any current compression
settings like mount options or file properties. The option is separate
from '-c' so it's more obvious it's mutually exclusive.
Signed-off-by: David Sterba <dsterba@suse.com>
---
Documentation/btrfs-filesystem.rst | 2 ++
cmds/filesystem.c | 19 ++++++++++++++++++-
kernel-shared/uapi/btrfs.h | 2 ++
libbtrfsutil/btrfs.h | 2 ++
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/Documentation/btrfs-filesystem.rst b/Documentation/btrfs-filesystem.rst
index 5852b4e6ddb7c4..146d88b65bbdff 100644
--- a/Documentation/btrfs-filesystem.rst
+++ b/Documentation/btrfs-filesystem.rst
@@ -124,6 +124,8 @@ defragment [options] <file>|<dir> [<file>|<dir>...]
1..9, *lzo* does not have any levels, *zstd* the standard levels 1..15 and also the
realtime -1..-15.
+ --nocomp
+ Do not compress while defragmenting, uncompress extents if needed.
-r
defragment files recursively in given directories, does not descend to
subvolumes or mount points
diff --git a/cmds/filesystem.c b/cmds/filesystem.c
index 54a186f023c218..40c4ee9d92581e 100644
--- a/cmds/filesystem.c
+++ b/cmds/filesystem.c
@@ -948,6 +948,7 @@ static const char * const cmd_filesystem_defrag_usage[] = {
OPTLINE("-r", "defragment files recursively"),
OPTLINE("-c[zlib,lzo,zstd]", "compress the file while defragmenting, optional parameter (no space in between)"),
OPTLINE("-L|--level level", "use given compression level if enabled (zlib: 1..9, zstd: -15..15, and 0 selects the default level)"),
+ OPTLINE("--nocomp", "don't compress while defragmenting (uncompress if needed)"),
OPTLINE("-f", "flush data to disk immediately after defragmenting"),
OPTLINE("-s start", "defragment only from byte onward"),
OPTLINE("-l len", "defragment only up to len bytes"),
@@ -1053,6 +1054,7 @@ static int cmd_filesystem_defrag(const struct cmd_struct *cmd,
int ret = 0;
int compress_type = BTRFS_COMPRESS_NONE;
int compress_level = 0;
+ bool opt_nocomp = false;
/*
* Kernel 4.19+ supports defragmention of files open read-only,
@@ -1085,10 +1087,11 @@ static int cmd_filesystem_defrag(const struct cmd_struct *cmd,
defrag_global_errors = 0;
optind = 0;
while(1) {
- enum { GETOPT_VAL_STEP = GETOPT_VAL_FIRST };
+ enum { GETOPT_VAL_STEP = GETOPT_VAL_FIRST, GETOPT_VAL_NOCOMP };
static const struct option long_options[] = {
{ "level", required_argument, NULL, 'L' },
{ "step", required_argument, NULL, GETOPT_VAL_STEP },
+ { "nocomp", no_argument, NULL, GETOPT_VAL_NOCOMP },
{ NULL, 0, NULL, 0 }
};
int c;
@@ -1099,6 +1102,11 @@ static int cmd_filesystem_defrag(const struct cmd_struct *cmd,
switch(c) {
case 'c':
+ if (opt_nocomp) {
+ error("cannot use compression with --nocomp");
+ return 1;
+ }
+
compress_type = BTRFS_COMPRESS_ZLIB;
if (optarg)
compress_type = parse_compress_type_arg(optarg);
@@ -1142,6 +1150,13 @@ static int cmd_filesystem_defrag(const struct cmd_struct *cmd,
case 'r':
recursive = true;
break;
+ case GETOPT_VAL_NOCOMP:
+ if (compress_level != BTRFS_COMPRESS_NONE) {
+ error("cannot use --nocomp with compression set");
+ return 1;
+ }
+ opt_nocomp = true;
+ break;
case GETOPT_VAL_STEP:
defrag_global_step = arg_strtou64_with_suffix(optarg);
if (defrag_global_step < SZ_256K) {
@@ -1171,6 +1186,8 @@ static int cmd_filesystem_defrag(const struct cmd_struct *cmd,
} else
defrag_global_range.compress_type = compress_type;
}
+ if (opt_nocomp)
+ defrag_global_range.flags |= BTRFS_DEFRAG_RANGE_NOCOMPRESS;
if (flush)
defrag_global_range.flags |= BTRFS_DEFRAG_RANGE_START_IO;
diff --git a/kernel-shared/uapi/btrfs.h b/kernel-shared/uapi/btrfs.h
index 9d536cb66b0934..11ab1120c0a1c8 100644
--- a/kernel-shared/uapi/btrfs.h
+++ b/kernel-shared/uapi/btrfs.h
@@ -646,8 +646,10 @@ _static_assert(sizeof(struct btrfs_ioctl_clone_range_args) == 32);
#define BTRFS_DEFRAG_RANGE_COMPRESS 1
#define BTRFS_DEFRAG_RANGE_START_IO 2
#define BTRFS_DEFRAG_RANGE_COMPRESS_LEVEL 4
+#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 {
diff --git a/libbtrfsutil/btrfs.h b/libbtrfsutil/btrfs.h
index 984c962fbd3d88..29320b5c0f7ae9 100644
--- a/libbtrfsutil/btrfs.h
+++ b/libbtrfsutil/btrfs.h
@@ -609,8 +609,10 @@ 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
+#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 {
--
2.49.0
reply other threads:[~2025-07-09 15:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250709152928.1055-1-dsterba@suse.com \
--to=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox