* [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters
@ 2022-01-21 5:19 Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 01/20] xfs_repair: check filesystem geometry before allowing upgrades Chandan Babu R
` (19 more replies)
0 siblings, 20 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:19 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This patchset implements the changes to userspace programs that are
required to support extending inode's data and attr fork extent
counter fields. These changes allow programs in xfsprogs to be able to
create and work with filesystem instances with 64-bit data fork extent
counter and 32-bit attr fork extent counter fields.
The patchset can also be obtained from
https://github.com/chandanr/xfsprogs-dev.git at branch
xfs-incompat-extend-extcnt-v5.
Changelog:
V4 -> V5:
1. Rebase on Darrick's upgrade-older-features branch.
2. Recompute transaction reservation values before checking if
upgrading an fs to a new feature would succeed.
3. xfs_db: Revert back display names of per-inode extent counter
fields to nextents and naextents. Use the value from the appropriate
field of disk inode based on whether the inode has nrext64 feature
bit set or not.
4. Skip nrext64_pad when printing entire inode.
5. Report nrext64 support through xfs_db's version command.
6. Update xfs_admin's manual page to show that xfs_admin can try to
upgrade an fs to nrext64 feature.
V3 -> V4:
1. Rebase patchset on top of Darrick's "xfs: kill XFS_BTREE_MAXLEVELS"
patchset.
2. Carve out a 64-bit inode field out of the existing di_pad and
di_flushiter fields to hold the 64-bit data fork extent counter.
3. Use the existing 32-bit inode data fork extent counter to hold the
attr fork extent counter.
4. Pass XFS_BULK_IREQ_NREXT64 flag to the bulkstat ioctl if the
underlying filesystem support for large exent counters is detected
by the presence of XFS_FSOP_GEOM_FLAGS_NREXT64 bit.
V2 -> V3:
1. Introduce the ability to upgrade existing filesystems to use 64-bit
extent counters if it is feasible to do so.
2. Report presence of 64-bit extent counters via xfs_info.
3. Add XFS_SB_FEAT_INCOMPAT_NREXT64 to XFS_SB_FEAT_INCOMPAT_ALL in a
separate patch.
4. Rename mkfs.xfs option from extcnt64bit to nrext64.
V1 -> V2:
1. Rebase patches on top of Darrick's btree-dynamic-depth branch.
2. Add support for using the new bulkstat ioctl version to support
64-bit data fork extent counter field.
Chandan Babu R (19):
xfsprogs: Move extent count limits to xfs_format.h
xfsprogs: Introduce xfs_iext_max_nextents() helper
xfsprogs: Use xfs_extnum_t instead of basic data types
xfsprogs: Introduce xfs_dfork_nextents() helper
xfsprogs: Use basic types to define xfs_log_dinode's di_nextents and
di_anextents
xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits
respectively
xfsprogs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs
feature bit
xfsprogs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
xfsprogs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers
xfsprogs: Use xfs_rfsblock_t to count maximum blocks that can be used
by BMBT
xfsprogs: Introduce macros to represent new maximum extent counts for
data/attr forks
xfsprogs: Introduce per-inode 64-bit extent counters
xfsprogs: Conditionally upgrade existing inodes to use 64-bit extent
counters
xfsprogs: Enable bulkstat ioctl to support 64-bit extent counters
xfsprogs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported
flags
xfsprogs: xfs_info: Report NREXT64 feature status
xfsprogs: Add mkfs option to create filesystem with large extent
counters
xfsprogs: Add support for upgrading to NREXT64 feature
xfsprogs: Define max extent length based on on-disk format definition
Darrick J. Wong (1):
xfs_repair: check filesystem geometry before allowing upgrades
db/bmap.c | 8 +-
db/btdump.c | 4 +-
db/check.c | 28 +++--
db/field.c | 4 -
db/field.h | 2 -
db/frag.c | 8 +-
db/inode.c | 224 ++++++++++++++++++++++++++++++++++++--
db/metadump.c | 6 +-
db/sb.c | 2 +
fsr/xfs_fsr.c | 4 +-
include/libxfs.h | 1 +
include/xfs_inode.h | 5 +
include/xfs_mount.h | 3 +
io/bulkstat.c | 1 +
libfrog/bulkstat.c | 29 ++++-
libfrog/fsgeom.c | 6 +-
libxfs/init.c | 24 ++--
libxfs/libxfs_api_defs.h | 3 +
libxfs/xfs_bmap.c | 77 +++++++------
libxfs/xfs_bmap_btree.c | 2 +-
libxfs/xfs_format.h | 60 ++++++++--
libxfs/xfs_fs.h | 13 ++-
libxfs/xfs_ialloc.c | 2 +
libxfs/xfs_inode_buf.c | 62 ++++++++---
libxfs/xfs_inode_fork.c | 13 ++-
libxfs/xfs_inode_fork.h | 59 +++++++++-
libxfs/xfs_log_format.h | 22 +++-
libxfs/xfs_sb.c | 6 +
libxfs/xfs_trans_resv.c | 10 +-
libxfs/xfs_types.h | 11 +-
logprint/log_misc.c | 20 +++-
logprint/log_print_all.c | 18 ++-
man/man8/mkfs.xfs.8.in | 7 ++
man/man8/xfs_admin.8 | 7 ++
mkfs/lts_4.19.conf | 1 +
mkfs/lts_5.10.conf | 1 +
mkfs/lts_5.15.conf | 1 +
mkfs/lts_5.4.conf | 1 +
mkfs/xfs_mkfs.c | 29 ++++-
repair/attr_repair.c | 2 +-
repair/dinode.c | 95 +++++++++-------
repair/dinode.h | 4 +-
repair/globals.c | 1 +
repair/globals.h | 1 +
repair/phase2.c | 230 +++++++++++++++++++++++++++++++++++++--
repair/phase4.c | 2 +-
repair/prefetch.c | 2 +-
repair/scan.c | 6 +-
repair/xfs_repair.c | 11 ++
49 files changed, 925 insertions(+), 213 deletions(-)
--
2.30.2
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V5 01/20] xfs_repair: check filesystem geometry before allowing upgrades
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 02/20] xfsprogs: Move extent count limits to xfs_format.h Chandan Babu R
` (18 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Darrick J. Wong, david, Chandan Babu R
From: "Darrick J. Wong" <djwong@kernel.org>
Currently, the two V5 feature upgrades permitted by xfs_repair do not
affect filesystem space usage, so we haven't needed to verify the
geometry.
However, this will change once we start to allow the sysadmin to add new
metadata indexes to existing filesystems. Add all the infrastructure we
need to ensure that the log will still be large enough, that there's
enough space for metadata space reservations, and the root inode will
still be where we expect it to be after the upgrade.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
[Recompute transaction reservation values; Exit with error if upgrade fails]
---
include/libxfs.h | 1 +
include/xfs_mount.h | 1 +
libxfs/init.c | 24 +++--
libxfs/libxfs_api_defs.h | 3 +
repair/phase2.c | 206 +++++++++++++++++++++++++++++++++++++--
5 files changed, 218 insertions(+), 17 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index 915bf511..7d6e9a33 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -77,6 +77,7 @@ struct iomap;
#include "xfs_refcount_btree.h"
#include "xfs_refcount.h"
#include "xfs_btree_staging.h"
+#include "xfs_ag_resv.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index bd464fbb..8139831b 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -256,6 +256,7 @@ __XFS_UNSUPP_OPSTATE(shutdown)
#define LIBXFS_BHASHSIZE(sbp) (1<<10)
+void libxfs_compute_all_maxlevels(struct xfs_mount *mp);
struct xfs_mount *libxfs_mount(struct xfs_mount *mp, struct xfs_sb *sb,
dev_t dev, dev_t logdev, dev_t rtdev, unsigned int flags);
int libxfs_flush_mount(struct xfs_mount *mp);
diff --git a/libxfs/init.c b/libxfs/init.c
index 94a80234..c02992a9 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -724,6 +724,21 @@ xfs_agbtree_compute_maxlevels(
mp->m_agbtree_maxlevels = max(levels, mp->m_refc_maxlevels);
}
+/* Compute maximum possible height of all btrees. */
+void
+libxfs_compute_all_maxlevels(
+ struct xfs_mount *mp)
+{
+ xfs_alloc_compute_maxlevels(mp);
+ xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
+ xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
+ xfs_ialloc_setup_geometry(mp);
+ xfs_rmapbt_compute_maxlevels(mp);
+ xfs_refcountbt_compute_maxlevels(mp);
+
+ xfs_agbtree_compute_maxlevels(mp);
+}
+
/*
* Mount structure initialization, provides a filled-in xfs_mount_t
* such that the numerous XFS_* macros can be used. If dev is zero,
@@ -768,14 +783,7 @@ libxfs_mount(
mp->m_swidth = sbp->sb_width;
}
- xfs_alloc_compute_maxlevels(mp);
- xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
- xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
- xfs_ialloc_setup_geometry(mp);
- xfs_rmapbt_compute_maxlevels(mp);
- xfs_refcountbt_compute_maxlevels(mp);
-
- xfs_agbtree_compute_maxlevels(mp);
+ libxfs_compute_all_maxlevels(mp);
/*
* Check that the data (and log if separate) are an ok size.
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 064fb48c..accac5ca 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -21,6 +21,8 @@
#define xfs_ag_init_headers libxfs_ag_init_headers
#define xfs_ag_block_count libxfs_ag_block_count
+#define xfs_ag_resv_init libxfs_ag_resv_init
+#define xfs_ag_resv_free libxfs_ag_resv_free
#define xfs_alloc_ag_max_usable libxfs_alloc_ag_max_usable
#define xfs_allocbt_maxlevels_ondisk libxfs_allocbt_maxlevels_ondisk
@@ -110,6 +112,7 @@
#define xfs_highbit32 libxfs_highbit32
#define xfs_highbit64 libxfs_highbit64
#define xfs_ialloc_calc_rootino libxfs_ialloc_calc_rootino
+#define xfs_ialloc_read_agi libxfs_ialloc_read_agi
#define xfs_iallocbt_maxlevels_ondisk libxfs_iallocbt_maxlevels_ondisk
#define xfs_idata_realloc libxfs_idata_realloc
#define xfs_idestroy_fork libxfs_idestroy_fork
diff --git a/repair/phase2.c b/repair/phase2.c
index 13832701..4c315055 100644
--- a/repair/phase2.c
+++ b/repair/phase2.c
@@ -133,7 +133,8 @@ zero_log(
static bool
set_inobtcount(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_sb *new_sb)
{
if (!xfs_has_crc(mp)) {
printf(
@@ -153,14 +154,15 @@ set_inobtcount(
}
printf(_("Adding inode btree counts to filesystem.\n"));
- mp->m_sb.sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
- mp->m_sb.sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+ new_sb->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+ new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
return true;
}
static bool
set_bigtime(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ struct xfs_sb *new_sb)
{
if (!xfs_has_crc(mp)) {
printf(
@@ -174,28 +176,214 @@ set_bigtime(
}
printf(_("Adding large timestamp support to filesystem.\n"));
- mp->m_sb.sb_features_incompat |= (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR |
- XFS_SB_FEAT_INCOMPAT_BIGTIME);
+ new_sb->sb_features_incompat |= (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR |
+ XFS_SB_FEAT_INCOMPAT_BIGTIME);
return true;
}
+struct check_state {
+ struct xfs_sb sb;
+ uint64_t features;
+ bool finobt_nores;
+};
+
+static inline void
+capture_old_state(
+ struct check_state *old_state,
+ const struct xfs_mount *mp)
+{
+ memcpy(&old_state->sb, &mp->m_sb, sizeof(struct xfs_sb));
+ old_state->finobt_nores = mp->m_finobt_nores;
+ old_state->features = mp->m_features;
+}
+
+static inline void
+restore_old_state(
+ struct xfs_mount *mp,
+ const struct check_state *old_state)
+{
+ memcpy(&mp->m_sb, &old_state->sb, sizeof(struct xfs_sb));
+ mp->m_finobt_nores = old_state->finobt_nores;
+ mp->m_features = old_state->features;
+ libxfs_compute_all_maxlevels(mp);
+ libxfs_trans_init(mp);
+}
+
+static inline void
+install_new_state(
+ struct xfs_mount *mp,
+ struct xfs_sb *new_sb)
+{
+ memcpy(&mp->m_sb, new_sb, sizeof(struct xfs_sb));
+ mp->m_features |= libxfs_sb_version_to_features(new_sb);
+ libxfs_compute_all_maxlevels(mp);
+ libxfs_trans_init(mp);
+}
+
+/*
+ * Make sure we can actually upgrade this (v5) filesystem without running afoul
+ * of root inode or log size requirements that would prevent us from mounting
+ * the filesystem. If everything checks out, commit the new geometry.
+ */
+static void
+install_new_geometry(
+ struct xfs_mount *mp,
+ struct xfs_sb *new_sb)
+{
+ struct check_state old;
+ struct xfs_perag *pag;
+ xfs_ino_t rootino;
+ xfs_agnumber_t agno;
+ int min_logblocks;
+ int error;
+
+ capture_old_state(&old, mp);
+ install_new_state(mp, new_sb);
+
+ /*
+ * The existing log must be large enough to satisfy the new minimum log
+ * size requirements.
+ */
+ min_logblocks = libxfs_log_calc_minimum_size(mp);
+ if (old.sb.sb_logblocks < min_logblocks) {
+ printf(
+ _("Filesystem log too small to upgrade filesystem; need %u blocks, have %u.\n"),
+ min_logblocks, old.sb.sb_logblocks);
+ exit(1);
+ }
+
+ /*
+ * The root inode must be where xfs_repair will expect it to be with
+ * the new geometry.
+ */
+ rootino = libxfs_ialloc_calc_rootino(mp, new_sb->sb_unit);
+ if (old.sb.sb_rootino != rootino) {
+ printf(
+ _("Cannot upgrade filesystem, root inode (%llu) cannot be moved to %llu.\n"),
+ (unsigned long long)old.sb.sb_rootino,
+ (unsigned long long)rootino);
+ exit(1);
+ }
+
+ /* Make sure we have enough space for per-AG reservations. */
+ for_each_perag(mp, agno, pag) {
+ struct xfs_trans *tp;
+ struct xfs_agf *agf;
+ struct xfs_buf *agi_bp, *agf_bp;
+ unsigned int avail, agblocks;
+
+ /* Put back the old super so that we can read AG headers. */
+ restore_old_state(mp, &old);
+
+ /*
+ * Create a dummy transaction so that we can load the AGI and
+ * AGF buffers in memory with the old fs geometry and pin them
+ * there while we try to make a per-AG reservation with the new
+ * geometry.
+ */
+ error = -libxfs_trans_alloc_empty(mp, &tp);
+ if (error)
+ do_error(
+ _("Cannot reserve resources for upgrade check, err=%d.\n"),
+ error);
+
+ error = -libxfs_ialloc_read_agi(mp, tp, pag->pag_agno,
+ &agi_bp);
+ if (error)
+ do_error(
+ _("Cannot read AGI %u for upgrade check, err=%d.\n"),
+ pag->pag_agno, error);
+
+ error = -libxfs_alloc_read_agf(mp, tp, pag->pag_agno, 0,
+ &agf_bp);
+ if (error)
+ do_error(
+ _("Cannot read AGF %u for upgrade check, err=%d.\n"),
+ pag->pag_agno, error);
+ agf = agf_bp->b_addr;
+ agblocks = be32_to_cpu(agf->agf_length);
+
+ /*
+ * Install the new superblock and try to make a per-AG space
+ * reservation with the new geometry. We pinned the AG header
+ * buffers to the transaction, so we shouldn't hit any
+ * corruption errors on account of the new geometry.
+ */
+ install_new_state(mp, new_sb);
+
+ error = -libxfs_ag_resv_init(pag, tp);
+ if (error == ENOSPC) {
+ printf(
+ _("Not enough free space would remain in AG %u for metadata.\n"),
+ pag->pag_agno);
+ exit(1);
+ }
+ if (error)
+ do_error(
+ _("Error %d while checking AG %u space reservation.\n"),
+ error, pag->pag_agno);
+
+ /*
+ * Would we have at least 10% free space in this AG after
+ * making per-AG reservations?
+ */
+ avail = pag->pagf_freeblks + pag->pagf_flcount;
+ avail -= pag->pag_meta_resv.ar_reserved;
+ avail -= pag->pag_rmapbt_resv.ar_asked;
+ if (avail < agblocks / 10)
+ printf(
+ _("AG %u will be low on space after upgrade.\n"),
+ pag->pag_agno);
+ libxfs_trans_cancel(tp);
+ }
+
+ /*
+ * Would we have at least 10% free space in the data device after all
+ * the upgrades?
+ */
+ if (mp->m_sb.sb_fdblocks < mp->m_sb.sb_dblocks / 10)
+ printf(_("Filesystem will be low on space after upgrade.\n"));
+
+ /*
+ * Release the per-AG reservations and mark the per-AG structure as
+ * uninitialized so that we don't trip over stale cached counters
+ * after the upgrade/
+ */
+ for_each_perag(mp, agno, pag) {
+ libxfs_ag_resv_free(pag);
+ pag->pagf_init = 0;
+ pag->pagi_init = 0;
+ }
+
+ /*
+ * Restore the old state to get everything back to a clean state,
+ * upgrade the featureset one more time, and recompute the btree max
+ * levels for this filesystem.
+ */
+ restore_old_state(mp, &old);
+ install_new_state(mp, new_sb);
+}
+
/* Perform the user's requested upgrades on filesystem. */
static void
upgrade_filesystem(
struct xfs_mount *mp)
{
+ struct xfs_sb new_sb;
struct xfs_buf *bp;
bool dirty = false;
int error;
+ memcpy(&new_sb, &mp->m_sb, sizeof(struct xfs_sb));
+
if (add_inobtcount)
- dirty |= set_inobtcount(mp);
+ dirty |= set_inobtcount(mp, &new_sb);
if (add_bigtime)
- dirty |= set_bigtime(mp);
+ dirty |= set_bigtime(mp, &new_sb);
if (!dirty)
return;
- mp->m_features |= libxfs_sb_version_to_features(&mp->m_sb);
+ install_new_geometry(mp, &new_sb);
if (no_modify)
return;
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 02/20] xfsprogs: Move extent count limits to xfs_format.h
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 01/20] xfs_repair: check filesystem geometry before allowing upgrades Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 03/20] xfsprogs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
` (17 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
Maximum values associated with extent counters i.e. Maximum extent length,
Maximum data extents and Maximum xattr extents are dictated by the on-disk
format. Hence move these definitions over to xfs_format.h.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_format.h | 7 +++++++
libxfs/xfs_types.h | 7 -------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index d665c04e..d75e5b16 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -869,6 +869,13 @@ enum xfs_dinode_fmt {
{ XFS_DINODE_FMT_BTREE, "btree" }, \
{ XFS_DINODE_FMT_UUID, "uuid" }
+/*
+ * Max values for extlen, extnum, aextnum.
+ */
+#define MAXEXTLEN ((xfs_extlen_t)0x001fffff) /* 21 bits */
+#define MAXEXTNUM ((xfs_extnum_t)0x7fffffff) /* signed int */
+#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */
+
/*
* Inode minimum and maximum sizes.
*/
diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h
index b6da06b4..794a54cb 100644
--- a/libxfs/xfs_types.h
+++ b/libxfs/xfs_types.h
@@ -56,13 +56,6 @@ typedef void * xfs_failaddr_t;
#define NULLFSINO ((xfs_ino_t)-1)
#define NULLAGINO ((xfs_agino_t)-1)
-/*
- * Max values for extlen, extnum, aextnum.
- */
-#define MAXEXTLEN ((xfs_extlen_t)0x001fffff) /* 21 bits */
-#define MAXEXTNUM ((xfs_extnum_t)0x7fffffff) /* signed int */
-#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */
-
/*
* Minimum and maximum blocksize and sectorsize.
* The blocksize upper limit is pretty much arbitrary.
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 03/20] xfsprogs: Introduce xfs_iext_max_nextents() helper
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 01/20] xfs_repair: check filesystem geometry before allowing upgrades Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 02/20] xfsprogs: Move extent count limits to xfs_format.h Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 04/20] xfsprogs: Use xfs_extnum_t instead of basic data types Chandan Babu R
` (16 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
xfs_iext_max_nextents() returns the maximum number of extents possible for one
of data, cow or attribute fork. This helper will be extended further in a
future commit when maximum extent counts associated with data/attribute forks
are increased.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_bmap.c | 9 ++++-----
libxfs/xfs_inode_buf.c | 8 +++-----
libxfs/xfs_inode_fork.c | 2 +-
libxfs/xfs_inode_fork.h | 8 ++++++++
repair/dinode.c | 4 ++--
5 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 8906265a..d6c672d2 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -67,13 +67,12 @@ xfs_bmap_compute_maxlevels(
* ATTR2 we have to assume the worst case scenario of a minimum size
* available.
*/
- if (whichfork == XFS_DATA_FORK) {
- maxleafents = MAXEXTNUM;
+ maxleafents = xfs_iext_max_nextents(whichfork);
+ if (whichfork == XFS_DATA_FORK)
sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
- } else {
- maxleafents = MAXAEXTNUM;
+ else
sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
- }
+
maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
minleafrecs = mp->m_bmap_dmnr[0];
minnoderecs = mp->m_bmap_dmnr[1];
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index e22e49a4..855f1b3d 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -334,6 +334,7 @@ xfs_dinode_verify_fork(
int whichfork)
{
uint32_t di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+ xfs_extnum_t max_extents;
switch (XFS_DFORK_FORMAT(dip, whichfork)) {
case XFS_DINODE_FMT_LOCAL:
@@ -355,12 +356,9 @@ xfs_dinode_verify_fork(
return __this_address;
break;
case XFS_DINODE_FMT_BTREE:
- if (whichfork == XFS_ATTR_FORK) {
- if (di_nextents > MAXAEXTNUM)
- return __this_address;
- } else if (di_nextents > MAXEXTNUM) {
+ max_extents = xfs_iext_max_nextents(whichfork);
+ if (di_nextents > max_extents)
return __this_address;
- }
break;
default:
return __this_address;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index d6ac13ee..625d8173 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -742,7 +742,7 @@ xfs_iext_count_may_overflow(
if (whichfork == XFS_COW_FORK)
return 0;
- max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM;
+ max_exts = xfs_iext_max_nextents(whichfork);
if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
max_exts = 10;
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index 3d64a3ac..2605f7ff 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -133,6 +133,14 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
return ifp->if_format;
}
+static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
+{
+ if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
+ return MAXEXTNUM;
+
+ return MAXAEXTNUM;
+}
+
struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
xfs_extnum_t nextents);
struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
diff --git a/repair/dinode.c b/repair/dinode.c
index 909fea8e..1c5e71ec 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1796,7 +1796,7 @@ _("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (nextents > MAXEXTNUM) {
+ if (nextents > xfs_iext_max_nextents(XFS_DATA_FORK)) {
do_warn(
_("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
nextents, lino);
@@ -1819,7 +1819,7 @@ _("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (anextents > MAXAEXTNUM) {
+ if (anextents > xfs_iext_max_nextents(XFS_ATTR_FORK)) {
do_warn(
_("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
anextents, lino);
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 04/20] xfsprogs: Use xfs_extnum_t instead of basic data types
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (2 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 03/20] xfsprogs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 05/20] xfsprogs: Introduce xfs_dfork_nextents() helper Chandan Babu R
` (15 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
xfs_extnum_t is the type to use to declare variables which have values
obtained from xfs_dinode->di_[a]nextents. This commit replaces basic
types (e.g. uint32_t) with xfs_extnum_t for such variables.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/bmap.c | 2 +-
db/frag.c | 2 +-
libxfs/xfs_bmap.c | 2 +-
libxfs/xfs_inode_buf.c | 2 +-
libxfs/xfs_inode_fork.c | 2 +-
repair/dinode.c | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/db/bmap.c b/db/bmap.c
index 43300456..8fa623bc 100644
--- a/db/bmap.c
+++ b/db/bmap.c
@@ -47,7 +47,7 @@ bmap(
int n;
int nex;
xfs_fsblock_t nextbno;
- int nextents;
+ xfs_extnum_t nextents;
xfs_bmbt_ptr_t *pp;
xfs_bmdr_block_t *rblock;
typnm_t typ;
diff --git a/db/frag.c b/db/frag.c
index ea81b349..f30415f6 100644
--- a/db/frag.c
+++ b/db/frag.c
@@ -273,7 +273,7 @@ process_fork(
int whichfork)
{
extmap_t *extmap;
- int nex;
+ xfs_extnum_t nex;
nex = XFS_DFORK_NEXTENTS(dip, whichfork);
if (!nex)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index d6c672d2..8da8aaab 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -47,7 +47,7 @@ xfs_bmap_compute_maxlevels(
{
int level; /* btree level */
uint maxblocks; /* max blocks at this level */
- uint maxleafents; /* max leaf entries possible */
+ xfs_extnum_t maxleafents; /* max leaf entries possible */
int maxrootrecs; /* max records in root block */
int minleafrecs; /* min records in leaf block */
int minnoderecs; /* min records in node block */
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 855f1b3d..b15a0166 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -333,7 +333,7 @@ xfs_dinode_verify_fork(
struct xfs_mount *mp,
int whichfork)
{
- uint32_t di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+ xfs_extnum_t di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
xfs_extnum_t max_extents;
switch (XFS_DFORK_FORMAT(dip, whichfork)) {
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 625d8173..4d908a7a 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -103,7 +103,7 @@ xfs_iformat_extents(
struct xfs_mount *mp = ip->i_mount;
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
int state = xfs_bmap_fork_to_state(whichfork);
- int nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ xfs_extnum_t nex = XFS_DFORK_NEXTENTS(dip, whichfork);
int size = nex * sizeof(xfs_bmbt_rec_t);
struct xfs_iext_cursor icur;
struct xfs_bmbt_rec *dp;
diff --git a/repair/dinode.c b/repair/dinode.c
index 1c5e71ec..e0b654ab 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -932,7 +932,7 @@ process_exinode(
xfs_bmbt_rec_t *rp;
xfs_fileoff_t first_key;
xfs_fileoff_t last_key;
- int32_t numrecs;
+ xfs_extnum_t numrecs;
int ret;
lino = XFS_AGINO_TO_INO(mp, agno, ino);
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 05/20] xfsprogs: Introduce xfs_dfork_nextents() helper
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (3 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 04/20] xfsprogs: Use xfs_extnum_t instead of basic data types Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 06/20] xfsprogs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
` (14 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit replaces the macro XFS_DFORK_NEXTENTS() with the helper function
xfs_dfork_nextents(). As of this commit, xfs_dfork_nextents() returns the same
value as XFS_DFORK_NEXTENTS(). A future commit which extends inode's extent
counter fields will add more logic to this helper.
This commit also replaces direct accesses to xfs_dinode->di_[a]nextents
with calls to xfs_dfork_nextents().
No functional changes have been made.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/bmap.c | 6 ++---
db/btdump.c | 4 ++--
db/check.c | 28 +++++++++++++---------
db/frag.c | 6 +++--
db/inode.c | 16 +++++++------
db/metadump.c | 4 ++--
libxfs/xfs_format.h | 4 ----
libxfs/xfs_inode_buf.c | 16 +++++++++----
libxfs/xfs_inode_fork.c | 9 +++----
libxfs/xfs_inode_fork.h | 32 +++++++++++++++++++++++++
repair/attr_repair.c | 2 +-
repair/dinode.c | 53 +++++++++++++++++++++++------------------
repair/prefetch.c | 2 +-
13 files changed, 117 insertions(+), 65 deletions(-)
diff --git a/db/bmap.c b/db/bmap.c
index 8fa623bc..d0c0ebac 100644
--- a/db/bmap.c
+++ b/db/bmap.c
@@ -68,7 +68,7 @@ bmap(
ASSERT(fmt == XFS_DINODE_FMT_LOCAL || fmt == XFS_DINODE_FMT_EXTENTS ||
fmt == XFS_DINODE_FMT_BTREE);
if (fmt == XFS_DINODE_FMT_EXTENTS) {
- nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+ nextents = xfs_dfork_nextents(dip, whichfork);
xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
for (ep = xp; ep < &xp[nextents] && n < nex; ep++) {
if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep))
@@ -158,9 +158,9 @@ bmap_f(
push_cur();
set_cur_inode(iocur_top->ino);
dip = iocur_top->data;
- if (be32_to_cpu(dip->di_nextents))
+ if (xfs_dfork_data_extents(dip))
dfork = 1;
- if (be16_to_cpu(dip->di_anextents))
+ if (xfs_dfork_attr_extents(dip))
afork = 1;
pop_cur();
}
diff --git a/db/btdump.c b/db/btdump.c
index cb9ca082..81642cde 100644
--- a/db/btdump.c
+++ b/db/btdump.c
@@ -166,13 +166,13 @@ dump_inode(
dip = iocur_top->data;
if (attrfork) {
- if (!dip->di_anextents ||
+ if (!xfs_dfork_attr_extents(dip) ||
dip->di_aformat != XFS_DINODE_FMT_BTREE) {
dbprintf(_("attr fork not in btree format\n"));
return 0;
}
} else {
- if (!dip->di_nextents ||
+ if (!xfs_dfork_data_extents(dip) ||
dip->di_format != XFS_DINODE_FMT_BTREE) {
dbprintf(_("data fork not in btree format\n"));
return 0;
diff --git a/db/check.c b/db/check.c
index 654631a5..1fdc1817 100644
--- a/db/check.c
+++ b/db/check.c
@@ -2713,7 +2713,7 @@ process_exinode(
xfs_bmbt_rec_t *rp;
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- *nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ *nex = xfs_dfork_nextents(dip, whichfork);
if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
sizeof(xfs_bmbt_rec_t)) {
if (!sflag || id->ilist)
@@ -2737,12 +2737,14 @@ process_inode(
inodata_t *id = NULL;
xfs_ino_t ino;
xfs_extnum_t nextents = 0;
+ xfs_extnum_t dnextents;
int security;
xfs_rfsblock_t totblocks;
xfs_rfsblock_t totdblocks = 0;
xfs_rfsblock_t totiblocks = 0;
dbm_t type;
xfs_extnum_t anextents = 0;
+ xfs_extnum_t danextents;
xfs_rfsblock_t atotdblocks = 0;
xfs_rfsblock_t atotiblocks = 0;
xfs_qcnt_t bc = 0;
@@ -2871,14 +2873,17 @@ process_inode(
error++;
return;
}
+
+ dnextents = xfs_dfork_data_extents(dip);
+ danextents = xfs_dfork_attr_extents(dip);
+
if (verbose || (id && id->ilist) || CHECK_BLIST(bno))
dbprintf(_("inode %lld mode %#o fmt %s "
"afmt %s "
"nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
id->ino, mode, fmtnames[(int)dip->di_format],
fmtnames[(int)dip->di_aformat],
- be32_to_cpu(dip->di_nextents),
- be16_to_cpu(dip->di_anextents),
+ dnextents, danextents,
be64_to_cpu(dip->di_nblocks), be64_to_cpu(dip->di_size),
diflags & XFS_DIFLAG_REALTIME ? " rt" : "",
diflags & XFS_DIFLAG_PREALLOC ? " pre" : "",
@@ -2893,25 +2898,26 @@ process_inode(
type = DBM_DIR;
if (dip->di_format == XFS_DINODE_FMT_LOCAL)
break;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+
+ blkmap = blkmap_alloc(dnextents);
break;
case S_IFREG:
if (diflags & XFS_DIFLAG_REALTIME)
type = DBM_RTDATA;
else if (id->ino == mp->m_sb.sb_rbmino) {
type = DBM_RTBITMAP;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
addlink_inode(id);
} else if (id->ino == mp->m_sb.sb_rsumino) {
type = DBM_RTSUM;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
addlink_inode(id);
}
else if (id->ino == mp->m_sb.sb_uquotino ||
id->ino == mp->m_sb.sb_gquotino ||
id->ino == mp->m_sb.sb_pquotino) {
type = DBM_QUOTA;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
addlink_inode(id);
}
else
@@ -2993,17 +2999,17 @@ process_inode(
be64_to_cpu(dip->di_nblocks), id->ino, totblocks);
error++;
}
- if (nextents != be32_to_cpu(dip->di_nextents)) {
+ if (nextents != dnextents) {
if (v)
dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
- be32_to_cpu(dip->di_nextents), id->ino, nextents);
+ dnextents, id->ino, nextents);
error++;
}
- if (anextents != be16_to_cpu(dip->di_anextents)) {
+ if (anextents != danextents) {
if (v)
dbprintf(_("bad anextents %d for inode %lld, counted "
"%d\n"),
- be16_to_cpu(dip->di_anextents), id->ino, anextents);
+ danextents, id->ino, anextents);
error++;
}
if (type == DBM_DIR)
diff --git a/db/frag.c b/db/frag.c
index f30415f6..1d013686 100644
--- a/db/frag.c
+++ b/db/frag.c
@@ -262,9 +262,11 @@ process_exinode(
int whichfork)
{
xfs_bmbt_rec_t *rp;
+ xfs_extnum_t nextents;
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS(dip, whichfork), extmapp);
+ nextents = xfs_dfork_nextents(dip, whichfork);
+ process_bmbt_reclist(rp, nextents, extmapp);
}
static void
@@ -275,7 +277,7 @@ process_fork(
extmap_t *extmap;
xfs_extnum_t nex;
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ nex = xfs_dfork_nextents(dip, whichfork);
if (!nex)
return;
extmap = extmap_alloc(nex);
diff --git a/db/inode.c b/db/inode.c
index 083888d8..57cc127b 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -275,7 +275,7 @@ inode_a_bmx_count(
return 0;
ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ?
- be16_to_cpu(dip->di_anextents) : 0;
+ xfs_dfork_attr_extents(dip) : 0;
}
static int
@@ -328,7 +328,8 @@ inode_a_size(
int idx)
{
struct xfs_attr_shortform *asf;
- struct xfs_dinode *dip;
+ struct xfs_dinode *dip;
+ xfs_extnum_t nextents;
ASSERT(startoff == 0);
ASSERT(idx == 0);
@@ -338,8 +339,8 @@ inode_a_size(
asf = (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
return bitize(be16_to_cpu(asf->hdr.totsize));
case XFS_DINODE_FMT_EXTENTS:
- return (int)be16_to_cpu(dip->di_anextents) *
- bitsz(xfs_bmbt_rec_t);
+ nextents = xfs_dfork_attr_extents(dip);
+ return nextents * bitsz(struct xfs_bmbt_rec);
case XFS_DINODE_FMT_BTREE:
return bitize((int)XFS_DFORK_ASIZE(dip, mp));
default:
@@ -500,7 +501,7 @@ inode_u_bmx_count(
dip = obj;
ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
return dip->di_format == XFS_DINODE_FMT_EXTENTS ?
- be32_to_cpu(dip->di_nextents) : 0;
+ xfs_dfork_data_extents(dip) : 0;
}
static int
@@ -586,6 +587,7 @@ inode_u_size(
int idx)
{
struct xfs_dinode *dip;
+ xfs_extnum_t nextents;
ASSERT(startoff == 0);
ASSERT(idx == 0);
@@ -596,8 +598,8 @@ inode_u_size(
case XFS_DINODE_FMT_LOCAL:
return bitize((int)be64_to_cpu(dip->di_size));
case XFS_DINODE_FMT_EXTENTS:
- return (int)be32_to_cpu(dip->di_nextents) *
- bitsz(xfs_bmbt_rec_t);
+ nextents = xfs_dfork_data_extents(dip);
+ return nextents * bitsz(struct xfs_bmbt_rec);
case XFS_DINODE_FMT_BTREE:
return bitize((int)XFS_DFORK_DSIZE(dip, mp));
case XFS_DINODE_FMT_UUID:
diff --git a/db/metadump.c b/db/metadump.c
index 2993f06e..90b2979d 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2282,7 +2282,7 @@ process_exinode(
whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ nex = xfs_dfork_nextents(dip, whichfork);
used = nex * sizeof(xfs_bmbt_rec_t);
if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
if (show_warnings)
@@ -2335,7 +2335,7 @@ static int
process_dev_inode(
struct xfs_dinode *dip)
{
- if (XFS_DFORK_NEXTENTS(dip, XFS_DATA_FORK)) {
+ if (xfs_dfork_data_extents(dip)) {
if (show_warnings)
print_warning("inode %llu has unexpected extents",
(unsigned long long)cur_ino);
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index d75e5b16..e5654b57 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -925,10 +925,6 @@ enum xfs_dinode_fmt {
((w) == XFS_DATA_FORK ? \
(dip)->di_format : \
(dip)->di_aformat)
-#define XFS_DFORK_NEXTENTS(dip,w) \
- ((w) == XFS_DATA_FORK ? \
- be32_to_cpu((dip)->di_nextents) : \
- be16_to_cpu((dip)->di_anextents))
/*
* For block and character special files the 32bit dev_t is stored at the
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index b15a0166..29204e4a 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -333,9 +333,11 @@ xfs_dinode_verify_fork(
struct xfs_mount *mp,
int whichfork)
{
- xfs_extnum_t di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+ xfs_extnum_t di_nextents;
xfs_extnum_t max_extents;
+ di_nextents = xfs_dfork_nextents(dip, whichfork);
+
switch (XFS_DFORK_FORMAT(dip, whichfork)) {
case XFS_DINODE_FMT_LOCAL:
/*
@@ -402,6 +404,8 @@ xfs_dinode_verify(
uint16_t flags;
uint64_t flags2;
uint64_t di_size;
+ xfs_rfsblock_t nblocks;
+ xfs_extnum_t nextents;
if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
return __this_address;
@@ -432,10 +436,12 @@ xfs_dinode_verify(
if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
return __this_address;
+ nextents = xfs_dfork_data_extents(dip);
+ nextents += xfs_dfork_attr_extents(dip);
+ nblocks = be64_to_cpu(dip->di_nblocks);
+
/* Fork checks carried over from xfs_iformat_fork */
- if (mode &&
- be32_to_cpu(dip->di_nextents) + be16_to_cpu(dip->di_anextents) >
- be64_to_cpu(dip->di_nblocks))
+ if (mode && nextents > nblocks)
return __this_address;
if (mode && XFS_DFORK_BOFF(dip) > mp->m_sb.sb_inodesize)
@@ -492,7 +498,7 @@ xfs_dinode_verify(
default:
return __this_address;
}
- if (dip->di_anextents)
+ if (xfs_dfork_attr_extents(dip))
return __this_address;
}
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 4d908a7a..14b29722 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -103,7 +103,7 @@ xfs_iformat_extents(
struct xfs_mount *mp = ip->i_mount;
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
int state = xfs_bmap_fork_to_state(whichfork);
- xfs_extnum_t nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ xfs_extnum_t nex = xfs_dfork_nextents(dip, whichfork);
int size = nex * sizeof(xfs_bmbt_rec_t);
struct xfs_iext_cursor icur;
struct xfs_bmbt_rec *dp;
@@ -228,7 +228,7 @@ xfs_iformat_data_fork(
* depend on it.
*/
ip->i_df.if_format = dip->di_format;
- ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents);
+ ip->i_df.if_nextents = xfs_dfork_data_extents(dip);
switch (inode->i_mode & S_IFMT) {
case S_IFIFO:
@@ -293,14 +293,15 @@ xfs_iformat_attr_fork(
struct xfs_inode *ip,
struct xfs_dinode *dip)
{
+ xfs_extnum_t naextents;
int error = 0;
/*
* Initialize the extent count early, as the per-format routines may
* depend on it.
*/
- ip->i_afp = xfs_ifork_alloc(dip->di_aformat,
- be16_to_cpu(dip->di_anextents));
+ naextents = xfs_dfork_attr_extents(dip);
+ ip->i_afp = xfs_ifork_alloc(dip->di_aformat, naextents);
switch (ip->i_afp->if_format) {
case XFS_DINODE_FMT_LOCAL:
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index 2605f7ff..7ed2ecb5 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -141,6 +141,38 @@ static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
return MAXAEXTNUM;
}
+static inline xfs_extnum_t
+xfs_dfork_data_extents(
+ struct xfs_dinode *dip)
+{
+ return be32_to_cpu(dip->di_nextents);
+}
+
+static inline xfs_extnum_t
+xfs_dfork_attr_extents(
+ struct xfs_dinode *dip)
+{
+ return be16_to_cpu(dip->di_anextents);
+}
+
+static inline xfs_extnum_t
+xfs_dfork_nextents(
+ struct xfs_dinode *dip,
+ int whichfork)
+{
+ switch (whichfork) {
+ case XFS_DATA_FORK:
+ return xfs_dfork_data_extents(dip);
+ case XFS_ATTR_FORK:
+ return xfs_dfork_attr_extents(dip);
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ return 0;
+}
+
struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
xfs_extnum_t nextents);
struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index 50c46619..954a2f1e 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -1083,7 +1083,7 @@ process_longform_attr(
bno = blkmap_get(blkmap, 0);
if (bno == NULLFSBLOCK) {
if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS &&
- be16_to_cpu(dip->di_anextents) == 0)
+ xfs_dfork_attr_extents(dip) == 0)
return(0); /* the kernel can handle this state */
do_warn(
_("block 0 of inode %" PRIu64 " attribute fork is missing\n"),
diff --git a/repair/dinode.c b/repair/dinode.c
index e0b654ab..386c39f6 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -68,7 +68,7 @@ _("clearing inode %" PRIu64 " attributes\n"), ino_num);
fprintf(stderr,
_("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
- if (be16_to_cpu(dino->di_anextents) != 0) {
+ if (xfs_dfork_attr_extents(dino) != 0) {
if (no_modify)
return(1);
dino->di_anextents = cpu_to_be16(0);
@@ -938,7 +938,7 @@ process_exinode(
lino = XFS_AGINO_TO_INO(mp, agno, ino);
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
*tot = 0;
- numrecs = XFS_DFORK_NEXTENTS(dip, whichfork);
+ numrecs = xfs_dfork_nextents(dip, whichfork);
/*
* We've already decided on the maximum number of extents on the inode,
@@ -1015,7 +1015,7 @@ process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, struct xfs_dinode *dino
xfs_fileoff_t expected_offset;
xfs_bmbt_rec_t *rp;
xfs_bmbt_irec_t irec;
- int numrecs;
+ xfs_extnum_t numrecs;
int i;
int max_blocks;
@@ -1037,7 +1037,7 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
}
rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino);
- numrecs = be32_to_cpu(dino->di_nextents);
+ numrecs = xfs_dfork_data_extents(dino);
/*
* the max # of extents in a symlink inode is equal to the
@@ -1543,6 +1543,8 @@ process_check_sb_inodes(
int *type,
int *dirty)
{
+ xfs_extnum_t nextents;
+
if (lino == mp->m_sb.sb_rootino) {
if (*type != XR_INO_DIR) {
do_warn(_("root inode %" PRIu64 " has bad type 0x%x\n"),
@@ -1597,10 +1599,12 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
do_warn(_("would reset to regular file\n"));
}
}
- if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
+
+ nextents = xfs_dfork_data_extents(dinoc);
+ if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%u) for realtime summary inode %" PRIu64 "\n"),
- be32_to_cpu(dinoc->di_nextents), lino);
+_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
+ nextents, lino);
return 1;
}
return 0;
@@ -1618,10 +1622,12 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
do_warn(_("would reset to regular file\n"));
}
}
- if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
+
+ nextents = xfs_dfork_data_extents(dinoc);
+ if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%u) for realtime bitmap inode %" PRIu64 "\n"),
- be32_to_cpu(dinoc->di_nextents), lino);
+_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
+ nextents, lino);
return 1;
}
return 0;
@@ -1780,6 +1786,8 @@ process_inode_blocks_and_extents(
xfs_ino_t lino,
int *dirty)
{
+ xfs_extnum_t dnextents;
+
if (nblocks != be64_to_cpu(dino->di_nblocks)) {
if (!no_modify) {
do_warn(
@@ -1802,20 +1810,19 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
nextents, lino);
return 1;
}
- if (nextents != be32_to_cpu(dino->di_nextents)) {
+
+ dnextents = xfs_dfork_data_extents(dino);
+ if (nextents != dnextents) {
if (!no_modify) {
do_warn(
_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
- lino,
- be32_to_cpu(dino->di_nextents),
- nextents);
+ lino, dnextents, nextents);
dino->di_nextents = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
_("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
- be32_to_cpu(dino->di_nextents),
- lino, nextents);
+ dnextents, lino, nextents);
}
}
@@ -1825,19 +1832,19 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
anextents, lino);
return 1;
}
- if (anextents != be16_to_cpu(dino->di_anextents)) {
+
+ dnextents = xfs_dfork_attr_extents(dino);
+ if (anextents != dnextents) {
if (!no_modify) {
do_warn(
_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
- lino,
- be16_to_cpu(dino->di_anextents), anextents);
+ lino, dnextents, anextents);
dino->di_anextents = cpu_to_be16(anextents);
*dirty = 1;
} else {
do_warn(
_("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
- be16_to_cpu(dino->di_anextents),
- lino, anextents);
+ dnextents, lino, anextents);
}
}
@@ -1879,7 +1886,7 @@ process_inode_data_fork(
* uses negative values in memory. hence if we see negative numbers
* here, trash it!
*/
- nex = be32_to_cpu(dino->di_nextents);
+ nex = xfs_dfork_data_extents(dino);
if (nex < 0)
*nextents = 1;
else
@@ -2000,7 +2007,7 @@ process_inode_attr_fork(
return 0;
}
- *anextents = be16_to_cpu(dino->di_anextents);
+ *anextents = xfs_dfork_attr_extents(dino);
if (*anextents > be64_to_cpu(dino->di_nblocks))
*anextents = 1;
diff --git a/repair/prefetch.c b/repair/prefetch.c
index a1c69612..1a7a4eab 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -393,7 +393,7 @@ pf_read_exinode(
struct xfs_dinode *dino)
{
pf_read_bmbt_reclist(args, (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino),
- be32_to_cpu(dino->di_nextents));
+ xfs_dfork_data_extents(dino));
}
static void
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 06/20] xfsprogs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (4 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 05/20] xfsprogs: Introduce xfs_dfork_nextents() helper Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 07/20] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
` (13 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
A future commit will increase the width of xfs_extnum_t in order to facilitate
larger per-inode extent counters. Hence this patch now uses basic types to
define xfs_log_dinode->[di_nextents|dianextents].
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_log_format.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index b322db52..fd66e702 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -396,8 +396,8 @@ struct xfs_log_dinode {
xfs_fsize_t di_size; /* number of bytes in file */
xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
- xfs_extnum_t di_nextents; /* number of extents in data fork */
- xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
+ uint32_t di_nextents; /* number of extents in data fork */
+ uint16_t di_anextents; /* number of extents in attribute fork*/
uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
int8_t di_aformat; /* format of attr fork's data */
uint32_t di_dmevmask; /* DMIG event mask */
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 07/20] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (5 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 06/20] xfsprogs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 08/20] xfsprogs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
` (12 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
A future commit will introduce a 64-bit on-disk data extent counter and a
32-bit on-disk attr extent counter. This commit promotes xfs_extnum_t and
xfs_aextnum_t to 64 and 32-bits in order to correctly handle in-core versions
of these quantities.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_bmap.c | 6 +++---
libxfs/xfs_inode_fork.c | 2 +-
libxfs/xfs_inode_fork.h | 2 +-
libxfs/xfs_types.h | 4 ++--
repair/dinode.c | 20 ++++++++++----------
repair/dinode.h | 4 ++--
repair/scan.c | 6 +++---
7 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 8da8aaab..42694956 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -45,9 +45,9 @@ xfs_bmap_compute_maxlevels(
xfs_mount_t *mp, /* file system mount structure */
int whichfork) /* data or attr fork */
{
+ xfs_extnum_t maxleafents; /* max leaf entries possible */
int level; /* btree level */
uint maxblocks; /* max blocks at this level */
- xfs_extnum_t maxleafents; /* max leaf entries possible */
int maxrootrecs; /* max records in root block */
int minleafrecs; /* min records in leaf block */
int minnoderecs; /* min records in node block */
@@ -76,7 +76,7 @@ xfs_bmap_compute_maxlevels(
maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
minleafrecs = mp->m_bmap_dmnr[0];
minnoderecs = mp->m_bmap_dmnr[1];
- maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
+ maxblocks = howmany_64(maxleafents, minleafrecs);
for (level = 1; maxblocks > 1; level++) {
if (maxblocks <= maxrootrecs)
maxblocks = 1;
@@ -460,7 +460,7 @@ error0:
if (bp_release)
xfs_trans_brelse(NULL, bp);
error_norelse:
- xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
+ xfs_warn(mp, "%s: BAD after btree leaves for %llu extents",
__func__, i);
xfs_err(mp, "%s: CORRUPTED BTREE OR SOMETHING", __func__);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 14b29722..f7fa0af5 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -115,7 +115,7 @@ xfs_iformat_extents(
* we just bail out rather than crash in kmem_alloc() or memcpy() below.
*/
if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
- xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
+ xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %llu).",
(unsigned long long) ip->i_ino, nex);
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_extents(1)", dip, sizeof(*dip),
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index 7ed2ecb5..4a8b77d4 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -21,9 +21,9 @@ struct xfs_ifork {
void *if_root; /* extent tree root */
char *if_data; /* inline file data */
} if_u1;
+ xfs_extnum_t if_nextents; /* # of extents in this fork */
short if_broot_bytes; /* bytes allocated for root */
int8_t if_format; /* format of this fork */
- xfs_extnum_t if_nextents; /* # of extents in this fork */
};
/*
diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h
index 794a54cb..373f64a4 100644
--- a/libxfs/xfs_types.h
+++ b/libxfs/xfs_types.h
@@ -12,8 +12,8 @@ typedef uint32_t xfs_agblock_t; /* blockno in alloc. group */
typedef uint32_t xfs_agino_t; /* inode # within allocation grp */
typedef uint32_t xfs_extlen_t; /* extent length in blocks */
typedef uint32_t xfs_agnumber_t; /* allocation group number */
-typedef int32_t xfs_extnum_t; /* # of extents in a file */
-typedef int16_t xfs_aextnum_t; /* # extents in an attribute fork */
+typedef uint64_t xfs_extnum_t; /* # of extents in a file */
+typedef uint32_t xfs_aextnum_t; /* # extents in an attribute fork */
typedef int64_t xfs_fsize_t; /* bytes in a file */
typedef uint64_t xfs_ufsize_t; /* unsigned bytes in a file */
diff --git a/repair/dinode.c b/repair/dinode.c
index 386c39f6..4cfc6352 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -342,7 +342,7 @@ static int
process_bmbt_reclist_int(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -645,7 +645,7 @@ int
process_bmbt_reclist(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -666,7 +666,7 @@ int
scan_bmbt_reclist(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -1045,7 +1045,7 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
*/
if (numrecs > max_symlink_blocks) {
do_warn(
-_("bad number of extents (%d) in symlink %" PRIu64 " data fork\n"),
+_("bad number of extents (%lu) in symlink %" PRIu64 " data fork\n"),
numrecs, lino);
return(1);
}
@@ -1603,7 +1603,7 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
nextents = xfs_dfork_data_extents(dinoc);
if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
+_("bad # of extents (%lu) for realtime summary inode %" PRIu64 "\n"),
nextents, lino);
return 1;
}
@@ -1626,7 +1626,7 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
nextents = xfs_dfork_data_extents(dinoc);
if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
+_("bad # of extents (%lu) for realtime bitmap inode %" PRIu64 "\n"),
nextents, lino);
return 1;
}
@@ -1815,13 +1815,13 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
if (nextents != dnextents) {
if (!no_modify) {
do_warn(
-_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
+_("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, nextents);
dino->di_nextents = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
-_("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
+_("bad nextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
dnextents, lino, nextents);
}
}
@@ -1837,13 +1837,13 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
if (anextents != dnextents) {
if (!no_modify) {
do_warn(
-_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
+_("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, anextents);
dino->di_anextents = cpu_to_be16(anextents);
*dirty = 1;
} else {
do_warn(
-_("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
+_("bad anextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
dnextents, lino, anextents);
}
}
diff --git a/repair/dinode.h b/repair/dinode.h
index 4ed8b46f..333d96d2 100644
--- a/repair/dinode.h
+++ b/repair/dinode.h
@@ -20,7 +20,7 @@ convert_extent(
int
process_bmbt_reclist(xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -33,7 +33,7 @@ int
scan_bmbt_reclist(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
diff --git a/repair/scan.c b/repair/scan.c
index 5a4b8dbd..c8977a02 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -220,7 +220,7 @@ scan_bmapbt(
xfs_fileoff_t first_key;
xfs_fileoff_t last_key;
char *forkname = get_forkname(whichfork);
- int numrecs;
+ xfs_extnum_t numrecs;
xfs_agnumber_t agno;
xfs_agblock_t agbno;
int state;
@@ -425,7 +425,7 @@ _("couldn't add inode %"PRIu64" bmbt block %"PRIu64" reverse-mapping data."),
if (numrecs > mp->m_bmap_dmxr[0] || (isroot == 0 && numrecs <
mp->m_bmap_dmnr[0])) {
do_warn(
-_("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"),
+_("inode %" PRIu64 " bad # of bmap records (%lu, min - %u, max - %u)\n"),
ino, numrecs, mp->m_bmap_dmnr[0],
mp->m_bmap_dmxr[0]);
return(1);
@@ -476,7 +476,7 @@ _("out-of-order bmap key (file offset) in inode %" PRIu64 ", %s fork, fsbno %" P
if (numrecs > mp->m_bmap_dmxr[1] || (isroot == 0 && numrecs <
mp->m_bmap_dmnr[1])) {
do_warn(
-_("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"),
+_("inode %" PRIu64 " bad # of bmap records (%lu, min - %u, max - %u)\n"),
ino, numrecs, mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1]);
return(1);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 08/20] xfsprogs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (6 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 07/20] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 09/20] xfsprogs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
` (11 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
XFS_SB_FEAT_INCOMPAT_NREXT64 incompat feature bit will be set on filesystems
which support large per-inode extent counters. This commit defines the new
incompat feature bit and the corresponding per-fs feature bit (along with
inline functions to work on it).
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/sb.c | 2 ++
include/xfs_mount.h | 2 ++
libxfs/xfs_format.h | 1 +
libxfs/xfs_sb.c | 3 +++
4 files changed, 8 insertions(+)
diff --git a/db/sb.c b/db/sb.c
index 7510e00f..7f83052c 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -704,6 +704,8 @@ version_string(
strcat(s, ",BIGTIME");
if (xfs_has_needsrepair(mp))
strcat(s, ",NEEDSREPAIR");
+ if (xfs_has_nrext64(mp))
+ strcat(s, ",NREXT64");
return s;
}
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index 8139831b..b253d1c8 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -154,6 +154,7 @@ typedef struct xfs_mount {
#define XFS_FEAT_INOBTCNT (1ULL << 23) /* inobt block counts */
#define XFS_FEAT_BIGTIME (1ULL << 24) /* large timestamps */
#define XFS_FEAT_NEEDSREPAIR (1ULL << 25) /* needs xfs_repair */
+#define XFS_FEAT_NREXT64 (1ULL << 26) /* 64-bit inode extent counters */
#define __XFS_HAS_FEAT(name, NAME) \
static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
@@ -197,6 +198,7 @@ __XFS_HAS_FEAT(realtime, REALTIME)
__XFS_HAS_FEAT(inobtcounts, INOBTCNT)
__XFS_HAS_FEAT(bigtime, BIGTIME)
__XFS_HAS_FEAT(needsrepair, NEEDSREPAIR)
+__XFS_HAS_FEAT(nrext64, NREXT64)
/* Kernel mount features that we don't support */
#define __XFS_UNSUPP_FEAT(name) \
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index e5654b57..7972cbc2 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -372,6 +372,7 @@ xfs_sb_has_ro_compat_feature(
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
+#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* 64-bit data fork extent counter */
#define XFS_SB_FEAT_INCOMPAT_ALL \
(XFS_SB_FEAT_INCOMPAT_FTYPE| \
XFS_SB_FEAT_INCOMPAT_SPINODES| \
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 986f9466..7ab13e07 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -122,6 +122,9 @@ xfs_sb_version_to_features(
features |= XFS_FEAT_BIGTIME;
if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
features |= XFS_FEAT_NEEDSREPAIR;
+ if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NREXT64)
+ features |= XFS_FEAT_NREXT64;
+
return features;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 09/20] xfsprogs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (7 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 08/20] xfsprogs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 10/20] xfsprogs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
` (10 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
XFS_FSOP_GEOM_FLAGS_NREXT64 indicates that the current filesystem instance
supports 64-bit per-inode extent counters.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_fs.h | 1 +
libxfs/xfs_sb.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index c43877c8..42bc3950 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -251,6 +251,7 @@ typedef struct xfs_fsop_resblks {
#define XFS_FSOP_GEOM_FLAGS_REFLINK (1 << 20) /* files can share blocks */
#define XFS_FSOP_GEOM_FLAGS_BIGTIME (1 << 21) /* 64-bit nsec timestamps */
#define XFS_FSOP_GEOM_FLAGS_INOBTCNT (1 << 22) /* inobt btree counter */
+#define XFS_FSOP_GEOM_FLAGS_NREXT64 (1 << 23) /* 64-bit extent counter */
/*
* Minimum and maximum sizes need for growth checks.
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 7ab13e07..6045266e 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -1136,6 +1136,9 @@ xfs_fs_geometry(
} else {
geo->logsectsize = BBSIZE;
}
+ if (xfs_has_nrext64(mp))
+ geo->flags |= XFS_FSOP_GEOM_FLAGS_NREXT64;
+
geo->rtsectsize = sbp->sb_blocksize;
geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp);
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 10/20] xfsprogs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (8 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 09/20] xfsprogs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 11/20] xfsprogs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
` (9 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit adds the new per-inode flag XFS_DIFLAG2_NREXT64 to indicate that
an inode supports 64-bit extent counters. This flag is also enabled by default
on newly created inodes when the corresponding filesystem has large extent
counter feature bit (i.e. XFS_FEAT_NREXT64) set.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/inode.c | 3 +++
include/xfs_inode.h | 5 +++++
libxfs/xfs_format.h | 10 +++++++++-
libxfs/xfs_ialloc.c | 2 ++
4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/db/inode.c b/db/inode.c
index 57cc127b..a9e6cc70 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -178,6 +178,9 @@ const field_t inode_v3_flds[] = {
{ "bigtime", FLDT_UINT1,
OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_BIGTIME_BIT - 1), C1,
0, TYP_NONE },
+ { "nrext64", FLDT_UINT1,
+ OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_NREXT64_BIT - 1), C1,
+ 0, TYP_NONE },
{ NULL }
};
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 08a62d83..79a5c526 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -164,6 +164,11 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
}
+static inline bool xfs_inode_has_nrext64(struct xfs_inode *ip)
+{
+ return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
+}
+
typedef struct cred {
uid_t cr_uid;
gid_t cr_gid;
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 7972cbc2..9934c320 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -992,15 +992,17 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
#define XFS_DIFLAG2_REFLINK_BIT 1 /* file's blocks may be shared */
#define XFS_DIFLAG2_COWEXTSIZE_BIT 2 /* copy on write extent size hint */
#define XFS_DIFLAG2_BIGTIME_BIT 3 /* big timestamps */
+#define XFS_DIFLAG2_NREXT64_BIT 4 /* 64-bit extent counter enabled */
#define XFS_DIFLAG2_DAX (1 << XFS_DIFLAG2_DAX_BIT)
#define XFS_DIFLAG2_REFLINK (1 << XFS_DIFLAG2_REFLINK_BIT)
#define XFS_DIFLAG2_COWEXTSIZE (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
+#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT)
#define XFS_DIFLAG2_ANY \
(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
- XFS_DIFLAG2_BIGTIME)
+ XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_NREXT64)
static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
{
@@ -1008,6 +1010,12 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_BIGTIME));
}
+static inline bool xfs_dinode_has_nrext64(const struct xfs_dinode *dip)
+{
+ return dip->di_version >= 3 &&
+ (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64));
+}
+
/*
* Inode number format:
* low inopblog bits - offset in block
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 82d6a3e8..1661ebe4 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -2767,6 +2767,8 @@ xfs_ialloc_setup_geometry(
igeo->new_diflags2 = 0;
if (xfs_has_bigtime(mp))
igeo->new_diflags2 |= XFS_DIFLAG2_BIGTIME;
+ if (xfs_has_nrext64(mp))
+ igeo->new_diflags2 |= XFS_DIFLAG2_NREXT64;
/* Compute inode btree geometry. */
igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 11/20] xfsprogs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (9 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 10/20] xfsprogs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 12/20] xfsprogs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
` (8 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_bmap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 42694956..51e9b6ce 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -46,8 +46,8 @@ xfs_bmap_compute_maxlevels(
int whichfork) /* data or attr fork */
{
xfs_extnum_t maxleafents; /* max leaf entries possible */
+ xfs_rfsblock_t maxblocks; /* max blocks at this level */
int level; /* btree level */
- uint maxblocks; /* max blocks at this level */
int maxrootrecs; /* max records in root block */
int minleafrecs; /* min records in leaf block */
int minnoderecs; /* min records in node block */
@@ -81,7 +81,7 @@ xfs_bmap_compute_maxlevels(
if (maxblocks <= maxrootrecs)
maxblocks = 1;
else
- maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
+ maxblocks = howmany_64(maxblocks, minnoderecs);
}
mp->m_bm_maxlevels[whichfork] = level;
ASSERT(mp->m_bm_maxlevels[whichfork] <= xfs_bmbt_maxlevels_ondisk());
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 12/20] xfsprogs: Introduce macros to represent new maximum extent counts for data/attr forks
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (10 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 11/20] xfsprogs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 13/20] xfsprogs: Introduce per-inode 64-bit extent counters Chandan Babu R
` (7 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit defines new macros to represent maximum extent counts allowed by
filesystems which have support for large per-inode extent counters.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_bmap.c | 9 ++++-----
libxfs/xfs_bmap_btree.c | 2 +-
libxfs/xfs_format.h | 20 ++++++++++++++++----
libxfs/xfs_inode_buf.c | 3 ++-
libxfs/xfs_inode_fork.c | 2 +-
libxfs/xfs_inode_fork.h | 19 +++++++++++++++----
repair/dinode.c | 6 ++++--
7 files changed, 43 insertions(+), 18 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 51e9b6ce..8dd084b9 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -54,10 +54,8 @@ xfs_bmap_compute_maxlevels(
int sz; /* root block size */
/*
- * The maximum number of extents in a file, hence the maximum number of
- * leaf entries, is controlled by the size of the on-disk extent count,
- * either a signed 32-bit number for the data fork, or a signed 16-bit
- * number for the attr fork.
+ * The maximum number of extents in a fork, hence the maximum number of
+ * leaf entries, is controlled by the size of the on-disk extent count.
*
* Note that we can no longer assume that if we are in ATTR1 that the
* fork offset of all the inodes will be
@@ -67,7 +65,8 @@ xfs_bmap_compute_maxlevels(
* ATTR2 we have to assume the worst case scenario of a minimum size
* available.
*/
- maxleafents = xfs_iext_max_nextents(whichfork);
+ maxleafents = xfs_iext_max_nextents(xfs_has_nrext64(mp),
+ whichfork);
if (whichfork == XFS_DATA_FORK)
sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
else
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index ba239d6e..02b36620 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -609,7 +609,7 @@ xfs_bmbt_maxlevels_ondisk(void)
minrecs[1] = xfs_bmbt_block_maxrecs(blocklen, false) / 2;
/* One extra level for the inode root. */
- return xfs_btree_compute_maxlevels(minrecs, MAXEXTNUM) + 1;
+ return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_EXTCNT_DATA_FORK) + 1;
}
/*
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 9934c320..d3dfd45c 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -872,10 +872,22 @@ enum xfs_dinode_fmt {
/*
* Max values for extlen, extnum, aextnum.
- */
-#define MAXEXTLEN ((xfs_extlen_t)0x001fffff) /* 21 bits */
-#define MAXEXTNUM ((xfs_extnum_t)0x7fffffff) /* signed int */
-#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */
+ *
+ * The newly introduced data fork extent counter is a 64-bit field. However, the
+ * maximum number of extents in a file is limited to 2^54 extents (assuming one
+ * blocks per extent) by the 54-bit wide startoff field of an extent record.
+ *
+ * A further limitation applies as shown below,
+ * 2^63 (max file size) / 64k (max block size) = 2^47
+ *
+ * Rounding up 47 to the nearest multiple of bits-per-byte results in 48. Hence
+ * 2^48 was chosen as the maximum data fork extent count.
+ */
+#define MAXEXTLEN ((xfs_extlen_t)((1ULL << 21) - 1)) /* 21 bits */
+#define XFS_MAX_EXTCNT_DATA_FORK ((xfs_extnum_t)((1ULL << 48) - 1)) /* Unsigned 48-bits */
+#define XFS_MAX_EXTCNT_ATTR_FORK ((xfs_extnum_t)((1ULL << 32) - 1)) /* Unsigned 32-bits */
+#define XFS_MAX_EXTCNT_DATA_FORK_OLD ((xfs_extnum_t)((1ULL << 31) - 1)) /* Signed 32-bits */
+#define XFS_MAX_EXTCNT_ATTR_FORK_OLD ((xfs_extnum_t)((1ULL << 15) - 1)) /* Signed 16-bits */
/*
* Inode minimum and maximum sizes.
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 29204e4a..b3f6be93 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -358,7 +358,8 @@ xfs_dinode_verify_fork(
return __this_address;
break;
case XFS_DINODE_FMT_BTREE:
- max_extents = xfs_iext_max_nextents(whichfork);
+ max_extents = xfs_iext_max_nextents(xfs_dinode_has_nrext64(dip),
+ whichfork);
if (di_nextents > max_extents)
return __this_address;
break;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index f7fa0af5..9e80396a 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -743,7 +743,7 @@ xfs_iext_count_may_overflow(
if (whichfork == XFS_COW_FORK)
return 0;
- max_exts = xfs_iext_max_nextents(whichfork);
+ max_exts = xfs_iext_max_nextents(xfs_inode_has_nrext64(ip), whichfork);
if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
max_exts = 10;
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index 4a8b77d4..e5680343 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -133,12 +133,23 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
return ifp->if_format;
}
-static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
+static inline xfs_extnum_t xfs_iext_max_nextents(bool has_nrext64,
+ int whichfork)
{
- if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
- return MAXEXTNUM;
+ switch (whichfork) {
+ case XFS_DATA_FORK:
+ case XFS_COW_FORK:
+ return has_nrext64 ? XFS_MAX_EXTCNT_DATA_FORK
+ : XFS_MAX_EXTCNT_DATA_FORK_OLD;
+
+ case XFS_ATTR_FORK:
+ return has_nrext64 ? XFS_MAX_EXTCNT_ATTR_FORK
+ : XFS_MAX_EXTCNT_ATTR_FORK_OLD;
- return MAXAEXTNUM;
+ default:
+ ASSERT(0);
+ return 0;
+ }
}
static inline xfs_extnum_t
diff --git a/repair/dinode.c b/repair/dinode.c
index 4cfc6352..54efe571 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1804,7 +1804,8 @@ _("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (nextents > xfs_iext_max_nextents(XFS_DATA_FORK)) {
+ if (nextents > xfs_iext_max_nextents(xfs_dinode_has_nrext64(dino),
+ XFS_DATA_FORK)) {
do_warn(
_("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
nextents, lino);
@@ -1826,7 +1827,8 @@ _("bad nextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (anextents > xfs_iext_max_nextents(XFS_ATTR_FORK)) {
+ if (anextents > xfs_iext_max_nextents(xfs_dinode_has_nrext64(dino),
+ XFS_ATTR_FORK)) {
do_warn(
_("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
anextents, lino);
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 13/20] xfsprogs: Introduce per-inode 64-bit extent counters
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (11 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 12/20] xfsprogs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 14/20] xfsprogs: Conditionally upgrade existing inodes to use " Chandan Babu R
` (6 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david, Dave Chinner
This commit introduces new fields in the on-disk inode format to support
64-bit data fork extent counters and 32-bit attribute fork extent
counters. The new fields will be used only when an inode has
XFS_DIFLAG2_NREXT64 flag set. Otherwise we continue to use the regular 32-bit
data fork extent counters and 16-bit attribute fork extent counters.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Suggested-by: Dave Chinner <dchinner@redhat.com>
---
db/field.c | 4 -
db/field.h | 2 -
db/inode.c | 205 ++++++++++++++++++++++++++++++++++++++-
libxfs/xfs_format.h | 22 ++++-
libxfs/xfs_inode_buf.c | 27 +++++-
libxfs/xfs_inode_fork.h | 6 ++
libxfs/xfs_log_format.h | 22 ++++-
logprint/log_misc.c | 20 +++-
logprint/log_print_all.c | 18 +++-
repair/dinode.c | 18 +++-
10 files changed, 312 insertions(+), 32 deletions(-)
diff --git a/db/field.c b/db/field.c
index 0a089b56..e2da7a6f 100644
--- a/db/field.c
+++ b/db/field.c
@@ -25,8 +25,6 @@
#include "symlink.h"
const ftattr_t ftattrtab[] = {
- { FLDT_AEXTNUM, "aextnum", fp_num, "%d", SI(bitsz(xfs_aextnum_t)),
- FTARG_SIGNED, NULL, NULL },
{ FLDT_AGBLOCK, "agblock", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
FTARG_DONULL, fa_agblock, NULL },
{ FLDT_AGBLOCKNZ, "agblocknz", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
@@ -300,8 +298,6 @@ const ftattr_t ftattrtab[] = {
FTARG_DONULL, fa_drtbno, NULL },
{ FLDT_EXTLEN, "extlen", fp_num, "%u", SI(bitsz(xfs_extlen_t)), 0, NULL,
NULL },
- { FLDT_EXTNUM, "extnum", fp_num, "%d", SI(bitsz(xfs_extnum_t)),
- FTARG_SIGNED, NULL, NULL },
{ FLDT_FSIZE, "fsize", fp_num, "%lld", SI(bitsz(xfs_fsize_t)),
FTARG_SIGNED, NULL, NULL },
{ FLDT_INO, "ino", fp_num, "%llu", SI(bitsz(xfs_ino_t)), FTARG_DONULL,
diff --git a/db/field.h b/db/field.h
index 387c189e..614fd0ab 100644
--- a/db/field.h
+++ b/db/field.h
@@ -5,7 +5,6 @@
*/
typedef enum fldt {
- FLDT_AEXTNUM,
FLDT_AGBLOCK,
FLDT_AGBLOCKNZ,
FLDT_AGF,
@@ -143,7 +142,6 @@ typedef enum fldt {
FLDT_DRFSBNO,
FLDT_DRTBNO,
FLDT_EXTLEN,
- FLDT_EXTNUM,
FLDT_FSIZE,
FLDT_INO,
FLDT_INOBT,
diff --git a/db/inode.c b/db/inode.c
index a9e6cc70..45ac1a89 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -27,6 +27,16 @@ static int inode_core_nlinkv2_count(void *obj, int startoff);
static int inode_core_onlink_count(void *obj, int startoff);
static int inode_core_projid_count(void *obj, int startoff);
static int inode_core_nlinkv1_count(void *obj, int startoff);
+static int inode_core_v3_pad_count(void *obj, int startoff);
+static int inode_core_v2_pad_count(void *obj, int startoff);
+static int inode_core_flushiter_count(void *obj, int startoff);
+static int inode_core_nrext64_pad_count(void *obj, int startoff);
+static int inode_core_nextents_offset(void *obj, int startoff, int idx);
+static int inode_core_nextents32_count(void *obj, int startoff);
+static int inode_core_nextents64_count(void *obj, int startoff);
+static int inode_core_anextents_offset(void *obj, int startoff, int idx);
+static int inode_core_anextents16_count(void *obj, int startoff);
+static int inode_core_anextents32_count(void *obj, int startoff);
static int inode_f(int argc, char **argv);
static int inode_u_offset(void *obj, int startoff, int idx);
static int inode_u_bmbt_count(void *obj, int startoff);
@@ -90,18 +100,30 @@ const field_t inode_core_flds[] = {
inode_core_projid_count, FLD_COUNT, TYP_NONE },
{ "projid_hi", FLDT_UINT16D, OI(COFF(projid_hi)),
inode_core_projid_count, FLD_COUNT, TYP_NONE },
- { "pad", FLDT_UINT8X, OI(OFF(pad)), CI(6), FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
+ { "v3_pad", FLDT_UINT8X, OI(OFF(v3_pad)),
+ inode_core_v3_pad_count, FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
+ { "v2_pad", FLDT_UINT8X, OI(OFF(v2_pad)),
+ inode_core_v2_pad_count, FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
{ "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE },
{ "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE },
- { "flushiter", FLDT_UINT16D, OI(COFF(flushiter)), C1, 0, TYP_NONE },
+ { "flushiter", FLDT_UINT16D, OI(COFF(flushiter)),
+ inode_core_flushiter_count, FLD_COUNT, TYP_NONE },
{ "atime", FLDT_TIMESTAMP, OI(COFF(atime)), C1, 0, TYP_NONE },
{ "mtime", FLDT_TIMESTAMP, OI(COFF(mtime)), C1, 0, TYP_NONE },
{ "ctime", FLDT_TIMESTAMP, OI(COFF(ctime)), C1, 0, TYP_NONE },
{ "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
{ "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
{ "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
- { "nextents", FLDT_EXTNUM, OI(COFF(nextents)), C1, 0, TYP_NONE },
- { "naextents", FLDT_AEXTNUM, OI(COFF(anextents)), C1, 0, TYP_NONE },
+ { "nrext64_pad", FLDT_UINT16D, OI(COFF(nrext64_pad)),
+ inode_core_nrext64_pad_count, FLD_COUNT|FLD_SKIPALL, TYP_NONE },
+ { "nextents", FLDT_UINT32D, inode_core_nextents_offset,
+ inode_core_nextents32_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
+ { "nextents", FLDT_UINT64D, inode_core_nextents_offset,
+ inode_core_nextents64_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
+ { "naextents", FLDT_UINT16D, inode_core_anextents_offset,
+ inode_core_anextents16_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
+ { "naextents", FLDT_UINT32D, inode_core_anextents_offset,
+ inode_core_anextents32_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
{ "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
{ "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
{ "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
@@ -403,6 +425,181 @@ inode_core_projid_count(
return dic->di_version >= 2;
}
+static int
+inode_core_v3_pad_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if ((dic->di_version == 3)
+ && !(dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64)))
+ return 8;
+
+ return 0;
+}
+
+static int
+inode_core_v2_pad_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (dic->di_version == 3)
+ return 0;
+
+ return 6;
+}
+
+static int
+inode_core_flushiter_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (dic->di_version == 3)
+ return 0;
+
+ return 1;
+}
+
+static int
+inode_core_nrext64_pad_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return 1;
+
+ return 0;
+}
+
+static int
+inode_core_nextents_offset(
+ void *obj,
+ int startoff,
+ int idx)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(idx == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return COFF(big_nextents);
+
+ return COFF(nextents);
+}
+
+static int
+inode_core_nextents32_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return 0;
+
+ return 1;
+}
+
+static int
+inode_core_nextents64_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return 1;
+
+ return 0;
+}
+
+static int
+inode_core_anextents_offset(
+ void *obj,
+ int startoff,
+ int idx)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(idx == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return COFF(big_anextents);
+
+ return COFF(anextents);
+}
+
+static int
+inode_core_anextents16_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return 0;
+
+ return 1;
+}
+
+static int
+inode_core_anextents32_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_dinode *dic;
+
+ ASSERT(startoff == 0);
+ ASSERT(obj == iocur_top->data);
+ dic = obj;
+
+ if (xfs_dinode_has_nrext64(dic))
+ return 1;
+
+ return 0;
+}
+
static int
inode_f(
int argc,
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index d3dfd45c..df1d6ec3 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -792,16 +792,30 @@ struct xfs_dinode {
__be32 di_nlink; /* number of links to file */
__be16 di_projid_lo; /* lower part of owner's project id */
__be16 di_projid_hi; /* higher part owner's project id */
- __u8 di_pad[6]; /* unused, zeroed space */
- __be16 di_flushiter; /* incremented on flush */
+ union {
+ __be64 di_big_nextents;/* NREXT64 data extents */
+ __u8 di_v3_pad[8]; /* !NREXT64 V3 inode zeroed space */
+ struct {
+ __u8 di_v2_pad[6]; /* V2 inode zeroed space */
+ __be16 di_flushiter; /* V2 inode incremented on flush */
+ };
+ };
xfs_timestamp_t di_atime; /* time last accessed */
xfs_timestamp_t di_mtime; /* time last modified */
xfs_timestamp_t di_ctime; /* time created/inode modified */
__be64 di_size; /* number of bytes in file */
__be64 di_nblocks; /* # of direct & btree blocks used */
__be32 di_extsize; /* basic/minimum extent size for file */
- __be32 di_nextents; /* number of extents in data fork */
- __be16 di_anextents; /* number of extents in attribute fork*/
+ union {
+ struct {
+ __be32 di_big_anextents; /* NREXT64 attr extents */
+ __be16 di_nrext64_pad; /* NREXT64 unused, zero */
+ } __packed;
+ struct {
+ __be32 di_nextents; /* !NREXT64 data extents */
+ __be16 di_anextents; /* !NREXT64 attr extents */
+ } __packed;
+ };
__u8 di_forkoff; /* attr fork offs, <<3 for 64b align */
__s8 di_aformat; /* format of attr fork's data */
__be32 di_dmevmask; /* DMIG event mask */
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index b3f6be93..9db63db9 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -276,6 +276,25 @@ xfs_inode_to_disk_ts(
return ts;
}
+static inline void
+xfs_inode_to_disk_iext_counters(
+ struct xfs_inode *ip,
+ struct xfs_dinode *to)
+{
+ if (xfs_inode_has_nrext64(ip)) {
+ to->di_big_nextents = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
+ to->di_big_anextents = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
+ /*
+ * We might be upgrading the inode to use larger extent counters
+ * than was previously used. Hence zero the unused field.
+ */
+ to->di_nrext64_pad = cpu_to_be16(0);
+ } else {
+ to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
+ to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
+ }
+}
+
void
xfs_inode_to_disk(
struct xfs_inode *ip,
@@ -293,7 +312,6 @@ xfs_inode_to_disk(
to->di_projid_lo = cpu_to_be16(ip->i_projid & 0xffff);
to->di_projid_hi = cpu_to_be16(ip->i_projid >> 16);
- memset(to->di_pad, 0, sizeof(to->di_pad));
to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
@@ -304,8 +322,6 @@ xfs_inode_to_disk(
to->di_size = cpu_to_be64(ip->i_disk_size);
to->di_nblocks = cpu_to_be64(ip->i_nblocks);
to->di_extsize = cpu_to_be32(ip->i_extsize);
- to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
- to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
to->di_forkoff = ip->i_forkoff;
to->di_aformat = xfs_ifork_format(ip->i_afp);
to->di_flags = cpu_to_be16(ip->i_diflags);
@@ -320,11 +336,14 @@ xfs_inode_to_disk(
to->di_lsn = cpu_to_be64(lsn);
memset(to->di_pad2, 0, sizeof(to->di_pad2));
uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
- to->di_flushiter = 0;
+ memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
} else {
to->di_version = 2;
to->di_flushiter = cpu_to_be16(ip->i_flushiter);
+ memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
}
+
+ xfs_inode_to_disk_iext_counters(ip, to);
}
static xfs_failaddr_t
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index e5680343..8e6221e3 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -156,6 +156,9 @@ static inline xfs_extnum_t
xfs_dfork_data_extents(
struct xfs_dinode *dip)
{
+ if (xfs_dinode_has_nrext64(dip))
+ return be64_to_cpu(dip->di_big_nextents);
+
return be32_to_cpu(dip->di_nextents);
}
@@ -163,6 +166,9 @@ static inline xfs_extnum_t
xfs_dfork_attr_extents(
struct xfs_dinode *dip)
{
+ if (xfs_dinode_has_nrext64(dip))
+ return be32_to_cpu(dip->di_big_anextents);
+
return be16_to_cpu(dip->di_anextents);
}
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index fd66e702..8dcd53fd 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -388,16 +388,30 @@ struct xfs_log_dinode {
uint32_t di_nlink; /* number of links to file */
uint16_t di_projid_lo; /* lower part of owner's project id */
uint16_t di_projid_hi; /* higher part of owner's project id */
- uint8_t di_pad[6]; /* unused, zeroed space */
- uint16_t di_flushiter; /* incremented on flush */
+ union {
+ uint64_t di_big_nextents;/* NREXT64 data extents */
+ uint8_t di_v3_pad[8]; /* !NREXT64 V3 inode zeroed space */
+ struct {
+ uint8_t di_v2_pad[6]; /* V2 inode zeroed space */
+ uint16_t di_flushiter; /* V2 inode incremented on flush */
+ };
+ };
xfs_log_timestamp_t di_atime; /* time last accessed */
xfs_log_timestamp_t di_mtime; /* time last modified */
xfs_log_timestamp_t di_ctime; /* time created/inode modified */
xfs_fsize_t di_size; /* number of bytes in file */
xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
- uint32_t di_nextents; /* number of extents in data fork */
- uint16_t di_anextents; /* number of extents in attribute fork*/
+ union {
+ struct {
+ uint32_t di_big_anextents; /* NREXT64 attr extents */
+ uint16_t di_nrext64_pad; /* NREXT64 unused, zero */
+ } __packed;
+ struct {
+ uint32_t di_nextents; /* !NREXT64 data extents */
+ uint16_t di_anextents; /* !NREXT64 attr extents */
+ } __packed;
+ };
uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
int8_t di_aformat; /* format of attr fork's data */
uint32_t di_dmevmask; /* DMIG event mask */
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index 35e926a3..95fb22a6 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -440,6 +440,8 @@ static void
xlog_print_trans_inode_core(
struct xfs_log_dinode *ip)
{
+ xfs_extnum_t nextents;
+
printf(_("INODE CORE\n"));
printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
ip->di_magic, ip->di_mode, (int)ip->di_version,
@@ -450,11 +452,21 @@ xlog_print_trans_inode_core(
xlog_extract_dinode_ts(ip->di_atime),
xlog_extract_dinode_ts(ip->di_mtime),
xlog_extract_dinode_ts(ip->di_ctime));
- printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
+
+ if (ip->di_flags2 & XFS_DIFLAG2_NREXT64)
+ nextents = ip->di_big_nextents;
+ else
+ nextents = ip->di_nextents;
+ printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%lx\n"),
(unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
- ip->di_extsize, ip->di_nextents);
- printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
- ip->di_anextents, (int)ip->di_forkoff, ip->di_dmevmask,
+ ip->di_extsize, nextents);
+
+ if (ip->di_flags2 & XFS_DIFLAG2_NREXT64)
+ nextents = ip->di_big_anextents;
+ else
+ nextents = ip->di_anextents;
+ printf(_("naextents 0x%lx forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
+ nextents, (int)ip->di_forkoff, ip->di_dmevmask,
ip->di_dmstate);
printf(_("flags 0x%x gen 0x%x\n"),
ip->di_flags, ip->di_gen);
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index 182b9d53..73ffc2f0 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -240,7 +240,10 @@ STATIC void
xlog_recover_print_inode_core(
struct xfs_log_dinode *di)
{
- printf(_(" CORE inode:\n"));
+ xfs_extnum_t nextents;
+ xfs_aextnum_t anextents;
+
+ printf(_(" CORE inode:\n"));
if (!print_inode)
return;
printf(_(" magic:%c%c mode:0x%x ver:%d format:%d\n"),
@@ -254,10 +257,19 @@ xlog_recover_print_inode_core(
xlog_extract_dinode_ts(di->di_mtime),
xlog_extract_dinode_ts(di->di_ctime));
printf(_(" flushiter:%d\n"), di->di_flushiter);
+
+ if (di->di_flags2 & XFS_DIFLAG2_NREXT64) {
+ nextents = di->di_big_nextents;
+ anextents = di->di_big_anextents;
+ } else {
+ nextents = di->di_nextents;
+ anextents = di->di_anextents;
+ }
+
printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
- "nextents:%d anextents:%d\n"), (unsigned long long)
+ "nextents:%lu anextents:%u\n"), (unsigned long long)
di->di_size, (unsigned long long)di->di_nblocks,
- di->di_extsize, di->di_nextents, (int)di->di_anextents);
+ di->di_extsize, nextents, anextents);
printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
"gen:%u\n"),
(int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate,
diff --git a/repair/dinode.c b/repair/dinode.c
index 54efe571..bf1ee26d 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -71,7 +71,12 @@ _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
if (xfs_dfork_attr_extents(dino) != 0) {
if (no_modify)
return(1);
- dino->di_anextents = cpu_to_be16(0);
+
+ if (xfs_dinode_has_nrext64(dino))
+ dino->di_big_anextents = 0;
+ else
+ dino->di_anextents = 0;
+
}
if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
@@ -1818,7 +1823,10 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
do_warn(
_("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, nextents);
- dino->di_nextents = cpu_to_be32(nextents);
+ if (xfs_dinode_has_nrext64(dino))
+ dino->di_big_nextents = cpu_to_be64(nextents);
+ else
+ dino->di_nextents = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
@@ -1841,7 +1849,11 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
do_warn(
_("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, anextents);
- dino->di_anextents = cpu_to_be16(anextents);
+ if (xfs_dinode_has_nrext64(dino))
+ dino->di_big_anextents = cpu_to_be32(anextents);
+ else
+ dino->di_anextents = cpu_to_be16(anextents);
+
*dirty = 1;
} else {
do_warn(
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 14/20] xfsprogs: Conditionally upgrade existing inodes to use 64-bit extent counters
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (12 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 13/20] xfsprogs: Introduce per-inode 64-bit extent counters Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 15/20] xfsprogs: Enable bulkstat ioctl to support " Chandan Babu R
` (5 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit upgrades inodes to use 64-bit extent counters when they are read
from disk. Inodes are upgraded only when the filesystem instance has
XFS_SB_FEAT_INCOMPAT_NREXT64 incompat flag set.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_inode_buf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 9db63db9..60feee8b 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -250,6 +250,12 @@ xfs_inode_from_disk(
}
if (xfs_is_reflink_inode(ip))
xfs_ifork_init_cow(ip);
+
+ if ((from->di_version == 3) &&
+ xfs_has_nrext64(ip->i_mount) &&
+ !xfs_dinode_has_nrext64(from))
+ ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;
+
return 0;
out_destroy_data_fork:
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 15/20] xfsprogs: Enable bulkstat ioctl to support 64-bit extent counters
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (13 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 14/20] xfsprogs: Conditionally upgrade existing inodes to use " Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-02-01 19:29 ` Darrick J. Wong
2022-01-21 5:20 ` [PATCH V5 16/20] xfsprogs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
` (4 subsequent siblings)
19 siblings, 1 reply; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit adds support to libfrog to enable reporting 64-bit extent counters
to its users. In order to do so, bulkstat ioctl is now invoked with the newly
introduced XFS_BULK_IREQ_NREXT64 flag if the underlying filesystem's geometry
supports 64-bit extent counters.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
fsr/xfs_fsr.c | 4 ++--
io/bulkstat.c | 1 +
libfrog/bulkstat.c | 29 +++++++++++++++++++++++++++--
libxfs/xfs_fs.h | 12 ++++++++----
4 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 6cf8bfb7..ba02506d 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -590,7 +590,7 @@ cmp(const void *s1, const void *s2)
(bs1->bs_version == XFS_BULKSTAT_VERSION_V5 &&
bs2->bs_version == XFS_BULKSTAT_VERSION_V5));
- return (bs2->bs_extents - bs1->bs_extents);
+ return (bs2->bs_extents64 - bs1->bs_extents64);
}
/*
@@ -655,7 +655,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
for (p = buf, endp = (buf + buflenout); p < endp ; p++) {
/* Do some obvious checks now */
if (((p->bs_mode & S_IFMT) != S_IFREG) ||
- (p->bs_extents < 2))
+ (p->bs_extents64 < 2))
continue;
ret = -xfrog_bulkstat_v5_to_v1(&fsxfd, &bs1, p);
diff --git a/io/bulkstat.c b/io/bulkstat.c
index 201470b2..0c9a2b02 100644
--- a/io/bulkstat.c
+++ b/io/bulkstat.c
@@ -57,6 +57,7 @@ dump_bulkstat(
printf("\tbs_sick = 0x%"PRIx16"\n", bstat->bs_sick);
printf("\tbs_checked = 0x%"PRIx16"\n", bstat->bs_checked);
printf("\tbs_mode = 0%"PRIo16"\n", bstat->bs_mode);
+ printf("\tbs_extents64 = %"PRIu64"\n", bstat->bs_extents64);
};
static void
diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
index 195f6ea0..0a90947f 100644
--- a/libfrog/bulkstat.c
+++ b/libfrog/bulkstat.c
@@ -56,6 +56,9 @@ xfrog_bulkstat_single5(
if (flags & ~(XFS_BULK_IREQ_SPECIAL))
return -EINVAL;
+ if (xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)
+ flags |= XFS_BULK_IREQ_NREXT64;
+
ret = xfrog_bulkstat_alloc_req(1, ino, &req);
if (ret)
return ret;
@@ -73,6 +76,12 @@ xfrog_bulkstat_single5(
}
memcpy(bulkstat, req->bulkstat, sizeof(struct xfs_bulkstat));
+
+ if (!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)) {
+ bulkstat->bs_extents64 = bulkstat->bs_extents;
+ bulkstat->bs_extents = 0;
+ }
+
free:
free(req);
return ret;
@@ -129,6 +138,7 @@ xfrog_bulkstat_single(
switch (error) {
case -EOPNOTSUPP:
case -ENOTTY:
+ assert(!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64));
xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
break;
}
@@ -259,10 +269,23 @@ xfrog_bulkstat5(
struct xfs_bulkstat_req *req)
{
int ret;
+ int i;
+
+ if (xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)
+ req->hdr.flags |= XFS_BULK_IREQ_NREXT64;
ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT, req);
if (ret)
return -errno;
+
+ if (!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)) {
+ for (i = 0; i < req->hdr.ocount; i++) {
+ req->bulkstat[i].bs_extents64 =
+ req->bulkstat[i].bs_extents;
+ req->bulkstat[i].bs_extents = 0;
+ }
+ }
+
return 0;
}
@@ -316,6 +339,7 @@ xfrog_bulkstat(
switch (error) {
case -EOPNOTSUPP:
case -ENOTTY:
+ assert(!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64));
xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
break;
}
@@ -342,6 +366,7 @@ xfrog_bulkstat_v5_to_v1(
const struct xfs_bulkstat *bs5)
{
if (bs5->bs_aextents > UINT16_MAX ||
+ bs5->bs_extents64 > INT32_MAX ||
cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks) > UINT32_MAX ||
cvt_off_fsb_to_b(xfd, bs5->bs_cowextsize_blks) > UINT32_MAX ||
time_too_big(bs5->bs_atime) ||
@@ -366,7 +391,7 @@ xfrog_bulkstat_v5_to_v1(
bs1->bs_blocks = bs5->bs_blocks;
bs1->bs_xflags = bs5->bs_xflags;
bs1->bs_extsize = cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks);
- bs1->bs_extents = bs5->bs_extents;
+ bs1->bs_extents = bs5->bs_extents64;
bs1->bs_gen = bs5->bs_gen;
bs1->bs_projid_lo = bs5->bs_projectid & 0xFFFF;
bs1->bs_forkoff = bs5->bs_forkoff;
@@ -407,7 +432,6 @@ xfrog_bulkstat_v1_to_v5(
bs5->bs_blocks = bs1->bs_blocks;
bs5->bs_xflags = bs1->bs_xflags;
bs5->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
- bs5->bs_extents = bs1->bs_extents;
bs5->bs_gen = bs1->bs_gen;
bs5->bs_projectid = bstat_get_projid(bs1);
bs5->bs_forkoff = bs1->bs_forkoff;
@@ -415,6 +439,7 @@ xfrog_bulkstat_v1_to_v5(
bs5->bs_checked = bs1->bs_checked;
bs5->bs_cowextsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_cowextsize);
bs5->bs_aextents = bs1->bs_aextents;
+ bs5->bs_extents64 = bs1->bs_extents;
}
/* Allocate a bulkstat request. Returns zero or a negative error code. */
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 42bc3950..f65bf2da 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -393,7 +393,7 @@ struct xfs_bulkstat {
uint32_t bs_extsize_blks; /* extent size hint, blocks */
uint32_t bs_nlink; /* number of links */
- uint32_t bs_extents; /* number of extents */
+ uint32_t bs_extents; /* 32-bit data fork extent counter */
uint32_t bs_aextents; /* attribute number of extents */
uint16_t bs_version; /* structure version */
uint16_t bs_forkoff; /* inode fork offset in bytes */
@@ -402,8 +402,9 @@ struct xfs_bulkstat {
uint16_t bs_checked; /* checked inode metadata */
uint16_t bs_mode; /* type and mode */
uint16_t bs_pad2; /* zeroed */
+ uint64_t bs_extents64; /* 64-bit data fork extent counter */
- uint64_t bs_pad[7]; /* zeroed */
+ uint64_t bs_pad[6]; /* zeroed */
};
#define XFS_BULKSTAT_VERSION_V1 (1)
@@ -484,8 +485,11 @@ struct xfs_bulk_ireq {
*/
#define XFS_BULK_IREQ_SPECIAL (1 << 1)
-#define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO | \
- XFS_BULK_IREQ_SPECIAL)
+#define XFS_BULK_IREQ_NREXT64 (1 << 3)
+
+#define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO | \
+ XFS_BULK_IREQ_SPECIAL | \
+ XFS_BULK_IREQ_NREXT64)
/* Operate on the root directory inode. */
#define XFS_BULK_IREQ_SPECIAL_ROOT (1)
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 16/20] xfsprogs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (14 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 15/20] xfsprogs: Enable bulkstat ioctl to support " Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 17/20] xfsprogs: xfs_info: Report NREXT64 feature status Chandan Babu R
` (3 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit enables XFS module to work with fs instances having 64-bit
per-inode extent counters by adding XFS_SB_FEAT_INCOMPAT_NREXT64 flag to the
list of supported incompat feature flags.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libxfs/xfs_format.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index df1d6ec3..b7521c1d 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -378,7 +378,8 @@ xfs_sb_has_ro_compat_feature(
XFS_SB_FEAT_INCOMPAT_SPINODES| \
XFS_SB_FEAT_INCOMPAT_META_UUID| \
XFS_SB_FEAT_INCOMPAT_BIGTIME| \
- XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
+ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR| \
+ XFS_SB_FEAT_INCOMPAT_NREXT64)
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
static inline bool
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 17/20] xfsprogs: xfs_info: Report NREXT64 feature status
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (15 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 16/20] xfsprogs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 18/20] xfsprogs: Add mkfs option to create filesystem with large extent counters Chandan Babu R
` (2 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit adds support to libfrog to obtain information about the
availability of NREXT64 feature in the underlying filesystem.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
libfrog/fsgeom.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index 4f1a1842..3e7f0797 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -30,6 +30,7 @@ xfs_report_geom(
int reflink_enabled;
int bigtime_enabled;
int inobtcount;
+ int nrext64;
isint = geo->logstart > 0;
lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0;
@@ -47,12 +48,13 @@ xfs_report_geom(
reflink_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_REFLINK ? 1 : 0;
bigtime_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_BIGTIME ? 1 : 0;
inobtcount = geo->flags & XFS_FSOP_GEOM_FLAGS_INOBTCNT ? 1 : 0;
+ nrext64 = geo->flags & XFS_FSOP_GEOM_FLAGS_NREXT64 ? 1 : 0;
printf(_(
"meta-data=%-22s isize=%-6d agcount=%u, agsize=%u blks\n"
" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
" =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n"
-" =%-22s reflink=%-4u bigtime=%u inobtcount=%u\n"
+" =%-22s reflink=%-4u bigtime=%u inobtcount=%u nrext64=%u\n"
"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
" =%-22s sunit=%-6u swidth=%u blks\n"
"naming =version %-14u bsize=%-6u ascii-ci=%d, ftype=%d\n"
@@ -62,7 +64,7 @@ xfs_report_geom(
mntpoint, geo->inodesize, geo->agcount, geo->agblocks,
"", geo->sectsize, attrversion, projid32bit,
"", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled,
- "", reflink_enabled, bigtime_enabled, inobtcount,
+ "", reflink_enabled, bigtime_enabled, inobtcount, nrext64,
"", geo->blocksize, (unsigned long long)geo->datablocks,
geo->imaxpct,
"", geo->sunit, geo->swidth,
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 18/20] xfsprogs: Add mkfs option to create filesystem with large extent counters
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (16 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 17/20] xfsprogs: xfs_info: Report NREXT64 feature status Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-25 0:33 ` Darrick J. Wong
2022-01-21 5:20 ` [PATCH V5 19/20] xfsprogs: Add support for upgrading to NREXT64 feature Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 20/20] xfsprogs: Define max extent length based on on-disk format definition Chandan Babu R
19 siblings, 1 reply; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
Enabling nrext64 option on mkfs.xfs command line extends the maximum values of
inode data and attr fork extent counters to 2^48 - 1 and 2^32 - 1
respectively. This also sets the XFS_SB_FEAT_INCOMPAT_NREXT64 incompat flag
on the superblock preventing older kernels from mounting such a filesystem.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
man/man8/mkfs.xfs.8.in | 7 +++++++
mkfs/lts_4.19.conf | 1 +
mkfs/lts_5.10.conf | 1 +
mkfs/lts_5.15.conf | 1 +
mkfs/lts_5.4.conf | 1 +
mkfs/xfs_mkfs.c | 23 +++++++++++++++++++++++
6 files changed, 34 insertions(+)
diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index a3526753..7d764f19 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -647,6 +647,13 @@ space over time such that no free extents are large enough to
accommodate a chunk of 64 inodes. Without this feature enabled, inode
allocations can fail with out of space errors under severe fragmented
free space conditions.
+.TP
+.BI nrext64[= value]
+Extend maximum values of inode data and attr fork extent counters from 2^31 -
+1 and 2^15 - 1 to 2^48 - 1 and 2^32 - 1 respectively. If the value is
+omitted, 1 is assumed. This feature is disabled by default. This feature is
+only available for filesystems formatted with -m crc=1.
+.TP
.RE
.PP
.PD 0
diff --git a/mkfs/lts_4.19.conf b/mkfs/lts_4.19.conf
index d21fcb7e..751be45e 100644
--- a/mkfs/lts_4.19.conf
+++ b/mkfs/lts_4.19.conf
@@ -2,6 +2,7 @@
# kernel was released at the end of 2018.
[metadata]
+nrext64=0
bigtime=0
crc=1
finobt=1
diff --git a/mkfs/lts_5.10.conf b/mkfs/lts_5.10.conf
index ac00960e..a1c991ce 100644
--- a/mkfs/lts_5.10.conf
+++ b/mkfs/lts_5.10.conf
@@ -2,6 +2,7 @@
# kernel was released at the end of 2020.
[metadata]
+nrext64=0
bigtime=0
crc=1
finobt=1
diff --git a/mkfs/lts_5.15.conf b/mkfs/lts_5.15.conf
index 32082958..d751f4c4 100644
--- a/mkfs/lts_5.15.conf
+++ b/mkfs/lts_5.15.conf
@@ -2,6 +2,7 @@
# kernel was released at the end of 2021.
[metadata]
+nrext64=0
bigtime=1
crc=1
finobt=1
diff --git a/mkfs/lts_5.4.conf b/mkfs/lts_5.4.conf
index dd60b9f1..7e8a0ff0 100644
--- a/mkfs/lts_5.4.conf
+++ b/mkfs/lts_5.4.conf
@@ -2,6 +2,7 @@
# kernel was released at the end of 2019.
[metadata]
+nrext64=0
bigtime=0
crc=1
finobt=1
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 96682f9a..28aca7b0 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -79,6 +79,7 @@ enum {
I_ATTR,
I_PROJID32BIT,
I_SPINODES,
+ I_NREXT64,
I_MAX_OPTS,
};
@@ -433,6 +434,7 @@ static struct opt_params iopts = {
[I_ATTR] = "attr",
[I_PROJID32BIT] = "projid32bit",
[I_SPINODES] = "sparse",
+ [I_NREXT64] = "nrext64",
},
.subopt_params = {
{ .index = I_ALIGN,
@@ -481,6 +483,12 @@ static struct opt_params iopts = {
.maxval = 1,
.defaultval = 1,
},
+ { .index = I_NREXT64,
+ .conflicts = { { NULL, LAST_CONFLICT } },
+ .minval = 0,
+ .maxval = 1,
+ .defaultval = 1,
+ }
},
};
@@ -805,6 +813,7 @@ struct sb_feat_args {
bool bigtime; /* XFS_SB_FEAT_INCOMPAT_BIGTIME */
bool nodalign;
bool nortalign;
+ bool nrext64;
};
struct cli_params {
@@ -1595,6 +1604,9 @@ inode_opts_parser(
case I_SPINODES:
cli->sb_feat.spinodes = getnum(value, opts, subopt);
break;
+ case I_NREXT64:
+ cli->sb_feat.nrext64 = getnum(value, opts, subopt);
+ break;
default:
return -EINVAL;
}
@@ -2172,6 +2184,14 @@ _("timestamps later than 2038 not supported without CRC support\n"));
usage();
}
cli->sb_feat.bigtime = false;
+
+ if (cli->sb_feat.nrext64 &&
+ cli_opt_set(&iopts, I_NREXT64)) {
+ fprintf(stderr,
+_("64 bit extent count not supported without CRC support\n"));
+ usage();
+ }
+ cli->sb_feat.nrext64 = false;
}
if (!cli->sb_feat.finobt) {
@@ -3164,6 +3184,8 @@ sb_set_features(
sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
}
+ if (fp->nrext64)
+ sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
}
/*
@@ -3875,6 +3897,7 @@ main(
.nodalign = false,
.nortalign = false,
.bigtime = true,
+ .nrext64 = false,
/*
* When we decide to enable a new feature by default,
* please remember to update the mkfs conf files.
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 19/20] xfsprogs: Add support for upgrading to NREXT64 feature
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (17 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 18/20] xfsprogs: Add mkfs option to create filesystem with large extent counters Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
2022-01-25 0:35 ` Darrick J. Wong
2022-01-21 5:20 ` [PATCH V5 20/20] xfsprogs: Define max extent length based on on-disk format definition Chandan Babu R
19 siblings, 1 reply; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
This commit adds support to xfs_repair to allow upgrading an existing
filesystem to support per-inode large extent counters.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
man/man8/xfs_admin.8 | 7 +++++++
repair/globals.c | 1 +
repair/globals.h | 1 +
repair/phase2.c | 24 ++++++++++++++++++++++++
repair/xfs_repair.c | 11 +++++++++++
5 files changed, 44 insertions(+)
diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8
index ad28e0f6..d64ed45b 100644
--- a/man/man8/xfs_admin.8
+++ b/man/man8/xfs_admin.8
@@ -149,6 +149,13 @@ Upgrade a filesystem to support larger timestamps up to the year 2486.
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.10.
+.TP 0.4i
+.B nrext64
+Upgrade a filesystem to support large per-inode extent counters. Maximum data
+fork extent count will be 2^48 while the maximum attribute fork extent count
+will be 2^32. 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.18.
.RE
.TP
.BI \-U " uuid"
diff --git a/repair/globals.c b/repair/globals.c
index f8d4f1e4..c4084985 100644
--- a/repair/globals.c
+++ b/repair/globals.c
@@ -51,6 +51,7 @@ int lazy_count; /* What to set if to if converting */
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;
/* misc status variables */
diff --git a/repair/globals.h b/repair/globals.h
index 0f98bd2b..b65e4a2d 100644
--- a/repair/globals.h
+++ b/repair/globals.h
@@ -92,6 +92,7 @@ extern int lazy_count; /* What to set if to if converting */
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;
/* misc status variables */
diff --git a/repair/phase2.c b/repair/phase2.c
index 4c315055..979e281d 100644
--- a/repair/phase2.c
+++ b/repair/phase2.c
@@ -181,6 +181,28 @@ set_bigtime(
return true;
}
+static bool
+set_nrext64(
+ struct xfs_mount *mp,
+ struct xfs_sb *new_sb)
+{
+ if (!xfs_has_crc(mp)) {
+ printf(
+ _("Nrext64 only supported on V5 filesystems.\n"));
+ exit(0);
+ }
+
+ if (xfs_has_nrext64(mp)) {
+ printf(_("Filesystem already supports nrext64.\n"));
+ exit(0);
+ }
+
+ printf(_("Adding nrext64 to filesystem.\n"));
+ new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
+ new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+ return true;
+}
+
struct check_state {
struct xfs_sb sb;
uint64_t features;
@@ -380,6 +402,8 @@ upgrade_filesystem(
dirty |= set_inobtcount(mp, &new_sb);
if (add_bigtime)
dirty |= set_bigtime(mp, &new_sb);
+ if (add_nrext64)
+ dirty |= set_nrext64(mp, &new_sb);
if (!dirty)
return;
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index de8617ba..c4705cf2 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -67,6 +67,7 @@ enum c_opt_nums {
CONVERT_LAZY_COUNT = 0,
CONVERT_INOBTCOUNT,
CONVERT_BIGTIME,
+ CONVERT_NREXT64,
C_MAX_OPTS,
};
@@ -74,6 +75,7 @@ static char *c_opts[] = {
[CONVERT_LAZY_COUNT] = "lazycount",
[CONVERT_INOBTCOUNT] = "inobtcount",
[CONVERT_BIGTIME] = "bigtime",
+ [CONVERT_NREXT64] = "nrext64",
[C_MAX_OPTS] = NULL,
};
@@ -324,6 +326,15 @@ process_args(int argc, char **argv)
_("-c bigtime only supports upgrades\n"));
add_bigtime = true;
break;
+ case CONVERT_NREXT64:
+ if (!val)
+ do_abort(
+ _("-c nrext64 requires a parameter\n"));
+ if (strtol(val, NULL, 0) != 1)
+ do_abort(
+ _("-c nrext64 only supports upgrades\n"));
+ add_nrext64 = true;
+ break;
default:
unknown('c', val);
break;
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH V5 20/20] xfsprogs: Define max extent length based on on-disk format definition
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (18 preceding siblings ...)
2022-01-21 5:20 ` [PATCH V5 19/20] xfsprogs: Add support for upgrading to NREXT64 feature Chandan Babu R
@ 2022-01-21 5:20 ` Chandan Babu R
19 siblings, 0 replies; 24+ messages in thread
From: Chandan Babu R @ 2022-01-21 5:20 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, david
The maximum extent length depends on maximum block count that can be stored in
a BMBT record. Hence this commit defines MAXEXTLEN based on
BMBT_BLOCKCOUNT_BITLEN.
While at it, the commit also renames MAXEXTLEN to XFS_MAX_BMBT_EXTLEN.
Suggested-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 2 +-
libxfs/xfs_bmap.c | 51 +++++++++++++++++++++--------------------
libxfs/xfs_format.h | 5 ++--
libxfs/xfs_inode_buf.c | 4 ++--
libxfs/xfs_trans_resv.c | 10 ++++----
mkfs/xfs_mkfs.c | 6 ++---
repair/phase4.c | 2 +-
7 files changed, 41 insertions(+), 39 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 90b2979d..9ea388b9 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -20,7 +20,7 @@
#include "field.h"
#include "dir2.h"
-#define DEFAULT_MAX_EXT_SIZE MAXEXTLEN
+#define DEFAULT_MAX_EXT_SIZE XFS_MAX_BMBT_EXTLEN
/* copy all metadata structures to/from a file */
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 8dd084b9..e3414657 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -1443,7 +1443,7 @@ xfs_bmap_add_extent_delay_real(
LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
LEFT.br_state == new->br_state &&
- LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+ LEFT.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
state |= BMAP_LEFT_CONTIG;
/*
@@ -1461,13 +1461,13 @@ xfs_bmap_add_extent_delay_real(
new_endoff == RIGHT.br_startoff &&
new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
new->br_state == RIGHT.br_state &&
- new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
+ new->br_blockcount + RIGHT.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
BMAP_RIGHT_FILLING)) !=
(BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
BMAP_RIGHT_FILLING) ||
LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
- <= MAXEXTLEN))
+ <= XFS_MAX_BMBT_EXTLEN))
state |= BMAP_RIGHT_CONTIG;
error = 0;
@@ -1991,7 +1991,7 @@ xfs_bmap_add_extent_unwritten_real(
LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
LEFT.br_state == new->br_state &&
- LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+ LEFT.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
state |= BMAP_LEFT_CONTIG;
/*
@@ -2009,13 +2009,13 @@ xfs_bmap_add_extent_unwritten_real(
new_endoff == RIGHT.br_startoff &&
new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
new->br_state == RIGHT.br_state &&
- new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
+ new->br_blockcount + RIGHT.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
BMAP_RIGHT_FILLING)) !=
(BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
BMAP_RIGHT_FILLING) ||
LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
- <= MAXEXTLEN))
+ <= XFS_MAX_BMBT_EXTLEN))
state |= BMAP_RIGHT_CONTIG;
/*
@@ -2501,15 +2501,15 @@ xfs_bmap_add_extent_hole_delay(
*/
if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) &&
left.br_startoff + left.br_blockcount == new->br_startoff &&
- left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+ left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
state |= BMAP_LEFT_CONTIG;
if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) &&
new->br_startoff + new->br_blockcount == right.br_startoff &&
- new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
+ new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
(!(state & BMAP_LEFT_CONTIG) ||
(left.br_blockcount + new->br_blockcount +
- right.br_blockcount <= MAXEXTLEN)))
+ right.br_blockcount <= XFS_MAX_BMBT_EXTLEN)))
state |= BMAP_RIGHT_CONTIG;
/*
@@ -2652,17 +2652,17 @@ xfs_bmap_add_extent_hole_real(
left.br_startoff + left.br_blockcount == new->br_startoff &&
left.br_startblock + left.br_blockcount == new->br_startblock &&
left.br_state == new->br_state &&
- left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+ left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
state |= BMAP_LEFT_CONTIG;
if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
new->br_startoff + new->br_blockcount == right.br_startoff &&
new->br_startblock + new->br_blockcount == right.br_startblock &&
new->br_state == right.br_state &&
- new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
+ new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
(!(state & BMAP_LEFT_CONTIG) ||
left.br_blockcount + new->br_blockcount +
- right.br_blockcount <= MAXEXTLEN))
+ right.br_blockcount <= XFS_MAX_BMBT_EXTLEN))
state |= BMAP_RIGHT_CONTIG;
error = 0;
@@ -2897,15 +2897,15 @@ xfs_bmap_extsize_align(
/*
* For large extent hint sizes, the aligned extent might be larger than
- * MAXEXTLEN. In that case, reduce the size by an extsz so that it pulls
- * the length back under MAXEXTLEN. The outer allocation loops handle
+ * XFS_MAX_BMBT_EXTLEN. In that case, reduce the size by an extsz so that it pulls
+ * the length back under XFS_MAX_BMBT_EXTLEN. The outer allocation loops handle
* short allocation just fine, so it is safe to do this. We only want to
* do it when we are forced to, though, because it means more allocation
* operations are required.
*/
- while (align_alen > MAXEXTLEN)
+ while (align_alen > XFS_MAX_BMBT_EXTLEN)
align_alen -= extsz;
- ASSERT(align_alen <= MAXEXTLEN);
+ ASSERT(align_alen <= XFS_MAX_BMBT_EXTLEN);
/*
* If the previous block overlaps with this proposed allocation
@@ -2995,9 +2995,9 @@ xfs_bmap_extsize_align(
return -EINVAL;
} else {
ASSERT(orig_off >= align_off);
- /* see MAXEXTLEN handling above */
+ /* see XFS_MAX_BMBT_EXTLEN handling above */
ASSERT(orig_end <= align_off + align_alen ||
- align_alen + extsz > MAXEXTLEN);
+ align_alen + extsz > XFS_MAX_BMBT_EXTLEN);
}
#ifdef DEBUG
@@ -3962,7 +3962,7 @@ xfs_bmapi_reserve_delalloc(
* Cap the alloc length. Keep track of prealloc so we know whether to
* tag the inode before we return.
*/
- alen = XFS_FILBLKS_MIN(len + prealloc, MAXEXTLEN);
+ alen = XFS_FILBLKS_MIN(len + prealloc, XFS_MAX_BMBT_EXTLEN);
if (!eof)
alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
if (prealloc && alen >= len)
@@ -4095,7 +4095,7 @@ xfs_bmapi_allocate(
if (!xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev))
bma->prev.br_startoff = NULLFILEOFF;
} else {
- bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN);
+ bma->length = XFS_FILBLKS_MIN(bma->length, XFS_MAX_BMBT_EXTLEN);
if (!bma->eof)
bma->length = XFS_FILBLKS_MIN(bma->length,
bma->got.br_startoff - bma->offset);
@@ -4415,8 +4415,8 @@ xfs_bmapi_write(
* xfs_extlen_t and therefore 32 bits. Hence we have to
* check for 32-bit overflows and handle them here.
*/
- if (len > (xfs_filblks_t)MAXEXTLEN)
- bma.length = MAXEXTLEN;
+ if (len > (xfs_filblks_t)XFS_MAX_BMBT_EXTLEN)
+ bma.length = XFS_MAX_BMBT_EXTLEN;
else
bma.length = len;
@@ -4551,7 +4551,8 @@ xfs_bmapi_convert_delalloc(
bma.ip = ip;
bma.wasdel = true;
bma.offset = bma.got.br_startoff;
- bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN);
+ bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount,
+ XFS_MAX_BMBT_EXTLEN);
bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
/*
@@ -4632,7 +4633,7 @@ xfs_bmapi_remap(
ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT(len > 0);
- ASSERT(len <= (xfs_filblks_t)MAXEXTLEN);
+ ASSERT(len <= (xfs_filblks_t)XFS_MAX_BMBT_EXTLEN);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC |
XFS_BMAPI_NORMAP)));
@@ -5632,7 +5633,7 @@ xfs_bmse_can_merge(
if ((left->br_startoff + left->br_blockcount != startoff) ||
(left->br_startblock + left->br_blockcount != got->br_startblock) ||
(left->br_state != got->br_state) ||
- (left->br_blockcount + got->br_blockcount > MAXEXTLEN))
+ (left->br_blockcount + got->br_blockcount > XFS_MAX_BMBT_EXTLEN))
return false;
return true;
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index b7521c1d..fa11e4c1 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -886,7 +886,7 @@ enum xfs_dinode_fmt {
{ XFS_DINODE_FMT_UUID, "uuid" }
/*
- * Max values for extlen, extnum, aextnum.
+ * Max values for ondisk inode's extent counters.
*
* The newly introduced data fork extent counter is a 64-bit field. However, the
* maximum number of extents in a file is limited to 2^54 extents (assuming one
@@ -898,7 +898,6 @@ enum xfs_dinode_fmt {
* Rounding up 47 to the nearest multiple of bits-per-byte results in 48. Hence
* 2^48 was chosen as the maximum data fork extent count.
*/
-#define MAXEXTLEN ((xfs_extlen_t)((1ULL << 21) - 1)) /* 21 bits */
#define XFS_MAX_EXTCNT_DATA_FORK ((xfs_extnum_t)((1ULL << 48) - 1)) /* Unsigned 48-bits */
#define XFS_MAX_EXTCNT_ATTR_FORK ((xfs_extnum_t)((1ULL << 32) - 1)) /* Unsigned 32-bits */
#define XFS_MAX_EXTCNT_DATA_FORK_OLD ((xfs_extnum_t)((1ULL << 31) - 1)) /* Signed 32-bits */
@@ -1635,6 +1634,8 @@ typedef struct xfs_bmdr_block {
#define BMBT_STARTOFF_MASK ((1ULL << BMBT_STARTOFF_BITLEN) - 1)
#define BMBT_BLOCKCOUNT_MASK ((1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
+#define XFS_MAX_BMBT_EXTLEN ((xfs_extlen_t)(BMBT_BLOCKCOUNT_MASK))
+
/*
* bmbt records have a file offset (block) field that is 54 bits wide, so this
* is the largest xfs_fileoff_t that we ever expect to see.
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 60feee8b..74bb682f 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -666,7 +666,7 @@ xfs_inode_validate_extsize(
if (extsize_bytes % blocksize_bytes)
return __this_address;
- if (extsize > MAXEXTLEN)
+ if (extsize > XFS_MAX_BMBT_EXTLEN)
return __this_address;
if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2)
@@ -723,7 +723,7 @@ xfs_inode_validate_cowextsize(
if (cowextsize_bytes % mp->m_sb.sb_blocksize)
return __this_address;
- if (cowextsize > MAXEXTLEN)
+ if (cowextsize > XFS_MAX_BMBT_EXTLEN)
return __this_address;
if (cowextsize > mp->m_sb.sb_agblocks / 2)
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
index 61a0a1ac..4759de1b 100644
--- a/libxfs/xfs_trans_resv.c
+++ b/libxfs/xfs_trans_resv.c
@@ -198,8 +198,8 @@ xfs_calc_inode_chunk_res(
/*
* Per-extent log reservation for the btree changes involved in freeing or
* allocating a realtime extent. We have to be able to log as many rtbitmap
- * blocks as needed to mark inuse MAXEXTLEN blocks' worth of realtime extents,
- * as well as the realtime summary block.
+ * blocks as needed to mark inuse XFS_MAX_BMBT_EXTLEN blocks' worth of realtime
+ * extents, as well as the realtime summary block.
*/
static unsigned int
xfs_rtalloc_log_count(
@@ -209,7 +209,7 @@ xfs_rtalloc_log_count(
unsigned int blksz = XFS_FSB_TO_B(mp, 1);
unsigned int rtbmp_bytes;
- rtbmp_bytes = (MAXEXTLEN / mp->m_sb.sb_rextsize) / NBBY;
+ rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY;
return (howmany(rtbmp_bytes, blksz) + 1) * num_ops;
}
@@ -246,7 +246,7 @@ xfs_rtalloc_log_count(
* the inode's bmap btree: max depth * block size
* the agfs of the ags from which the extents are allocated: 2 * sector
* the superblock free block counter: sector size
- * the realtime bitmap: ((MAXEXTLEN / rtextsize) / NBBY) bytes
+ * the realtime bitmap: ((XFS_MAX_BMBT_EXTLEN / rtextsize) / NBBY) bytes
* the realtime summary: 1 block
* the allocation btrees: 2 trees * (2 * max depth - 1) * block size
* And the bmap_finish transaction can free bmap blocks in a join (t3):
@@ -298,7 +298,7 @@ xfs_calc_write_reservation(
* the agf for each of the ags: 2 * sector size
* the agfl for each of the ags: 2 * sector size
* the super block to reflect the freed blocks: sector size
- * the realtime bitmap: 2 exts * ((MAXEXTLEN / rtextsize) / NBBY) bytes
+ * the realtime bitmap: 2 exts * ((XFS_MAX_BMBT_EXTLEN / rtextsize) / NBBY) bytes
* the realtime summary: 2 exts * 1 block
* worst case split in allocation btrees per extent assuming 2 extents:
* 2 exts * 2 trees * (2 * max depth - 1) * block size
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 28aca7b0..ca121a72 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2418,7 +2418,7 @@ validate_extsize_hint(
fprintf(stderr,
_("illegal extent size hint %lld, must be less than %u.\n"),
(long long)cli->fsx.fsx_extsize,
- min(MAXEXTLEN, mp->m_sb.sb_agblocks / 2));
+ min(XFS_MAX_BMBT_EXTLEN, mp->m_sb.sb_agblocks / 2));
usage();
}
@@ -2441,7 +2441,7 @@ _("illegal extent size hint %lld, must be less than %u.\n"),
fprintf(stderr,
_("illegal extent size hint %lld, must be less than %u and a multiple of %u.\n"),
(long long)cli->fsx.fsx_extsize,
- min(MAXEXTLEN, mp->m_sb.sb_agblocks / 2),
+ min(XFS_MAX_BMBT_EXTLEN, mp->m_sb.sb_agblocks / 2),
mp->m_sb.sb_rextsize);
usage();
}
@@ -2470,7 +2470,7 @@ validate_cowextsize_hint(
fprintf(stderr,
_("illegal CoW extent size hint %lld, must be less than %u.\n"),
(long long)cli->fsx.fsx_cowextsize,
- min(MAXEXTLEN, mp->m_sb.sb_agblocks / 2));
+ min(XFS_MAX_BMBT_EXTLEN, mp->m_sb.sb_agblocks / 2));
usage();
}
}
diff --git a/repair/phase4.c b/repair/phase4.c
index 2260f6a3..292f55b7 100644
--- a/repair/phase4.c
+++ b/repair/phase4.c
@@ -372,7 +372,7 @@ phase4(xfs_mount_t *mp)
if (rt_start == 0) {
rt_start = bno;
rt_len = 1;
- } else if (rt_len == MAXEXTLEN) {
+ } else if (rt_len == XFS_MAX_BMBT_EXTLEN) {
/*
* large extent case
*/
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V5 18/20] xfsprogs: Add mkfs option to create filesystem with large extent counters
2022-01-21 5:20 ` [PATCH V5 18/20] xfsprogs: Add mkfs option to create filesystem with large extent counters Chandan Babu R
@ 2022-01-25 0:33 ` Darrick J. Wong
0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2022-01-25 0:33 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, david
> xfsprogs: Add mkfs option to create filesystem with large extent
> counters
This ought to be shorter and more direct about this being an mkfs
patch:
"mkfs: add option to create filesystem with large extent counters"
On Fri, Jan 21, 2022 at 10:50:17AM +0530, Chandan Babu R wrote:
> Enabling nrext64 option on mkfs.xfs command line extends the maximum values of
> inode data and attr fork extent counters to 2^48 - 1 and 2^32 - 1
> respectively. This also sets the XFS_SB_FEAT_INCOMPAT_NREXT64 incompat flag
> on the superblock preventing older kernels from mounting such a filesystem.
>
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
> man/man8/mkfs.xfs.8.in | 7 +++++++
> mkfs/lts_4.19.conf | 1 +
> mkfs/lts_5.10.conf | 1 +
> mkfs/lts_5.15.conf | 1 +
> mkfs/lts_5.4.conf | 1 +
> mkfs/xfs_mkfs.c | 23 +++++++++++++++++++++++
> 6 files changed, 34 insertions(+)
>
> diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
> index a3526753..7d764f19 100644
> --- a/man/man8/mkfs.xfs.8.in
> +++ b/man/man8/mkfs.xfs.8.in
> @@ -647,6 +647,13 @@ space over time such that no free extents are large enough to
> accommodate a chunk of 64 inodes. Without this feature enabled, inode
> allocations can fail with out of space errors under severe fragmented
> free space conditions.
> +.TP
> +.BI nrext64[= value]
> +Extend maximum values of inode data and attr fork extent counters from 2^31 -
> +1 and 2^15 - 1 to 2^48 - 1 and 2^32 - 1 respectively. If the value is
> +omitted, 1 is assumed. This feature is disabled by default. This feature is
> +only available for filesystems formatted with -m crc=1.
> +.TP
> .RE
> .PP
> .PD 0
> diff --git a/mkfs/lts_4.19.conf b/mkfs/lts_4.19.conf
> index d21fcb7e..751be45e 100644
> --- a/mkfs/lts_4.19.conf
> +++ b/mkfs/lts_4.19.conf
> @@ -2,6 +2,7 @@
> # kernel was released at the end of 2018.
>
> [metadata]
> +nrext64=0
> bigtime=0
> crc=1
> finobt=1
> diff --git a/mkfs/lts_5.10.conf b/mkfs/lts_5.10.conf
> index ac00960e..a1c991ce 100644
> --- a/mkfs/lts_5.10.conf
> +++ b/mkfs/lts_5.10.conf
> @@ -2,6 +2,7 @@
> # kernel was released at the end of 2020.
>
> [metadata]
> +nrext64=0
> bigtime=0
> crc=1
> finobt=1
> diff --git a/mkfs/lts_5.15.conf b/mkfs/lts_5.15.conf
> index 32082958..d751f4c4 100644
> --- a/mkfs/lts_5.15.conf
> +++ b/mkfs/lts_5.15.conf
> @@ -2,6 +2,7 @@
> # kernel was released at the end of 2021.
>
> [metadata]
> +nrext64=0
> bigtime=1
> crc=1
> finobt=1
> diff --git a/mkfs/lts_5.4.conf b/mkfs/lts_5.4.conf
> index dd60b9f1..7e8a0ff0 100644
> --- a/mkfs/lts_5.4.conf
> +++ b/mkfs/lts_5.4.conf
> @@ -2,6 +2,7 @@
> # kernel was released at the end of 2019.
>
> [metadata]
> +nrext64=0
> bigtime=0
> crc=1
> finobt=1
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 96682f9a..28aca7b0 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -79,6 +79,7 @@ enum {
> I_ATTR,
> I_PROJID32BIT,
> I_SPINODES,
> + I_NREXT64,
> I_MAX_OPTS,
> };
>
> @@ -433,6 +434,7 @@ static struct opt_params iopts = {
> [I_ATTR] = "attr",
> [I_PROJID32BIT] = "projid32bit",
> [I_SPINODES] = "sparse",
> + [I_NREXT64] = "nrext64",
> },
> .subopt_params = {
> { .index = I_ALIGN,
> @@ -481,6 +483,12 @@ static struct opt_params iopts = {
> .maxval = 1,
> .defaultval = 1,
> },
> + { .index = I_NREXT64,
> + .conflicts = { { NULL, LAST_CONFLICT } },
> + .minval = 0,
> + .maxval = 1,
> + .defaultval = 1,
> + }
> },
> };
>
> @@ -805,6 +813,7 @@ struct sb_feat_args {
> bool bigtime; /* XFS_SB_FEAT_INCOMPAT_BIGTIME */
> bool nodalign;
> bool nortalign;
> + bool nrext64;
> };
>
> struct cli_params {
> @@ -1595,6 +1604,9 @@ inode_opts_parser(
> case I_SPINODES:
> cli->sb_feat.spinodes = getnum(value, opts, subopt);
> break;
> + case I_NREXT64:
> + cli->sb_feat.nrext64 = getnum(value, opts, subopt);
> + break;
> default:
> return -EINVAL;
> }
> @@ -2172,6 +2184,14 @@ _("timestamps later than 2038 not supported without CRC support\n"));
> usage();
> }
> cli->sb_feat.bigtime = false;
> +
> + if (cli->sb_feat.nrext64 &&
> + cli_opt_set(&iopts, I_NREXT64)) {
> + fprintf(stderr,
Nit: second line of if test has the same indentation level as the first
line of the if body.
With those two things fixed,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> +_("64 bit extent count not supported without CRC support\n"));
> + usage();
> + }
> + cli->sb_feat.nrext64 = false;
> }
>
> if (!cli->sb_feat.finobt) {
> @@ -3164,6 +3184,8 @@ sb_set_features(
> sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
> }
>
> + if (fp->nrext64)
> + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
> }
>
> /*
> @@ -3875,6 +3897,7 @@ main(
> .nodalign = false,
> .nortalign = false,
> .bigtime = true,
> + .nrext64 = false,
> /*
> * When we decide to enable a new feature by default,
> * please remember to update the mkfs conf files.
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V5 19/20] xfsprogs: Add support for upgrading to NREXT64 feature
2022-01-21 5:20 ` [PATCH V5 19/20] xfsprogs: Add support for upgrading to NREXT64 feature Chandan Babu R
@ 2022-01-25 0:35 ` Darrick J. Wong
0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2022-01-25 0:35 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, david
> xfsprogs: Add support for upgrading to NREXT64 feature
Please shorten the subject line of this patch as well:
"xfs_repair: add suppport for upgrading to nrext64 feature"
On Fri, Jan 21, 2022 at 10:50:18AM +0530, Chandan Babu R wrote:
> This commit adds support to xfs_repair to allow upgrading an existing
> filesystem to support per-inode large extent counters.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
> man/man8/xfs_admin.8 | 7 +++++++
> repair/globals.c | 1 +
> repair/globals.h | 1 +
> repair/phase2.c | 24 ++++++++++++++++++++++++
> repair/xfs_repair.c | 11 +++++++++++
> 5 files changed, 44 insertions(+)
>
> diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8
> index ad28e0f6..d64ed45b 100644
> --- a/man/man8/xfs_admin.8
> +++ b/man/man8/xfs_admin.8
> @@ -149,6 +149,13 @@ Upgrade a filesystem to support larger timestamps up to the year 2486.
> 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.10.
> +.TP 0.4i
> +.B nrext64
> +Upgrade a filesystem to support large per-inode extent counters. Maximum data
Nit: sentence needs an article, e.g.
"The maximum data fork extent count..."
With that fixed,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> +fork extent count will be 2^48 while the maximum attribute fork extent count
> +will be 2^32. 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.18.
> .RE
> .TP
> .BI \-U " uuid"
> diff --git a/repair/globals.c b/repair/globals.c
> index f8d4f1e4..c4084985 100644
> --- a/repair/globals.c
> +++ b/repair/globals.c
> @@ -51,6 +51,7 @@ int lazy_count; /* What to set if to if converting */
> 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;
>
> /* misc status variables */
>
> diff --git a/repair/globals.h b/repair/globals.h
> index 0f98bd2b..b65e4a2d 100644
> --- a/repair/globals.h
> +++ b/repair/globals.h
> @@ -92,6 +92,7 @@ extern int lazy_count; /* What to set if to if converting */
> 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;
>
> /* misc status variables */
>
> diff --git a/repair/phase2.c b/repair/phase2.c
> index 4c315055..979e281d 100644
> --- a/repair/phase2.c
> +++ b/repair/phase2.c
> @@ -181,6 +181,28 @@ set_bigtime(
> return true;
> }
>
> +static bool
> +set_nrext64(
> + struct xfs_mount *mp,
> + struct xfs_sb *new_sb)
> +{
> + if (!xfs_has_crc(mp)) {
> + printf(
> + _("Nrext64 only supported on V5 filesystems.\n"));
> + exit(0);
> + }
> +
> + if (xfs_has_nrext64(mp)) {
> + printf(_("Filesystem already supports nrext64.\n"));
> + exit(0);
> + }
> +
> + printf(_("Adding nrext64 to filesystem.\n"));
> + new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
> + new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
> + return true;
> +}
> +
> struct check_state {
> struct xfs_sb sb;
> uint64_t features;
> @@ -380,6 +402,8 @@ upgrade_filesystem(
> dirty |= set_inobtcount(mp, &new_sb);
> if (add_bigtime)
> dirty |= set_bigtime(mp, &new_sb);
> + if (add_nrext64)
> + dirty |= set_nrext64(mp, &new_sb);
> if (!dirty)
> return;
>
> diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
> index de8617ba..c4705cf2 100644
> --- a/repair/xfs_repair.c
> +++ b/repair/xfs_repair.c
> @@ -67,6 +67,7 @@ enum c_opt_nums {
> CONVERT_LAZY_COUNT = 0,
> CONVERT_INOBTCOUNT,
> CONVERT_BIGTIME,
> + CONVERT_NREXT64,
> C_MAX_OPTS,
> };
>
> @@ -74,6 +75,7 @@ static char *c_opts[] = {
> [CONVERT_LAZY_COUNT] = "lazycount",
> [CONVERT_INOBTCOUNT] = "inobtcount",
> [CONVERT_BIGTIME] = "bigtime",
> + [CONVERT_NREXT64] = "nrext64",
> [C_MAX_OPTS] = NULL,
> };
>
> @@ -324,6 +326,15 @@ process_args(int argc, char **argv)
> _("-c bigtime only supports upgrades\n"));
> add_bigtime = true;
> break;
> + case CONVERT_NREXT64:
> + if (!val)
> + do_abort(
> + _("-c nrext64 requires a parameter\n"));
> + if (strtol(val, NULL, 0) != 1)
> + do_abort(
> + _("-c nrext64 only supports upgrades\n"));
> + add_nrext64 = true;
> + break;
> default:
> unknown('c', val);
> break;
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V5 15/20] xfsprogs: Enable bulkstat ioctl to support 64-bit extent counters
2022-01-21 5:20 ` [PATCH V5 15/20] xfsprogs: Enable bulkstat ioctl to support " Chandan Babu R
@ 2022-02-01 19:29 ` Darrick J. Wong
0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2022-02-01 19:29 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, david
On Fri, Jan 21, 2022 at 10:50:14AM +0530, Chandan Babu R wrote:
> This commit adds support to libfrog to enable reporting 64-bit extent counters
> to its users. In order to do so, bulkstat ioctl is now invoked with the newly
> introduced XFS_BULK_IREQ_NREXT64 flag if the underlying filesystem's geometry
> supports 64-bit extent counters.
>
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
> fsr/xfs_fsr.c | 4 ++--
> io/bulkstat.c | 1 +
> libfrog/bulkstat.c | 29 +++++++++++++++++++++++++++--
> libxfs/xfs_fs.h | 12 ++++++++----
On second thought: While you're adding comments to the definition of
XFS_BULK_IREQ_NREXT64 in xfs_fs.h, can you please update
man/man2/ioctl_xfs_bulkstat.2 as well?
--D
> 4 files changed, 38 insertions(+), 8 deletions(-)
>
> diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
> index 6cf8bfb7..ba02506d 100644
> --- a/fsr/xfs_fsr.c
> +++ b/fsr/xfs_fsr.c
> @@ -590,7 +590,7 @@ cmp(const void *s1, const void *s2)
> (bs1->bs_version == XFS_BULKSTAT_VERSION_V5 &&
> bs2->bs_version == XFS_BULKSTAT_VERSION_V5));
>
> - return (bs2->bs_extents - bs1->bs_extents);
> + return (bs2->bs_extents64 - bs1->bs_extents64);
> }
>
> /*
> @@ -655,7 +655,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
> for (p = buf, endp = (buf + buflenout); p < endp ; p++) {
> /* Do some obvious checks now */
> if (((p->bs_mode & S_IFMT) != S_IFREG) ||
> - (p->bs_extents < 2))
> + (p->bs_extents64 < 2))
> continue;
>
> ret = -xfrog_bulkstat_v5_to_v1(&fsxfd, &bs1, p);
> diff --git a/io/bulkstat.c b/io/bulkstat.c
> index 201470b2..0c9a2b02 100644
> --- a/io/bulkstat.c
> +++ b/io/bulkstat.c
> @@ -57,6 +57,7 @@ dump_bulkstat(
> printf("\tbs_sick = 0x%"PRIx16"\n", bstat->bs_sick);
> printf("\tbs_checked = 0x%"PRIx16"\n", bstat->bs_checked);
> printf("\tbs_mode = 0%"PRIo16"\n", bstat->bs_mode);
> + printf("\tbs_extents64 = %"PRIu64"\n", bstat->bs_extents64);
> };
>
> static void
> diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
> index 195f6ea0..0a90947f 100644
> --- a/libfrog/bulkstat.c
> +++ b/libfrog/bulkstat.c
> @@ -56,6 +56,9 @@ xfrog_bulkstat_single5(
> if (flags & ~(XFS_BULK_IREQ_SPECIAL))
> return -EINVAL;
>
> + if (xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)
> + flags |= XFS_BULK_IREQ_NREXT64;
> +
> ret = xfrog_bulkstat_alloc_req(1, ino, &req);
> if (ret)
> return ret;
> @@ -73,6 +76,12 @@ xfrog_bulkstat_single5(
> }
>
> memcpy(bulkstat, req->bulkstat, sizeof(struct xfs_bulkstat));
> +
> + if (!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)) {
> + bulkstat->bs_extents64 = bulkstat->bs_extents;
> + bulkstat->bs_extents = 0;
> + }
> +
> free:
> free(req);
> return ret;
> @@ -129,6 +138,7 @@ xfrog_bulkstat_single(
> switch (error) {
> case -EOPNOTSUPP:
> case -ENOTTY:
> + assert(!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64));
> xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
> break;
> }
> @@ -259,10 +269,23 @@ xfrog_bulkstat5(
> struct xfs_bulkstat_req *req)
> {
> int ret;
> + int i;
> +
> + if (xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)
> + req->hdr.flags |= XFS_BULK_IREQ_NREXT64;
>
> ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT, req);
> if (ret)
> return -errno;
> +
> + if (!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64)) {
> + for (i = 0; i < req->hdr.ocount; i++) {
> + req->bulkstat[i].bs_extents64 =
> + req->bulkstat[i].bs_extents;
> + req->bulkstat[i].bs_extents = 0;
> + }
> + }
> +
> return 0;
> }
>
> @@ -316,6 +339,7 @@ xfrog_bulkstat(
> switch (error) {
> case -EOPNOTSUPP:
> case -ENOTTY:
> + assert(!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64));
> xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
> break;
> }
> @@ -342,6 +366,7 @@ xfrog_bulkstat_v5_to_v1(
> const struct xfs_bulkstat *bs5)
> {
> if (bs5->bs_aextents > UINT16_MAX ||
> + bs5->bs_extents64 > INT32_MAX ||
> cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks) > UINT32_MAX ||
> cvt_off_fsb_to_b(xfd, bs5->bs_cowextsize_blks) > UINT32_MAX ||
> time_too_big(bs5->bs_atime) ||
> @@ -366,7 +391,7 @@ xfrog_bulkstat_v5_to_v1(
> bs1->bs_blocks = bs5->bs_blocks;
> bs1->bs_xflags = bs5->bs_xflags;
> bs1->bs_extsize = cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks);
> - bs1->bs_extents = bs5->bs_extents;
> + bs1->bs_extents = bs5->bs_extents64;
> bs1->bs_gen = bs5->bs_gen;
> bs1->bs_projid_lo = bs5->bs_projectid & 0xFFFF;
> bs1->bs_forkoff = bs5->bs_forkoff;
> @@ -407,7 +432,6 @@ xfrog_bulkstat_v1_to_v5(
> bs5->bs_blocks = bs1->bs_blocks;
> bs5->bs_xflags = bs1->bs_xflags;
> bs5->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
> - bs5->bs_extents = bs1->bs_extents;
> bs5->bs_gen = bs1->bs_gen;
> bs5->bs_projectid = bstat_get_projid(bs1);
> bs5->bs_forkoff = bs1->bs_forkoff;
> @@ -415,6 +439,7 @@ xfrog_bulkstat_v1_to_v5(
> bs5->bs_checked = bs1->bs_checked;
> bs5->bs_cowextsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_cowextsize);
> bs5->bs_aextents = bs1->bs_aextents;
> + bs5->bs_extents64 = bs1->bs_extents;
> }
>
> /* Allocate a bulkstat request. Returns zero or a negative error code. */
> diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
> index 42bc3950..f65bf2da 100644
> --- a/libxfs/xfs_fs.h
> +++ b/libxfs/xfs_fs.h
> @@ -393,7 +393,7 @@ struct xfs_bulkstat {
> uint32_t bs_extsize_blks; /* extent size hint, blocks */
>
> uint32_t bs_nlink; /* number of links */
> - uint32_t bs_extents; /* number of extents */
> + uint32_t bs_extents; /* 32-bit data fork extent counter */
> uint32_t bs_aextents; /* attribute number of extents */
> uint16_t bs_version; /* structure version */
> uint16_t bs_forkoff; /* inode fork offset in bytes */
> @@ -402,8 +402,9 @@ struct xfs_bulkstat {
> uint16_t bs_checked; /* checked inode metadata */
> uint16_t bs_mode; /* type and mode */
> uint16_t bs_pad2; /* zeroed */
> + uint64_t bs_extents64; /* 64-bit data fork extent counter */
>
> - uint64_t bs_pad[7]; /* zeroed */
> + uint64_t bs_pad[6]; /* zeroed */
> };
>
> #define XFS_BULKSTAT_VERSION_V1 (1)
> @@ -484,8 +485,11 @@ struct xfs_bulk_ireq {
> */
> #define XFS_BULK_IREQ_SPECIAL (1 << 1)
>
> -#define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO | \
> - XFS_BULK_IREQ_SPECIAL)
> +#define XFS_BULK_IREQ_NREXT64 (1 << 3)
> +
> +#define XFS_BULK_IREQ_FLAGS_ALL (XFS_BULK_IREQ_AGNO | \
> + XFS_BULK_IREQ_SPECIAL | \
> + XFS_BULK_IREQ_NREXT64)
>
> /* Operate on the root directory inode. */
> #define XFS_BULK_IREQ_SPECIAL_ROOT (1)
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2022-02-01 19:29 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-21 5:19 [PATCH V5 00/20] xfsprogs: Extend per-inode extent counters Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 01/20] xfs_repair: check filesystem geometry before allowing upgrades Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 02/20] xfsprogs: Move extent count limits to xfs_format.h Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 03/20] xfsprogs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 04/20] xfsprogs: Use xfs_extnum_t instead of basic data types Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 05/20] xfsprogs: Introduce xfs_dfork_nextents() helper Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 06/20] xfsprogs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 07/20] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 08/20] xfsprogs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 09/20] xfsprogs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 10/20] xfsprogs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 11/20] xfsprogs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 12/20] xfsprogs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 13/20] xfsprogs: Introduce per-inode 64-bit extent counters Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 14/20] xfsprogs: Conditionally upgrade existing inodes to use " Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 15/20] xfsprogs: Enable bulkstat ioctl to support " Chandan Babu R
2022-02-01 19:29 ` Darrick J. Wong
2022-01-21 5:20 ` [PATCH V5 16/20] xfsprogs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 17/20] xfsprogs: xfs_info: Report NREXT64 feature status Chandan Babu R
2022-01-21 5:20 ` [PATCH V5 18/20] xfsprogs: Add mkfs option to create filesystem with large extent counters Chandan Babu R
2022-01-25 0:33 ` Darrick J. Wong
2022-01-21 5:20 ` [PATCH V5 19/20] xfsprogs: Add support for upgrading to NREXT64 feature Chandan Babu R
2022-01-25 0:35 ` Darrick J. Wong
2022-01-21 5:20 ` [PATCH V5 20/20] xfsprogs: Define max extent length based on on-disk format definition Chandan Babu R
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.