* [PATCH 1/7] xfs: store inode btree block counts in AGI header
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
2020-08-17 22:58 ` [PATCH 2/7] xfs_db: support displaying " Darrick J. Wong
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Add a btree block usage counter for both inode btrees to the AGI header
so that we don't have to walk the entire finobt at mount time to create
the per-AG reservations.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
libxfs/xfs_ag.c | 4 ++
libxfs/xfs_format.h | 19 ++++++++++-
libxfs/xfs_ialloc.c | 1 +
libxfs/xfs_ialloc_btree.c | 78 +++++++++++++++++++++++++++++++++++++++++----
4 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index ceaa7e5e4640..38c3acd8d990 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -333,6 +333,10 @@ xfs_agiblock_init(
}
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ agi->agi_iblocks = cpu_to_be32(1);
+ agi->agi_fblocks = cpu_to_be32(1);
+ }
}
typedef void (*aghdr_init_work_f)(struct xfs_mount *mp, struct xfs_buf *bp,
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index d14fee3e3ac2..67357622e5e5 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -449,6 +449,7 @@ xfs_sb_has_compat_feature(
#define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */
#define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */
#define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */
+#define XFS_SB_FEAT_RO_COMPAT_INOBTCNT (1 << 3) /* inobt block counts */
#define XFS_SB_FEAT_RO_COMPAT_ALL \
(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
@@ -563,6 +564,18 @@ static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp)
(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK);
}
+/*
+ * Inode btree block counter. We record the number of inobt and finobt blocks
+ * in the AGI header so that we can skip the finobt walk at mount time when
+ * setting up per-AG reservations. Since this is mostly an optimization of an
+ * existing feature, we only enable it when that feature is also enabled.
+ */
+static inline bool xfs_sb_version_hasinobtcounts(struct xfs_sb *sbp)
+{
+ return xfs_sb_version_hasfinobt(sbp) &&
+ (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_INOBTCNT);
+}
+
/*
* end of superblock version macros
*/
@@ -765,6 +778,9 @@ typedef struct xfs_agi {
__be32 agi_free_root; /* root of the free inode btree */
__be32 agi_free_level;/* levels in free inode btree */
+ __be32 agi_iblocks; /* inobt blocks used */
+ __be32 agi_fblocks; /* finobt blocks used */
+
/* structure must be padded to 64 bit alignment */
} xfs_agi_t;
@@ -785,7 +801,8 @@ typedef struct xfs_agi {
#define XFS_AGI_ALL_BITS_R1 ((1 << XFS_AGI_NUM_BITS_R1) - 1)
#define XFS_AGI_FREE_ROOT (1 << 11)
#define XFS_AGI_FREE_LEVEL (1 << 12)
-#define XFS_AGI_NUM_BITS_R2 13
+#define XFS_AGI_IBLOCKS (1 << 13) /* both inobt/finobt block counters */
+#define XFS_AGI_NUM_BITS_R2 14
/* disk block (xfs_daddr_t) in the AG */
#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 1d5bb668c9f9..45bbbb321118 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -2512,6 +2512,7 @@ xfs_ialloc_log_agi(
offsetof(xfs_agi_t, agi_unlinked),
offsetof(xfs_agi_t, agi_free_root),
offsetof(xfs_agi_t, agi_free_level),
+ offsetof(xfs_agi_t, agi_iblocks),
sizeof(xfs_agi_t)
};
#ifdef DEBUG
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index e73ffffede4d..6df4afb4e138 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -66,6 +66,25 @@ xfs_finobt_set_root(
XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL);
}
+/* Update the inode btree block counter for this btree. */
+static inline void
+xfs_inobt_change_blocks(
+ struct xfs_btree_cur *cur,
+ int howmuch)
+{
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
+ struct xfs_agi *agi = agbp->b_addr;
+
+ if (!xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb))
+ return;
+
+ if (cur->bc_btnum == XFS_BTNUM_FINO)
+ be32_add_cpu(&agi->agi_fblocks, howmuch);
+ else
+ be32_add_cpu(&agi->agi_iblocks, howmuch);
+ xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_IBLOCKS);
+}
+
STATIC int
__xfs_inobt_alloc_block(
struct xfs_btree_cur *cur,
@@ -101,6 +120,7 @@ __xfs_inobt_alloc_block(
new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno));
*stat = 1;
+ xfs_inobt_change_blocks(cur, 1);
return 0;
}
@@ -121,10 +141,17 @@ xfs_finobt_alloc_block(
union xfs_btree_ptr *new,
int *stat)
{
+ int error;
+
if (cur->bc_mp->m_finobt_nores)
- return xfs_inobt_alloc_block(cur, start, new, stat);
- return __xfs_inobt_alloc_block(cur, start, new, stat,
- XFS_AG_RESV_METADATA);
+ error = xfs_inobt_alloc_block(cur, start, new, stat);
+ else
+ error = __xfs_inobt_alloc_block(cur, start, new, stat,
+ XFS_AG_RESV_METADATA);
+ if (error)
+ return error;
+
+ return 0;
}
STATIC int
@@ -133,6 +160,7 @@ __xfs_inobt_free_block(
struct xfs_buf *bp,
enum xfs_ag_resv_type resv)
{
+ xfs_inobt_change_blocks(cur, -1);
return xfs_free_extent(cur->bc_tp,
XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1,
&XFS_RMAP_OINFO_INOBT, resv);
@@ -479,19 +507,29 @@ xfs_inobt_commit_staged_btree(
{
struct xfs_agi *agi = agbp->b_addr;
struct xbtree_afakeroot *afake = cur->bc_ag.afake;
+ int fields;
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
if (cur->bc_btnum == XFS_BTNUM_INO) {
+ fields = XFS_AGI_ROOT | XFS_AGI_LEVEL;
agi->agi_root = cpu_to_be32(afake->af_root);
agi->agi_level = cpu_to_be32(afake->af_levels);
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL);
+ if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) {
+ agi->agi_iblocks = cpu_to_be32(afake->af_blocks);
+ fields |= XFS_AGI_IBLOCKS;
+ }
+ xfs_ialloc_log_agi(tp, agbp, fields);
xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_inobt_ops);
} else {
+ fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL;
agi->agi_free_root = cpu_to_be32(afake->af_root);
agi->agi_free_level = cpu_to_be32(afake->af_levels);
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREE_ROOT |
- XFS_AGI_FREE_LEVEL);
+ if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) {
+ agi->agi_fblocks = cpu_to_be32(afake->af_blocks);
+ fields |= XFS_AGI_IBLOCKS;
+ }
+ xfs_ialloc_log_agi(tp, agbp, fields);
xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_finobt_ops);
}
}
@@ -672,6 +710,28 @@ xfs_inobt_count_blocks(
return error;
}
+/* Read finobt block count from AGI header. */
+static int
+xfs_finobt_read_blocks(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ xfs_agnumber_t agno,
+ xfs_extlen_t *tree_blocks)
+{
+ struct xfs_buf *agbp;
+ struct xfs_agi *agi;
+ int error;
+
+ error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
+ if (error)
+ return error;
+
+ agi = agbp->b_addr;
+ *tree_blocks = be32_to_cpu(agi->agi_fblocks);
+ xfs_trans_brelse(tp, agbp);
+ return 0;
+}
+
/*
* Figure out how many blocks to reserve and how many are used by this btree.
*/
@@ -689,7 +749,11 @@ xfs_finobt_calc_reserves(
if (!xfs_sb_version_hasfinobt(&mp->m_sb))
return 0;
- error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len);
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb))
+ error = xfs_finobt_read_blocks(mp, tp, agno, &tree_len);
+ else
+ error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO,
+ &tree_len);
if (error)
return error;
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/7] xfs_db: support displaying inode btree block counts in AGI header
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
2020-08-17 22:58 ` [PATCH 1/7] xfs: store inode btree block counts in " Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
2020-08-17 22:58 ` [PATCH 3/7] xfs_db: add bigtime upgrade path Darrick J. Wong
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Fix up xfs_db to support displaying the btree block counts.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
db/agi.c | 2 ++
db/sb.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/db/agi.c b/db/agi.c
index bf21b2d40f04..cfb4f7b8528a 100644
--- a/db/agi.c
+++ b/db/agi.c
@@ -48,6 +48,8 @@ const field_t agi_flds[] = {
{ "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE },
{ "free_root", FLDT_AGBLOCK, OI(OFF(free_root)), C1, 0, TYP_FINOBT },
{ "free_level", FLDT_UINT32D, OI(OFF(free_level)), C1, 0, TYP_NONE },
+ { "ino_blocks", FLDT_UINT32D, OI(OFF(iblocks)), C1, 0, TYP_NONE },
+ { "fino_blocks", FLDT_UINT32D, OI(OFF(fblocks)), C1, 0, TYP_NONE },
{ NULL }
};
diff --git a/db/sb.c b/db/sb.c
index 8a303422b427..e3b1fe0b2e6e 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -687,6 +687,8 @@ version_string(
strcat(s, ",RMAPBT");
if (xfs_sb_version_hasreflink(sbp))
strcat(s, ",REFLINK");
+ if (xfs_sb_version_hasinobtcounts(sbp))
+ strcat(s, ",INOBTCNT");
return s;
}
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/7] xfs_db: add bigtime upgrade path
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
2020-08-17 22:58 ` [PATCH 1/7] xfs: store inode btree block counts in " Darrick J. Wong
2020-08-17 22:58 ` [PATCH 2/7] xfs_db: support displaying " Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
2020-08-18 14:14 ` Amir Goldstein
2020-08-17 22:58 ` [PATCH 4/7] xfs_repair: check inode btree block counters in AGI Darrick J. Wong
` (3 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Enable users to upgrade their filesystems to bigtime support.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
db/sb.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++-
db/xfs_admin.sh | 4 ++-
man/man8/xfs_admin.8 | 16 +++++++++++
3 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/db/sb.c b/db/sb.c
index e3b1fe0b2e6e..33d9f7df49bb 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -620,6 +620,44 @@ do_version(xfs_agnumber_t agno, uint16_t version, uint32_t features)
return 1;
}
+/* Add new V5 features to the filesystem. */
+static bool
+add_v5_features(
+ struct xfs_mount *mp,
+ uint32_t compat,
+ uint32_t ro_compat,
+ uint32_t incompat,
+ uint32_t log_incompat)
+{
+ struct xfs_sb tsb;
+ xfs_agnumber_t agno;
+
+ dbprintf(_("Upgrading V5 filesystem\n"));
+ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
+ if (!get_sb(agno, &tsb))
+ break;
+
+ tsb.sb_features_compat |= compat;
+ tsb.sb_features_ro_compat |= ro_compat;
+ tsb.sb_features_incompat |= incompat;
+ tsb.sb_features_log_incompat |= log_incompat;
+ libxfs_sb_to_disk(iocur_top->data, &tsb);
+ write_cur();
+ }
+
+ if (agno != mp->m_sb.sb_agcount) {
+ dbprintf(
+_("Failed to upgrade V5 filesystem AG %d\n"), agno);
+ return false;
+ }
+
+ mp->m_sb.sb_features_compat |= compat;
+ mp->m_sb.sb_features_ro_compat |= ro_compat;
+ mp->m_sb.sb_features_incompat |= incompat;
+ mp->m_sb.sb_features_log_incompat |= log_incompat;
+ return true;
+}
+
static char *
version_string(
xfs_sb_t *sbp)
@@ -705,6 +743,10 @@ version_f(
{
uint16_t version = 0;
uint32_t features = 0;
+ uint32_t upgrade_compat = 0;
+ uint32_t upgrade_ro_compat = 0;
+ uint32_t upgrade_incompat = 0;
+ uint32_t upgrade_log_incompat = 0;
xfs_agnumber_t ag;
if (argc == 2) { /* WRITE VERSION */
@@ -716,7 +758,25 @@ version_f(
}
/* Logic here derived from the IRIX xfs_chver(1M) script. */
- if (!strcasecmp(argv[1], "extflg")) {
+ if (!strcasecmp(argv[1], "inobtcount")) {
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ dbprintf(
+ _("inode btree counter feature is already enabled\n"));
+ return 0;
+ }
+ if (!xfs_sb_version_hasfinobt(&mp->m_sb)) {
+ dbprintf(
+ _("inode btree counter feature cannot be enabled on filesystems lacking free inode btrees\n"));
+ return 0;
+ }
+ if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+ dbprintf(
+ _("inode btree counter feature cannot be enabled on pre-V5 filesystems\n"));
+ return 0;
+ }
+
+ upgrade_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+ } else if (!strcasecmp(argv[1], "extflg")) {
switch (XFS_SB_VERSION_NUM(&mp->m_sb)) {
case XFS_SB_VERSION_1:
version = 0x0004 | XFS_SB_VERSION_EXTFLGBIT;
@@ -807,6 +867,17 @@ version_f(
mp->m_sb.sb_versionnum = version;
mp->m_sb.sb_features2 = features;
}
+
+ if (upgrade_compat || upgrade_ro_compat || upgrade_incompat ||
+ upgrade_log_incompat) {
+ if (!add_v5_features(mp, upgrade_compat,
+ upgrade_ro_compat,
+ upgrade_incompat,
+ upgrade_log_incompat)) {
+ exitcode = 1;
+ return 1;
+ }
+ }
}
if (argc == 3) { /* VERSIONNUM + FEATURES2 */
diff --git a/db/xfs_admin.sh b/db/xfs_admin.sh
index bd325da2f776..0f0c8d18d6cb 100755
--- a/db/xfs_admin.sh
+++ b/db/xfs_admin.sh
@@ -9,7 +9,7 @@ DB_OPTS=""
REPAIR_OPTS=""
USAGE="Usage: xfs_admin [-efjlpuV] [-c 0|1] [-L label] [-U uuid] device [logdev]"
-while getopts "efjlpuc:L:U:V" c
+while getopts "efjlpuc:L:O:U:V" c
do
case $c in
c) REPAIR_OPTS=$REPAIR_OPTS" -c lazycount="$OPTARG;;
@@ -19,6 +19,8 @@ do
l) DB_OPTS=$DB_OPTS" -r -c label";;
L) DB_OPTS=$DB_OPTS" -c 'label "$OPTARG"'";;
p) DB_OPTS=$DB_OPTS" -c 'version projid32bit'";;
+ O) DB_OPTS=$DB_OPTS" -c 'version "$OPTARG"'";
+ REPAIR_OPTS="$REPAIR_OPTS ";;
u) DB_OPTS=$DB_OPTS" -r -c uuid";;
U) DB_OPTS=$DB_OPTS" -c 'uuid "$OPTARG"'";;
V) xfs_db -p xfs_admin -V
diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8
index 8afc873fb50a..65ca6afc1e12 100644
--- a/man/man8/xfs_admin.8
+++ b/man/man8/xfs_admin.8
@@ -6,6 +6,8 @@ xfs_admin \- change parameters of an XFS filesystem
[
.B \-eflpu
] [
+.BR \-O " feature"
+] [
.BR "\-c 0" | 1
] [
.B \-L
@@ -103,6 +105,20 @@ The filesystem label can be cleared using the special "\c
" value for
.IR label .
.TP
+.BI \-O " feature"
+Add a new feature to the filesystem.
+Only one feature can be specified at a time.
+Features are as follows:
+.RS 0.7i
+.TP
+.B inobtcount
+Upgrade the filesystem to support the inode btree counters feature.
+This reduces mount time by caching the size of the inode btrees in the
+allocation group metadata.
+Once enabled, the filesystem will not be writable by older kernels.
+The filesystem cannot be downgraded after this feature is enabled.
+.RE
+.TP
.BI \-U " uuid"
Set the UUID of the filesystem to
.IR uuid .
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 3/7] xfs_db: add bigtime upgrade path
2020-08-17 22:58 ` [PATCH 3/7] xfs_db: add bigtime upgrade path Darrick J. Wong
@ 2020-08-18 14:14 ` Amir Goldstein
2020-08-18 15:19 ` Darrick J. Wong
0 siblings, 1 reply; 10+ messages in thread
From: Amir Goldstein @ 2020-08-18 14:14 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Eric Sandeen, linux-xfs
On Tue, Aug 18, 2020 at 2:24 AM Darrick J. Wong <darrick.wong@oracle.com> wrote:
>
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Enable users to upgrade their filesystems to bigtime support.
That was supposed to be "inobtcount" (title as well)
Thanks,
Amir.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/7] xfs_db: add bigtime upgrade path
2020-08-18 14:14 ` Amir Goldstein
@ 2020-08-18 15:19 ` Darrick J. Wong
0 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-18 15:19 UTC (permalink / raw)
To: Amir Goldstein; +Cc: Eric Sandeen, linux-xfs
On Tue, Aug 18, 2020 at 05:14:27PM +0300, Amir Goldstein wrote:
> On Tue, Aug 18, 2020 at 2:24 AM Darrick J. Wong <darrick.wong@oracle.com> wrote:
> >
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> >
> > Enable users to upgrade their filesystems to bigtime support.
>
> That was supposed to be "inobtcount" (title as well)
Fixed, thanks. :)
--D
> Thanks,
> Amir.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/7] xfs_repair: check inode btree block counters in AGI
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
` (2 preceding siblings ...)
2020-08-17 22:58 ` [PATCH 3/7] xfs_db: add bigtime upgrade path Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
2020-08-17 22:58 ` [PATCH 5/7] xfs_repair: regenerate " Darrick J. Wong
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Make sure that both inode btree block counters in the AGI are correct.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
repair/scan.c | 38 +++++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/repair/scan.c b/repair/scan.c
index 42b299f75067..f05d0c918ce9 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -1948,6 +1948,12 @@ _("invalid inode count, inode chunk %d/%u, count %d ninodes %d\n"),
return suspect;
}
+struct ino_priv {
+ struct aghdr_cnts *agcnts;
+ uint32_t ino_blocks;
+ uint32_t fino_blocks;
+};
+
/*
* this one walks the inode btrees sucking the info there into
* the incore avl tree. We try and rescue corrupted btree records
@@ -1976,7 +1982,8 @@ scan_inobt(
void *priv,
const struct xfs_buf_ops *ops)
{
- struct aghdr_cnts *agcnts = priv;
+ struct ino_priv *ipriv = priv;
+ struct aghdr_cnts *agcnts = ipriv->agcnts;
char *name;
xfs_agino_t lastino = 0;
int i;
@@ -2022,6 +2029,17 @@ scan_inobt(
return;
}
+ switch (magic) {
+ case XFS_FIBT_MAGIC:
+ case XFS_FIBT_CRC_MAGIC:
+ ipriv->fino_blocks++;
+ break;
+ case XFS_IBT_MAGIC:
+ case XFS_IBT_CRC_MAGIC:
+ ipriv->ino_blocks++;
+ break;
+ }
+
/*
* check for btree blocks multiply claimed, any unknown/free state
* is ok in the bitmap block.
@@ -2347,6 +2365,9 @@ validate_agi(
xfs_agnumber_t agno,
struct aghdr_cnts *agcnts)
{
+ struct ino_priv priv = {
+ .agcnts = agcnts,
+ };
xfs_agblock_t bno;
int i;
uint32_t magic;
@@ -2356,7 +2377,7 @@ validate_agi(
magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC
: XFS_IBT_MAGIC;
scan_sbtree(bno, be32_to_cpu(agi->agi_level),
- agno, 0, scan_inobt, 1, magic, agcnts,
+ agno, 0, scan_inobt, 1, magic, &priv,
&xfs_inobt_buf_ops);
} else {
do_warn(_("bad agbno %u for inobt root, agno %d\n"),
@@ -2369,7 +2390,7 @@ validate_agi(
magic = xfs_sb_version_hascrc(&mp->m_sb) ?
XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
scan_sbtree(bno, be32_to_cpu(agi->agi_free_level),
- agno, 0, scan_inobt, 1, magic, agcnts,
+ agno, 0, scan_inobt, 1, magic, &priv,
&xfs_finobt_buf_ops);
} else {
do_warn(_("bad agbno %u for finobt root, agno %d\n"),
@@ -2377,6 +2398,17 @@ validate_agi(
}
}
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ if (be32_to_cpu(agi->agi_iblocks) != priv.ino_blocks)
+ do_warn(_("bad inobt block count %u, saw %u\n"),
+ priv.ino_blocks,
+ be32_to_cpu(agi->agi_iblocks));
+ if (be32_to_cpu(agi->agi_fblocks) != priv.fino_blocks)
+ do_warn(_("bad finobt block count %u, saw %u\n"),
+ priv.fino_blocks,
+ be32_to_cpu(agi->agi_fblocks));
+ }
+
if (be32_to_cpu(agi->agi_count) != agcnts->agicount) {
do_warn(_("agi_count %u, counted %u in ag %u\n"),
be32_to_cpu(agi->agi_count), agcnts->agicount, agno);
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/7] xfs_repair: regenerate inode btree block counters in AGI
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
` (3 preceding siblings ...)
2020-08-17 22:58 ` [PATCH 4/7] xfs_repair: check inode btree block counters in AGI Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
2020-08-17 22:58 ` [PATCH 6/7] xfs: enable new inode btree counters feature Darrick J. Wong
2020-08-17 22:58 ` [PATCH 7/7] mkfs: enable the inode btree counter feature Darrick J. Wong
6 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Reset both inode btree block counters in the AGI when rebuilding the
metadata indexes.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
repair/phase5.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/repair/phase5.c b/repair/phase5.c
index 446f7ec0a1db..b97d23809f3c 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -172,6 +172,11 @@ build_agi(
cpu_to_be32(btr_fino->newbt.afake.af_levels);
}
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ agi->agi_iblocks = cpu_to_be32(btr_ino->newbt.afake.af_blocks);
+ agi->agi_fblocks = cpu_to_be32(btr_fino->newbt.afake.af_blocks);
+ }
+
libxfs_buf_mark_dirty(agi_buf);
libxfs_buf_relse(agi_buf);
}
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/7] xfs: enable new inode btree counters feature
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
` (4 preceding siblings ...)
2020-08-17 22:58 ` [PATCH 5/7] xfs_repair: regenerate " Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
2020-08-17 22:58 ` [PATCH 7/7] mkfs: enable the inode btree counter feature Darrick J. Wong
6 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Enable the new inode btree counters feature.
Signed-off-by: Darrick J. Wong <darrick.wong@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 67357622e5e5..88cbcb7950c3 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -453,7 +453,8 @@ xfs_sb_has_compat_feature(
#define XFS_SB_FEAT_RO_COMPAT_ALL \
(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
- XFS_SB_FEAT_RO_COMPAT_REFLINK)
+ XFS_SB_FEAT_RO_COMPAT_REFLINK| \
+ XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
static inline bool
xfs_sb_has_ro_compat_feature(
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/7] mkfs: enable the inode btree counter feature
2020-08-17 22:58 [PATCH 0/7] xfsprogs: add a inode btree blocks counts to the AGI header Darrick J. Wong
` (5 preceding siblings ...)
2020-08-17 22:58 ` [PATCH 6/7] xfs: enable new inode btree counters feature Darrick J. Wong
@ 2020-08-17 22:58 ` Darrick J. Wong
6 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2020-08-17 22:58 UTC (permalink / raw)
To: sandeen, darrick.wong; +Cc: linux-xfs
From: Darrick J. Wong <darrick.wong@oracle.com>
Teach mkfs how to enable the inode btree counter feature.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
man/man8/mkfs.xfs.8 | 15 +++++++++++++++
mkfs/xfs_mkfs.c | 27 ++++++++++++++++++++++++++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8
index 93dcd6583f1b..082f3ab6c063 100644
--- a/man/man8/mkfs.xfs.8
+++ b/man/man8/mkfs.xfs.8
@@ -188,6 +188,21 @@ option set. When the option
.B \-m crc=0
is used, the free inode btree feature is not supported and is disabled.
.TP
+.BI inobtcount= value
+This option causes the filesystem to record the number of blocks used by
+the inode btree and the free inode btree.
+This can be used to reduce mount times when the free inode btree is enabled.
+.IP
+By default,
+.B mkfs.xfs
+will not enable this option.
+This feature is only available for filesystems created with the (default)
+.B \-m finobt=1
+option set.
+When the option
+.B \-m finobt=0
+is used, the inode btree counter feature is not supported and is disabled.
+.TP
.BI uuid= value
Use the given value as the filesystem UUID for the newly created filesystem.
The default is to generate a random UUID.
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 66b0c759b1cb..037246effd70 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -119,6 +119,7 @@ enum {
M_UUID,
M_RMAPBT,
M_REFLINK,
+ M_INOBTCNT,
M_MAX_OPTS,
};
@@ -665,6 +666,7 @@ static struct opt_params mopts = {
[M_UUID] = "uuid",
[M_RMAPBT] = "rmapbt",
[M_REFLINK] = "reflink",
+ [M_INOBTCNT] = "inobtcount",
},
.subopt_params = {
{ .index = M_CRC,
@@ -695,6 +697,12 @@ static struct opt_params mopts = {
.maxval = 1,
.defaultval = 1,
},
+ { .index = M_INOBTCNT,
+ .conflicts = { { NULL, LAST_CONFLICT } },
+ .minval = 0,
+ .maxval = 1,
+ .defaultval = 1,
+ },
},
};
@@ -746,6 +754,7 @@ struct sb_feat_args {
bool spinodes; /* XFS_SB_FEAT_INCOMPAT_SPINODES */
bool rmapbt; /* XFS_SB_FEAT_RO_COMPAT_RMAPBT */
bool reflink; /* XFS_SB_FEAT_RO_COMPAT_REFLINK */
+ bool inobtcnt; /* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */
bool nodalign;
bool nortalign;
};
@@ -868,7 +877,8 @@ usage( void )
{
fprintf(stderr, _("Usage: %s\n\
/* blocksize */ [-b size=num]\n\
-/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n\
+/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
+ inobtcnt=0|1]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
(sunit=value,swidth=value|su=num,sw=num|noalign),\n\
sectsize=num\n\
@@ -1608,6 +1618,9 @@ meta_opts_parser(
case M_REFLINK:
cli->sb_feat.reflink = getnum(value, opts, subopt);
break;
+ case M_INOBTCNT:
+ cli->sb_feat.inobtcnt = getnum(value, opts, subopt);
+ break;
default:
return -EINVAL;
}
@@ -2033,6 +2046,15 @@ _("reflink not supported without CRC support\n"));
cli->sb_feat.reflink = false;
}
+ if (!cli->sb_feat.finobt) {
+ if (cli->sb_feat.inobtcnt && cli_opt_set(&mopts, M_INOBTCNT)) {
+ fprintf(stderr,
+_("inode btree counters not supported without finobt support\n"));
+ usage();
+ }
+ cli->sb_feat.inobtcnt = false;
+ }
+
if ((cli->fsx.fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
!cli->sb_feat.reflink) {
fprintf(stderr,
@@ -2996,6 +3018,8 @@ sb_set_features(
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT;
if (fp->reflink)
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
+ if (fp->inobtcnt)
+ sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
/*
* Sparse inode chunk support has two main inode alignment requirements.
@@ -3664,6 +3688,7 @@ main(
.spinodes = true,
.rmapbt = true,
.reflink = true,
+ .inobtcnt = false,
.parent_pointers = false,
.nodalign = false,
.nortalign = false,
^ permalink raw reply related [flat|nested] 10+ messages in thread