From: Darrick J. Wong <djwong@xxxxxxxxxx> Create a log incompat flag so that we only attempt to process swap extent log items if the filesystem supports it, and a geometry flag to advertise support if it's present. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_format.h | 6 +++ fs/xfs/libxfs/xfs_fs.h | 3 ++ fs/xfs/libxfs/xfs_sb.c | 3 ++ fs/xfs/libxfs/xfs_swapext.h | 75 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 fs/xfs/libxfs/xfs_swapext.h diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 4baafff619789..c0209bd21dba1 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -391,6 +391,12 @@ xfs_sb_has_incompat_feature( } #define XFS_SB_FEAT_INCOMPAT_LOG_XATTRS (1 << 0) /* Delayed Attributes */ + +/* + * Log contains SXI log intent items which are not otherwise protected by + * an INCOMPAT/RO_COMPAT feature flag. + */ +#define XFS_SB_FEAT_INCOMPAT_LOG_SWAPEXT (1U << 31) #define XFS_SB_FEAT_INCOMPAT_LOG_ALL \ (XFS_SB_FEAT_INCOMPAT_LOG_XATTRS) #define XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_LOG_ALL diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index ec92e6ded6b8b..63a145e50350b 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -240,6 +240,9 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_INOBTCNT (1 << 22) /* inobt btree counter */ #define XFS_FSOP_GEOM_FLAGS_NREXT64 (1 << 23) /* large extent counters */ +/* atomic file extent swap available to userspace */ +#define XFS_FSOP_GEOM_FLAGS_ATOMIC_SWAP (1U << 31) + /* * Minimum and maximum sizes need for growth checks. * diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 7f2a5aee0ab83..5de377c2b0fea 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -26,6 +26,7 @@ #include "xfs_health.h" #include "xfs_ag.h" #include "xfs_rtbitmap.h" +#include "xfs_swapext.h" /* * Physical superblock buffer manipulations. Shared with libxfs in userspace. @@ -1258,6 +1259,8 @@ xfs_fs_geometry( } if (xfs_has_large_extent_counts(mp)) geo->flags |= XFS_FSOP_GEOM_FLAGS_NREXT64; + if (xfs_atomic_swap_supported(mp)) + geo->flags |= XFS_FSOP_GEOM_FLAGS_ATOMIC_SWAP; geo->rtsectsize = sbp->sb_blocksize; geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp); diff --git a/fs/xfs/libxfs/xfs_swapext.h b/fs/xfs/libxfs/xfs_swapext.h new file mode 100644 index 0000000000000..01bb3271f6474 --- /dev/null +++ b/fs/xfs/libxfs/xfs_swapext.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2020-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong <djwong@xxxxxxxxxx> + */ +#ifndef __XFS_SWAPEXT_H_ +#define __XFS_SWAPEXT_H_ 1 + +/* + * Decide if this filesystem supports the minimum feature set required to use + * the swapext iteration code in non-atomic swap mode. This mode uses the + * BUI log items introduced for the rmapbt and reflink features, but does not + * use swapext log items to track progress over a file range. + */ +static inline bool +xfs_swapext_supports_nonatomic( + struct xfs_mount *mp) +{ + return xfs_has_reflink(mp) || xfs_has_rmapbt(mp); +} + +/* + * Decide if this filesystem has a new enough permanent feature set to protect + * swapext log items from being replayed on a kernel that does not have + * XFS_SB_FEAT_INCOMPAT_LOG_SWAPEXT set. + */ +static inline bool +xfs_swapext_can_use_without_log_assistance( + struct xfs_mount *mp) +{ + if (!xfs_sb_is_v5(&mp->m_sb)) + return false; + + if (xfs_sb_has_incompat_feature(&mp->m_sb, + ~(XFS_SB_FEAT_INCOMPAT_FTYPE | + XFS_SB_FEAT_INCOMPAT_SPINODES | + XFS_SB_FEAT_INCOMPAT_META_UUID | + XFS_SB_FEAT_INCOMPAT_BIGTIME | + XFS_SB_FEAT_INCOMPAT_NREXT64))) + return true; + + return false; +} + +/* + * Decide if atomic extent swapping could be used on this filesystem. This + * does not say anything about the filesystem's readiness to do that. + */ +static inline bool +xfs_atomic_swap_supported( + struct xfs_mount *mp) +{ + /* + * In theory, we could support atomic extent swapping by setting + * XFS_SB_FEAT_INCOMPAT_LOG_SWAPEXT on any filesystem and that would be + * sufficient to protect the swapext log items that would be created. + * However, we don't want to enable new features on a really old + * filesystem, so we'll only advertise atomic swap support on the ones + * that support BUI log items. + */ + if (xfs_swapext_supports_nonatomic(mp)) + return true; + + /* + * If the filesystem has an RO_COMPAT or INCOMPAT bit that we don't + * recognize, then it's new enough not to need INCOMPAT_LOG_SWAPEXT + * to protect swapext log items. + */ + if (xfs_swapext_can_use_without_log_assistance(mp)) + return true; + + return false; +} + +#endif /* __XFS_SWAPEXT_H_ */