[PATCH 5/7] xfs_fsr: port to new file exchange library function

Darrick J. Wong
2024-10-25T06:33:46Z

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

Port fsr to use the new libfrog library functions to handle exchanging
mappings between the target and donor files.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fsr/xfs_fsr.c | 74 ++++++++++++++++++++++++++-------------------------------
1 file changed, 34 insertions(+), 40 deletions(-)

diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 22e134adfd73ab..8845ff172fcb2e 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -13,6 +13,7 @@
#include "libfrog/paths.h"
#include "libfrog/fsgeom.h"
#include "libfrog/bulkstat.h"
+#include "libfrog/file_exchange.h"

#include <fcntl.h>
#include <errno.h>
@@ -122,12 +123,6 @@ open_handle(
return 0;
}

-static int
-xfs_swapext(int fd, xfs_swapext_t *sx)
-{
- return ioctl(fd, XFS_IOC_SWAPEXT, sx);
-}
-
static int
xfs_fscounts(int fd, xfs_fsop_counts_t *counts)
{
@@ -1189,14 +1184,13 @@ packfile(
struct xfs_bulkstat *statp,
struct fsxattr *fsxp)
{
+ struct xfs_commit_range xdf;
int tfd = -1;
- int srval;
int retval = -1; /* Failure is the default */
int nextents, extent, cur_nextents, new_nextents;
unsigned blksz_dio;
unsigned dio_min;
struct dioattr dio;
- static xfs_swapext_t sx;
struct xfs_flock64 space;
off_t cnt, pos;
void *fbuf = NULL;
@@ -1239,6 +1233,16 @@ packfile(
goto out;
}

+ /*
+ * Snapshot file_fd before we start copying data but after tweaking
+ * forkoff.
+ */
+ error = xfrog_defragrange_prep(&xdf, file_fd->fd, statp, tfd);
+ if (error) {
+ fsrprintf(_("failed to prep for defrag: %s\n"), strerror(error));
+ goto out;
+ }
+
/* Setup extended inode flags, project identifier, etc */
if (fsxp->fsx_xflags || fsxp->fsx_projid) {
if (ioctl(tfd, FS_IOC_FSSETXATTR, fsxp) < 0) {
@@ -1446,19 +1450,6 @@ packfile(
goto out;
}

- error = -xfrog_bulkstat_v5_to_v1(file_fd, &sx.sx_stat, statp);
- if (error) {
- fsrprintf(_("bstat conversion error on %s: %s\n"),
- fname, strerror(error));
- goto out;
- }
-
- sx.sx_version = XFS_SX_VERSION;
- sx.sx_fdtarget = file_fd->fd;
- sx.sx_fdtmp = tfd;
- sx.sx_offset = 0;
- sx.sx_length = statp->bs_size;
-
/* switch to the owner's id, to keep quota in line */
if (fchown(tfd, statp->bs_uid, statp->bs_gid) < 0) {
if (vflag)
@@ -1468,25 +1459,28 @@ packfile(
}

/* Swap the extents */
- srval = xfs_swapext(file_fd->fd, &sx);
- if (srval < 0) {
- if (errno == ENOTSUP) {
- if (vflag || dflag)
- fsrprintf(_("%s: file type not supported\n"), fname);
- } else if (errno == EFAULT) {
- /* The file has changed since we started the copy */
- if (vflag || dflag)
- fsrprintf(_("%s: file modified defrag aborted\n"),
- fname);
- } else if (errno == EBUSY) {
- /* Timestamp has changed or mmap'ed file */
- if (vflag || dflag)
- fsrprintf(_("%s: file busy\n"), fname);
- } else {
- fsrprintf(_("XFS_IOC_SWAPEXT failed: %s: %s\n"),
- fname, strerror(errno));
- }
- goto out;
+ error = xfrog_defragrange(file_fd->fd, &xdf);
+ switch (error) {
+ case 0:
+ break;
+ case ENOTSUP:
+ if (vflag || dflag)
+ fsrprintf(_("%s: file type not supported\n"), fname);
+ break;
+ case EFAULT:
+ /* The file has changed since we started the copy */
+ if (vflag || dflag)
+ fsrprintf(_("%s: file modified defrag aborted\n"),
+ fname);
+ break;
+ case EBUSY:
+ /* Timestamp has changed or mmap'ed file */
+ if (vflag || dflag)
+ fsrprintf(_("%s: file busy\n"), fname);
+ break;
+ default:
+ fsrprintf(_("XFS_IOC_SWAPEXT failed: %s: %s\n"),
+ fname, strerror(error));
}

/* Report progress */