[PATCH 6/7] xfs_io: add a commitrange option to the exchangerange command

Darrick J. Wong
2024-10-25T06:34:01Z

From: Darrick J. Wong <djwong@kernel.org>

Teach the xfs_io exchangerange command to be able to use the commit
range functionality so that we can test it piece by piece.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
io/exchrange.c | 26 ++++++++++++++++++++++----
man/man8/xfs_io.8 | 3 +++
2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/io/exchrange.c b/io/exchrange.c
index 016429280e2717..0a3750f1eb2607 100644
--- a/io/exchrange.c
+++ b/io/exchrange.c
@@ -19,6 +19,7 @@ exchangerange_help(void)
"\n"
" Exchange file data between the open file descriptor and the supplied filename.\n"
" -C -- Print timing information in a condensed format\n"
+" -c -- Commit to the exchange only if file2 has not changed.\n"
" -d N -- Start exchanging contents at this position in the open file\n"
" -f -- Flush changed file data and metadata to disk\n"
" -l N -- Exchange this many bytes between the two files instead of to EOF\n"
@@ -34,9 +35,9 @@ exchangerange_f(
int argc,
char **argv)
{
- struct xfs_exchange_range fxr;
struct stat stat;
struct timeval t1, t2;
+ bool use_commit = false;
uint64_t flags = XFS_EXCHANGE_RANGE_TO_EOF;
int64_t src_offset = 0;
int64_t dest_offset = 0;
@@ -53,6 +54,9 @@ exchangerange_f(
case 'C':
condensed = 1;
break;
+ case 'c':
+ use_commit = true;
+ break;
case 'd':
dest_offset = cvtnum(fsblocksize, fssectsize, optarg);
if (dest_offset < 0) {
@@ -117,8 +121,22 @@ exchangerange_f(
if (length < 0)
length = stat.st_size;

- xfrog_exchangerange_prep(&fxr, dest_offset, fd, src_offset, length);
- ret = xfrog_exchangerange(file->fd, &fxr, flags);
+ if (use_commit) {
+ struct xfs_commit_range xcr;
+
+ ret = xfrog_commitrange_prep(&xcr, file->fd, dest_offset, fd,
+ src_offset, length);
+ if (!ret) {
+ gettimeofday(&t1, NULL);
+ ret = xfrog_commitrange(file->fd, &xcr, flags);
+ }
+ } else {
+ struct xfs_exchange_range fxr;
+
+ xfrog_exchangerange_prep(&fxr, dest_offset, fd, src_offset,
+ length);
+ ret = xfrog_exchangerange(file->fd, &fxr, flags);
+ }
if (ret) {
xfrog_perror(ret, "exchangerange");
exitcode = 1;
@@ -149,7 +167,7 @@ static struct cmdinfo exchangerange_cmd = {
void
exchangerange_init(void)
{
- exchangerange_cmd.args = _("[-Cfntw] [-d dest_offset] [-s src_offset] [-l length] <donorfile>");
+ exchangerange_cmd.args = _("[-Ccfntw] [-d dest_offset] [-s src_offset] [-l length] <donorfile>");
exchangerange_cmd.oneline = _("Exchange contents between files.");

add_command(&exchangerange_cmd);
diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8
index 1e7901393ff4d4..49d4057bb069ed 100644
--- a/man/man8/xfs_io.8
+++ b/man/man8/xfs_io.8
@@ -732,6 +732,9 @@ .SH FILE I/O COMMANDS
.B \-C
Print timing information in a condensed format.
.TP
+.B \-c
+Exchange contents only if file2 has not changed.
+.TP
.BI \-d " dest_offset"
Swap extents with open file beginning at
.IR dest_offset .