]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: add exchange-range to file systems
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:01 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:06 +0000 (17:01 -0700)
Enable upgrading existing filesystems to support the file exchange range
feature.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
man/man8/xfs_admin.8
repair/globals.c
repair/globals.h
repair/phase2.c
repair/xfs_repair.c

index 4794d6774edeb2c63472bfa92ee4a7305840d794..63f8ee90307b30da692eee69068fdc2bfdd00aa8 100644 (file)
@@ -156,6 +156,13 @@ data fork extent count will be 2^48 - 1, while the maximum attribute fork
 extent count will be 2^32 - 1. The filesystem cannot be downgraded after this
 feature is enabled. Once enabled, the filesystem will not be mountable by
 older kernels.  This feature was added to Linux 5.19.
+.TP 0.4i
+.B exchange
+Upgrade a filesystem to support atomic file content exchanges through the
+XFS_IOC_EXCHANGE_RANGE ioctl, and to support online repairs of directories,
+extended attributes, symbolic links, and realtime free space metadata.
+The filesystem cannot be downgraded after this feature is enabled.
+Once enabled, the filesystem will not be mountable by older kernels.
 .RE
 .TP
 .BI \-U " uuid"
index 24f720c46afb7fb05cf2eaa386e7c6ffb1fc2ad1..c0c45df51d562aba4cfe6b42af19f9f0bdf05dac 100644 (file)
@@ -52,6 +52,7 @@ bool  features_changed;       /* did we change superblock feature bits? */
 bool   add_inobtcount;         /* add inode btree counts to AGI */
 bool   add_bigtime;            /* add support for timestamps up to 2486 */
 bool   add_nrext64;
+bool   add_exchrange;          /* add file content exchange support */
 
 /* misc status variables */
 
index b83a8ae65942aca964ff5d0a27081807860eb333..1eadfdbf9ae4f25b355f522267abb2c009de18ee 100644 (file)
@@ -93,6 +93,7 @@ extern bool   features_changed;       /* did we change superblock feature bits? */
 extern bool    add_inobtcount;         /* add inode btree counts to AGI */
 extern bool    add_bigtime;            /* add support for timestamps up to 2486 */
 extern bool    add_nrext64;
+extern bool    add_exchrange;          /* add file content exchange support */
 
 /* misc status variables */
 
index 06374817964cf057a21c615f9562f03b0b28981c..83f0c539bb5de462047103807edc29b8d0ea4167 100644 (file)
@@ -182,6 +182,34 @@ set_nrext64(
        return true;
 }
 
+static bool
+set_exchrange(
+       struct xfs_mount        *mp,
+       struct xfs_sb           *new_sb)
+{
+       if (xfs_has_exchange_range(mp)) {
+               printf(_("Filesystem already supports exchange-range.\n"));
+               exit(0);
+       }
+
+       if (!xfs_has_crc(mp)) {
+               printf(
+       _("File exchange-range feature only supported on V5 filesystems.\n"));
+               exit(0);
+       }
+
+       if (!xfs_has_reflink(mp)) {
+               printf(
+       _("File exchange-range feature cannot be added without reflink.\n"));
+               exit(0);
+       }
+
+       printf(_("Adding file exchange-range support to filesystem.\n"));
+       new_sb->sb_features_ro_compat |= XFS_SB_FEAT_INCOMPAT_EXCHRANGE;
+       new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+       return true;
+}
+
 struct check_state {
        struct xfs_sb           sb;
        uint64_t                features;
@@ -290,6 +318,8 @@ upgrade_filesystem(
                dirty |= set_bigtime(mp, &new_sb);
        if (add_nrext64)
                dirty |= set_nrext64(mp, &new_sb);
+       if (add_exchrange)
+               dirty |= set_exchrange(mp, &new_sb);
        if (!dirty)
                return;
 
index 88aa7554201ba80318f0ed808d2108b72af5175a..e325d61f10367ef410bcde8649abad2ea6c0a4b7 100644 (file)
@@ -69,6 +69,7 @@ enum c_opt_nums {
        CONVERT_INOBTCOUNT,
        CONVERT_BIGTIME,
        CONVERT_NREXT64,
+       CONVERT_EXCHRANGE,
        C_MAX_OPTS,
 };
 
@@ -77,6 +78,7 @@ static char *c_opts[] = {
        [CONVERT_INOBTCOUNT]    = "inobtcount",
        [CONVERT_BIGTIME]       = "bigtime",
        [CONVERT_NREXT64]       = "nrext64",
+       [CONVERT_EXCHRANGE]     = "exchange",
        [C_MAX_OPTS]            = NULL,
 };
 
@@ -360,6 +362,15 @@ process_args(int argc, char **argv)
                _("-c nrext64 only supports upgrades\n"));
                                        add_nrext64 = true;
                                        break;
+                               case CONVERT_EXCHRANGE:
+                                       if (!val)
+                                               do_abort(
+               _("-c exchange requires a parameter\n"));
+                                       if (strtol(val, NULL, 0) != 1)
+                                               do_abort(
+               _("-c exchange only supports upgrades\n"));
+                                       add_exchrange = true;
+                                       break;
                                default:
                                        unknown('c', val);
                                        break;