* [PATCH 001/111] xfs: convert kmem_zalloc() to kzalloc()
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
@ 2024-05-22 2:49 ` Darrick J. Wong
2024-05-22 2:49 ` [PATCH 002/111] xfs: convert kmem_alloc() to kmalloc() Darrick J. Wong
` (110 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:49 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 10634530f7ba947d8eab52a580e0840778d4ef75
There's no reason to keep the kmem_zalloc() around anymore, it's
just a thin wrapper around kmalloc(), so lets get rid of it.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
include/kmem.h | 5 ++++-
libxfs/xfs_ag.c | 2 +-
libxfs/xfs_attr_leaf.c | 3 ++-
libxfs/xfs_btree_staging.c | 2 +-
libxfs/xfs_da_btree.c | 5 +++--
libxfs/xfs_defer.c | 2 +-
libxfs/xfs_dir2.c | 18 +++++++++---------
libxfs/xfs_iext_tree.c | 12 ++++++++----
8 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/include/kmem.h b/include/kmem.h
index 8ae919c70..6818a4047 100644
--- a/include/kmem.h
+++ b/include/kmem.h
@@ -25,8 +25,9 @@ typedef unsigned int __bitwise gfp_t;
#define GFP_NOFS ((__force gfp_t)0)
#define __GFP_NOFAIL ((__force gfp_t)0)
#define __GFP_NOLOCKDEP ((__force gfp_t)0)
+#define __GFP_RETRY_MAYFAIL ((__force gfp_t)0)
-#define __GFP_ZERO (__force gfp_t)1
+#define __GFP_ZERO ((__force gfp_t)1)
struct kmem_cache * kmem_cache_create(const char *name, unsigned int size,
unsigned int align, unsigned int slab_flags,
@@ -65,6 +66,8 @@ static inline void *kmalloc(size_t size, gfp_t flags)
return kvmalloc(size, flags);
}
+#define kzalloc(size, gfp) kvmalloc((size), (gfp) | __GFP_ZERO)
+
static inline void kfree(const void *ptr)
{
return kmem_free(ptr);
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 0556d5547..b22be1477 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -379,7 +379,7 @@ xfs_initialize_perag(
continue;
}
- pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
+ pag = kzalloc(sizeof(*pag), GFP_KERNEL | __GFP_RETRY_MAYFAIL);
if (!pag) {
error = -ENOMEM;
goto out_unwind_new_pags;
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index e3f8f67b5..8a0a7c219 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -2247,7 +2247,8 @@ xfs_attr3_leaf_unbalance(
struct xfs_attr_leafblock *tmp_leaf;
struct xfs_attr3_icleaf_hdr tmphdr;
- tmp_leaf = kmem_zalloc(state->args->geo->blksize, 0);
+ tmp_leaf = kzalloc(state->args->geo->blksize,
+ GFP_KERNEL | __GFP_NOFAIL);
/*
* Copy the header into the temp leaf so that all the stuff
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 0ea44dcf1..45b793559 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -406,7 +406,7 @@ xfs_btree_bload_prep_block(
/* Allocate a new incore btree root block. */
new_size = bbl->iroot_size(cur, level, nr_this_block, priv);
- ifp->if_broot = kmem_zalloc(new_size, 0);
+ ifp->if_broot = kzalloc(new_size, GFP_KERNEL);
ifp->if_broot_bytes = (int)new_size;
/* Initialize it and send it out. */
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 0779bb624..0864cb5ed 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -2514,7 +2514,7 @@ xfs_dabuf_map(
int error = 0, nirecs, i;
if (nfsb > 1)
- irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_NOFS);
+ irecs = kzalloc(sizeof(irec) * nfsb, GFP_NOFS | __GFP_NOFAIL);
nirecs = nfsb;
error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs,
@@ -2527,7 +2527,8 @@ xfs_dabuf_map(
* larger one that needs to be free by the caller.
*/
if (nirecs > 1) {
- map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS);
+ map = kzalloc(nirecs * sizeof(struct xfs_buf_map),
+ GFP_NOFS | __GFP_NOFAIL);
if (!map) {
error = -ENOMEM;
goto out_free_irecs;
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index bf1d1e06a..70489b097 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -973,7 +973,7 @@ xfs_defer_ops_capture(
return ERR_PTR(error);
/* Create an object to capture the defer ops. */
- dfc = kmem_zalloc(sizeof(*dfc), KM_NOFS);
+ dfc = kzalloc(sizeof(*dfc), GFP_NOFS | __GFP_NOFAIL);
INIT_LIST_HEAD(&dfc->dfc_list);
INIT_LIST_HEAD(&dfc->dfc_dfops);
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index a781520c8..cb299a6ed 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -103,10 +103,10 @@ xfs_da_mount(
ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
- mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
- KM_MAYFAIL);
- mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
- KM_MAYFAIL);
+ mp->m_dir_geo = kzalloc(sizeof(struct xfs_da_geometry),
+ GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+ mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry),
+ GFP_KERNEL | __GFP_RETRY_MAYFAIL);
if (!mp->m_dir_geo || !mp->m_attr_geo) {
kmem_free(mp->m_dir_geo);
kmem_free(mp->m_attr_geo);
@@ -235,7 +235,7 @@ xfs_dir_init(
if (error)
return error;
- args = kmem_zalloc(sizeof(*args), KM_NOFS);
+ args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
@@ -272,7 +272,7 @@ xfs_dir_createname(
XFS_STATS_INC(dp->i_mount, xs_dir_create);
}
- args = kmem_zalloc(sizeof(*args), KM_NOFS);
+ args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
@@ -371,7 +371,7 @@ xfs_dir_lookup(
* lockdep Doing this avoids having to add a bunch of lockdep class
* annotations into the reclaim path for the ilock.
*/
- args = kmem_zalloc(sizeof(*args), KM_NOFS);
+ args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name;
args->namelen = name->len;
@@ -440,7 +440,7 @@ xfs_dir_removename(
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
XFS_STATS_INC(dp->i_mount, xs_dir_remove);
- args = kmem_zalloc(sizeof(*args), KM_NOFS);
+ args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
@@ -501,7 +501,7 @@ xfs_dir_replace(
if (rval)
return rval;
- args = kmem_zalloc(sizeof(*args), KM_NOFS);
+ args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
diff --git a/libxfs/xfs_iext_tree.c b/libxfs/xfs_iext_tree.c
index 24124039f..641b53f4e 100644
--- a/libxfs/xfs_iext_tree.c
+++ b/libxfs/xfs_iext_tree.c
@@ -398,7 +398,8 @@ static void
xfs_iext_grow(
struct xfs_ifork *ifp)
{
- struct xfs_iext_node *node = kmem_zalloc(NODE_SIZE, KM_NOFS);
+ struct xfs_iext_node *node = kzalloc(NODE_SIZE,
+ GFP_NOFS | __GFP_NOFAIL);
int i;
if (ifp->if_height == 1) {
@@ -454,7 +455,8 @@ xfs_iext_split_node(
int *nr_entries)
{
struct xfs_iext_node *node = *nodep;
- struct xfs_iext_node *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
+ struct xfs_iext_node *new = kzalloc(NODE_SIZE,
+ GFP_NOFS | __GFP_NOFAIL);
const int nr_move = KEYS_PER_NODE / 2;
int nr_keep = nr_move + (KEYS_PER_NODE & 1);
int i = 0;
@@ -542,7 +544,8 @@ xfs_iext_split_leaf(
int *nr_entries)
{
struct xfs_iext_leaf *leaf = cur->leaf;
- struct xfs_iext_leaf *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
+ struct xfs_iext_leaf *new = kzalloc(NODE_SIZE,
+ GFP_NOFS | __GFP_NOFAIL);
const int nr_move = RECS_PER_LEAF / 2;
int nr_keep = nr_move + (RECS_PER_LEAF & 1);
int i;
@@ -583,7 +586,8 @@ xfs_iext_alloc_root(
{
ASSERT(ifp->if_bytes == 0);
- ifp->if_data = kmem_zalloc(sizeof(struct xfs_iext_rec), KM_NOFS);
+ ifp->if_data = kzalloc(sizeof(struct xfs_iext_rec),
+ GFP_NOFS | __GFP_NOFAIL);
ifp->if_height = 1;
/* now that we have a node step into it */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 002/111] xfs: convert kmem_alloc() to kmalloc()
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
2024-05-22 2:49 ` [PATCH 001/111] xfs: convert kmem_zalloc() to kzalloc() Darrick J. Wong
@ 2024-05-22 2:49 ` Darrick J. Wong
2024-05-22 2:49 ` [PATCH 003/111] xfs: convert remaining kmem_free() to kfree() Darrick J. Wong
` (109 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:49 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: f078d4ea827607867d42fb3b2ef907caf86ce49d
kmem_alloc() is just a thin wrapper around kmalloc() these days.
Convert everything to use kmalloc() so we can get rid of the
wrapper.
Note: the transaction region allocation in xlog_add_to_transaction()
can be a high order allocation. Converting it to use
kmalloc(__GFP_NOFAIL) results in warnings in the page allocation
code being triggered because the mm subsystem does not want us to
use __GFP_NOFAIL with high order allocations like we've been doing
with the kmem_alloc() wrapper for a couple of decades. Hence this
specific case gets converted to xlog_kvmalloc() rather than
kmalloc() to avoid this issue.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_attr_leaf.c | 7 +++----
libxfs/xfs_btree_staging.c | 4 ++--
libxfs/xfs_da_btree.c | 3 ++-
libxfs/xfs_dir2.c | 2 +-
libxfs/xfs_dir2_block.c | 2 +-
libxfs/xfs_dir2_sf.c | 8 ++++----
libxfs/xfs_inode_fork.c | 15 ++++++++-------
7 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 8a0a7c219..0d7dc789c 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -876,8 +876,7 @@ xfs_attr_shortform_to_leaf(
trace_xfs_attr_sf_to_leaf(args);
- tmpbuffer = kmem_alloc(size, 0);
- ASSERT(tmpbuffer != NULL);
+ tmpbuffer = kmalloc(size, GFP_KERNEL | __GFP_NOFAIL);
memcpy(tmpbuffer, ifp->if_data, size);
sf = (struct xfs_attr_sf_hdr *)tmpbuffer;
@@ -1056,7 +1055,7 @@ xfs_attr3_leaf_to_shortform(
trace_xfs_attr_leaf_to_sf(args);
- tmpbuffer = kmem_alloc(args->geo->blksize, 0);
+ tmpbuffer = kmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL);
if (!tmpbuffer)
return -ENOMEM;
@@ -1530,7 +1529,7 @@ xfs_attr3_leaf_compact(
trace_xfs_attr_leaf_compact(args);
- tmpbuffer = kmem_alloc(args->geo->blksize, 0);
+ tmpbuffer = kmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL);
memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
memset(bp->b_addr, 0, args->geo->blksize);
leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 45b793559..da6e9fa8e 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -139,7 +139,7 @@ xfs_btree_stage_afakeroot(
ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE));
ASSERT(cur->bc_tp == NULL);
- nops = kmem_alloc(sizeof(struct xfs_btree_ops), KM_NOFS);
+ nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_NOFS | __GFP_NOFAIL);
memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
nops->alloc_block = xfs_btree_fakeroot_alloc_block;
nops->free_block = xfs_btree_fakeroot_free_block;
@@ -220,7 +220,7 @@ xfs_btree_stage_ifakeroot(
ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
ASSERT(cur->bc_tp == NULL);
- nops = kmem_alloc(sizeof(struct xfs_btree_ops), KM_NOFS);
+ nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_NOFS | __GFP_NOFAIL);
memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
nops->alloc_block = xfs_btree_fakeroot_alloc_block;
nops->free_block = xfs_btree_fakeroot_free_block;
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 0864cb5ed..33ac8d13c 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -2178,7 +2178,8 @@ xfs_da_grow_inode_int(
* If we didn't get it and the block might work if fragmented,
* try without the CONTIG flag. Loop until we get it all.
*/
- mapp = kmem_alloc(sizeof(*mapp) * count, 0);
+ mapp = kmalloc(sizeof(*mapp) * count,
+ GFP_KERNEL | __GFP_NOFAIL);
for (b = *bno, mapi = 0; b < *bno + count; ) {
c = (int)(*bno + count - b);
nmap = min(XFS_BMAP_MAX_NMAP, c);
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index cb299a6ed..52f0461ef 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -332,7 +332,7 @@ xfs_dir_cilookup_result(
!(args->op_flags & XFS_DA_OP_CILOOKUP))
return -EEXIST;
- args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL);
+ args->value = kmalloc(len, GFP_NOFS | __GFP_RETRY_MAYFAIL);
if (!args->value)
return -ENOMEM;
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index bf950c700..b694e6219 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -1105,7 +1105,7 @@ xfs_dir2_sf_to_block(
* Copy the directory into a temporary buffer.
* Then pitch the incore inode data so we can make extents.
*/
- sfp = kmem_alloc(ifp->if_bytes, 0);
+ sfp = kmalloc(ifp->if_bytes, GFP_KERNEL | __GFP_NOFAIL);
memcpy(sfp, oldsfp, ifp->if_bytes);
xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK);
diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
index 37c7e1d5c..9e0c15f99 100644
--- a/libxfs/xfs_dir2_sf.c
+++ b/libxfs/xfs_dir2_sf.c
@@ -276,7 +276,7 @@ xfs_dir2_block_to_sf(
* format the data into. Once we have formatted the data, we can free
* the block and copy the formatted data into the inode literal area.
*/
- sfp = kmem_alloc(mp->m_sb.sb_inodesize, 0);
+ sfp = kmalloc(mp->m_sb.sb_inodesize, GFP_KERNEL | __GFP_NOFAIL);
memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count));
/*
@@ -524,7 +524,7 @@ xfs_dir2_sf_addname_hard(
* Copy the old directory to the stack buffer.
*/
old_isize = (int)dp->i_disk_size;
- buf = kmem_alloc(old_isize, 0);
+ buf = kmalloc(old_isize, GFP_KERNEL | __GFP_NOFAIL);
oldsfp = (xfs_dir2_sf_hdr_t *)buf;
memcpy(oldsfp, dp->i_df.if_data, old_isize);
/*
@@ -1151,7 +1151,7 @@ xfs_dir2_sf_toino4(
* Don't want xfs_idata_realloc copying the data here.
*/
oldsize = dp->i_df.if_bytes;
- buf = kmem_alloc(oldsize, 0);
+ buf = kmalloc(oldsize, GFP_KERNEL | __GFP_NOFAIL);
ASSERT(oldsfp->i8count == 1);
memcpy(buf, oldsfp, oldsize);
/*
@@ -1223,7 +1223,7 @@ xfs_dir2_sf_toino8(
* Don't want xfs_idata_realloc copying the data here.
*/
oldsize = dp->i_df.if_bytes;
- buf = kmem_alloc(oldsize, 0);
+ buf = kmalloc(oldsize, GFP_KERNEL | __GFP_NOFAIL);
ASSERT(oldsfp->i8count == 0);
memcpy(buf, oldsfp, oldsize);
/*
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 208b283ba..7de346e87 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -48,7 +48,7 @@ xfs_init_local_fork(
mem_size++;
if (size) {
- char *new_data = kmem_alloc(mem_size, KM_NOFS);
+ char *new_data = kmalloc(mem_size, GFP_NOFS | __GFP_NOFAIL);
memcpy(new_data, data, size);
if (zero_terminate)
@@ -75,7 +75,7 @@ xfs_iformat_local(
/*
* If the size is unreasonable, then something
* is wrong and we just bail out rather than crash in
- * kmem_alloc() or memcpy() below.
+ * kmalloc() or memcpy() below.
*/
if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
xfs_warn(ip->i_mount,
@@ -114,7 +114,7 @@ xfs_iformat_extents(
/*
* If the number of extents is unreasonable, then something is wrong and
- * we just bail out rather than crash in kmem_alloc() or memcpy() below.
+ * we just bail out rather than crash in kmalloc() or memcpy() below.
*/
if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
xfs_warn(ip->i_mount, "corrupt inode %llu ((a)extents = %llu).",
@@ -203,7 +203,7 @@ xfs_iformat_btree(
}
ifp->if_broot_bytes = size;
- ifp->if_broot = kmem_alloc(size, KM_NOFS);
+ ifp->if_broot = kmalloc(size, GFP_NOFS | __GFP_NOFAIL);
ASSERT(ifp->if_broot != NULL);
/*
* Copy and convert from the on-disk structure
@@ -397,7 +397,8 @@ xfs_iroot_realloc(
*/
if (ifp->if_broot_bytes == 0) {
new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
- ifp->if_broot = kmem_alloc(new_size, KM_NOFS);
+ ifp->if_broot = kmalloc(new_size,
+ GFP_NOFS | __GFP_NOFAIL);
ifp->if_broot_bytes = (int)new_size;
return;
}
@@ -438,7 +439,7 @@ xfs_iroot_realloc(
else
new_size = 0;
if (new_size > 0) {
- new_broot = kmem_alloc(new_size, KM_NOFS);
+ new_broot = kmalloc(new_size, GFP_NOFS | __GFP_NOFAIL);
/*
* First copy over the btree block header.
*/
@@ -486,7 +487,7 @@ xfs_iroot_realloc(
*
* If the amount of space needed has decreased below the size of the
* inline buffer, then switch to using the inline buffer. Otherwise,
- * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
+ * use krealloc() or kmalloc() to adjust the size of the buffer
* to what is needed.
*
* ip -- the inode whose if_data area is changing
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 003/111] xfs: convert remaining kmem_free() to kfree()
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
2024-05-22 2:49 ` [PATCH 001/111] xfs: convert kmem_zalloc() to kzalloc() Darrick J. Wong
2024-05-22 2:49 ` [PATCH 002/111] xfs: convert kmem_alloc() to kmalloc() Darrick J. Wong
@ 2024-05-22 2:49 ` Darrick J. Wong
2024-05-22 2:49 ` [PATCH 004/111] xfs: use __GFP_NOLOCKDEP instead of GFP_NOFS Darrick J. Wong
` (108 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:49 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: d4c75a1b40cd036a84d98e2711db9cf30eaaaf5f
The remaining callers of kmem_free() are freeing heap memory, so
we can convert them directly to kfree() and get rid of kmem_free()
altogether.
This conversion was done with:
$ for f in `git grep -l kmem_free fs/xfs`; do
> sed -i s/kmem_free/kfree/ $f
> done
$
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_ag.c | 6 +++---
libxfs/xfs_attr_leaf.c | 8 ++++----
libxfs/xfs_btree.c | 2 +-
libxfs/xfs_btree_staging.c | 4 ++--
libxfs/xfs_da_btree.c | 10 +++++-----
libxfs/xfs_defer.c | 4 ++--
libxfs/xfs_dir2.c | 18 +++++++++---------
libxfs/xfs_dir2_block.c | 4 ++--
libxfs/xfs_dir2_sf.c | 8 ++++----
libxfs/xfs_iext_tree.c | 8 ++++----
libxfs/xfs_inode_fork.c | 6 +++---
11 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index b22be1477..2ea8d06ca 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -239,7 +239,7 @@ __xfs_free_perag(
struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head);
ASSERT(!delayed_work_pending(&pag->pag_blockgc_work));
- kmem_free(pag);
+ kfree(pag);
}
/*
@@ -351,7 +351,7 @@ xfs_free_unused_perag_range(
break;
xfs_buf_hash_destroy(pag);
xfs_defer_drain_free(&pag->pag_intents_drain);
- kmem_free(pag);
+ kfree(pag);
}
}
@@ -451,7 +451,7 @@ xfs_initialize_perag(
radix_tree_delete(&mp->m_perag_tree, index);
spin_unlock(&mp->m_perag_lock);
out_free_pag:
- kmem_free(pag);
+ kfree(pag);
out_unwind_new_pags:
/* unwind any prior newly initialized pags */
xfs_free_unused_perag_range(mp, first_initialised, agcount);
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 0d7dc789c..fdc53451c 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -920,7 +920,7 @@ xfs_attr_shortform_to_leaf(
}
error = 0;
out:
- kmem_free(tmpbuffer);
+ kfree(tmpbuffer);
return error;
}
@@ -1121,7 +1121,7 @@ xfs_attr3_leaf_to_shortform(
error = 0;
out:
- kmem_free(tmpbuffer);
+ kfree(tmpbuffer);
return error;
}
@@ -1567,7 +1567,7 @@ xfs_attr3_leaf_compact(
*/
xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
- kmem_free(tmpbuffer);
+ kfree(tmpbuffer);
}
/*
@@ -2287,7 +2287,7 @@ xfs_attr3_leaf_unbalance(
}
memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
savehdr = tmphdr; /* struct copy */
- kmem_free(tmp_leaf);
+ kfree(tmp_leaf);
}
xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 0022bb641..663439ec3 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -448,7 +448,7 @@ xfs_btree_del_cursor(
ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_ino.allocated == 0 ||
xfs_is_shutdown(cur->bc_mp) || error != 0);
if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
- kmem_free(cur->bc_ops);
+ kfree(cur->bc_ops);
if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS) && cur->bc_ag.pag)
xfs_perag_put(cur->bc_ag.pag);
kmem_cache_free(cur->bc_cache, cur);
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index da6e9fa8e..0828cc7e3 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -171,7 +171,7 @@ xfs_btree_commit_afakeroot(
trace_xfs_btree_commit_afakeroot(cur);
- kmem_free((void *)cur->bc_ops);
+ kfree((void *)cur->bc_ops);
cur->bc_ag.agbp = agbp;
cur->bc_ops = ops;
cur->bc_flags &= ~XFS_BTREE_STAGING;
@@ -254,7 +254,7 @@ xfs_btree_commit_ifakeroot(
trace_xfs_btree_commit_ifakeroot(cur);
- kmem_free((void *)cur->bc_ops);
+ kfree((void *)cur->bc_ops);
cur->bc_ino.ifake = NULL;
cur->bc_ino.whichfork = whichfork;
cur->bc_ops = ops;
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 33ac8d13c..910099449 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -2216,7 +2216,7 @@ xfs_da_grow_inode_int(
out_free_map:
if (mapp != &map)
- kmem_free(mapp);
+ kfree(mapp);
return error;
}
@@ -2555,7 +2555,7 @@ xfs_dabuf_map(
*nmaps = nirecs;
out_free_irecs:
if (irecs != &irec)
- kmem_free(irecs);
+ kfree(irecs);
return error;
invalid_mapping:
@@ -2611,7 +2611,7 @@ xfs_da_get_buf(
out_free:
if (mapp != &map)
- kmem_free(mapp);
+ kfree(mapp);
return error;
}
@@ -2652,7 +2652,7 @@ xfs_da_read_buf(
*bpp = bp;
out_free:
if (mapp != &map)
- kmem_free(mapp);
+ kfree(mapp);
return error;
}
@@ -2683,7 +2683,7 @@ xfs_da_reada_buf(
out_free:
if (mapp != &map)
- kmem_free(mapp);
+ kfree(mapp);
return error;
}
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index 70489b097..1de3faf5e 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -1032,7 +1032,7 @@ xfs_defer_ops_capture_abort(
for (i = 0; i < dfc->dfc_held.dr_inos; i++)
xfs_irele(dfc->dfc_held.dr_ip[i]);
- kmem_free(dfc);
+ kfree(dfc);
}
/*
@@ -1108,7 +1108,7 @@ xfs_defer_ops_continue(
list_splice_init(&dfc->dfc_dfops, &tp->t_dfops);
tp->t_flags |= dfc->dfc_tpflags;
- kmem_free(dfc);
+ kfree(dfc);
}
/* Release the resources captured and continued during recovery. */
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index 52f0461ef..c2f0efa06 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -108,8 +108,8 @@ xfs_da_mount(
mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry),
GFP_KERNEL | __GFP_RETRY_MAYFAIL);
if (!mp->m_dir_geo || !mp->m_attr_geo) {
- kmem_free(mp->m_dir_geo);
- kmem_free(mp->m_attr_geo);
+ kfree(mp->m_dir_geo);
+ kfree(mp->m_attr_geo);
return -ENOMEM;
}
@@ -177,8 +177,8 @@ void
xfs_da_unmount(
struct xfs_mount *mp)
{
- kmem_free(mp->m_dir_geo);
- kmem_free(mp->m_attr_geo);
+ kfree(mp->m_dir_geo);
+ kfree(mp->m_attr_geo);
}
/*
@@ -243,7 +243,7 @@ xfs_dir_init(
args->dp = dp;
args->trans = tp;
error = xfs_dir2_sf_create(args, pdp->i_ino);
- kmem_free(args);
+ kfree(args);
return error;
}
@@ -312,7 +312,7 @@ xfs_dir_createname(
rval = xfs_dir2_node_addname(args);
out_free:
- kmem_free(args);
+ kfree(args);
return rval;
}
@@ -418,7 +418,7 @@ xfs_dir_lookup(
}
out_free:
xfs_iunlock(dp, lock_mode);
- kmem_free(args);
+ kfree(args);
return rval;
}
@@ -476,7 +476,7 @@ xfs_dir_removename(
else
rval = xfs_dir2_node_removename(args);
out_free:
- kmem_free(args);
+ kfree(args);
return rval;
}
@@ -537,7 +537,7 @@ xfs_dir_replace(
else
rval = xfs_dir2_node_replace(args);
out_free:
- kmem_free(args);
+ kfree(args);
return rval;
}
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index b694e6219..aed3c14a8 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -1250,7 +1250,7 @@ xfs_dir2_sf_to_block(
sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
}
/* Done with the temporary buffer */
- kmem_free(sfp);
+ kfree(sfp);
/*
* Sort the leaf entries by hash value.
*/
@@ -1265,6 +1265,6 @@ xfs_dir2_sf_to_block(
xfs_dir3_data_check(dp, bp);
return 0;
out_free:
- kmem_free(sfp);
+ kfree(sfp);
return error;
}
diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
index 9e0c15f99..aaf73cd35 100644
--- a/libxfs/xfs_dir2_sf.c
+++ b/libxfs/xfs_dir2_sf.c
@@ -350,7 +350,7 @@ xfs_dir2_block_to_sf(
xfs_dir2_sf_check(args);
out:
xfs_trans_log_inode(args->trans, dp, logflags);
- kmem_free(sfp);
+ kfree(sfp);
return error;
}
@@ -576,7 +576,7 @@ xfs_dir2_sf_addname_hard(
sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
memcpy(sfep, oldsfep, old_isize - nbytes);
}
- kmem_free(buf);
+ kfree(buf);
dp->i_disk_size = new_isize;
xfs_dir2_sf_check(args);
}
@@ -1190,7 +1190,7 @@ xfs_dir2_sf_toino4(
/*
* Clean up the inode.
*/
- kmem_free(buf);
+ kfree(buf);
dp->i_disk_size = newsize;
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
}
@@ -1262,7 +1262,7 @@ xfs_dir2_sf_toino8(
/*
* Clean up the inode.
*/
- kmem_free(buf);
+ kfree(buf);
dp->i_disk_size = newsize;
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
}
diff --git a/libxfs/xfs_iext_tree.c b/libxfs/xfs_iext_tree.c
index 641b53f4e..a3bbd9157 100644
--- a/libxfs/xfs_iext_tree.c
+++ b/libxfs/xfs_iext_tree.c
@@ -747,7 +747,7 @@ xfs_iext_remove_node(
again:
ASSERT(node->ptrs[pos]);
ASSERT(node->ptrs[pos] == victim);
- kmem_free(victim);
+ kfree(victim);
nr_entries = xfs_iext_node_nr_entries(node, pos) - 1;
offset = node->keys[0];
@@ -793,7 +793,7 @@ xfs_iext_remove_node(
ASSERT(node == ifp->if_data);
ifp->if_data = node->ptrs[0];
ifp->if_height--;
- kmem_free(node);
+ kfree(node);
}
}
@@ -867,7 +867,7 @@ xfs_iext_free_last_leaf(
struct xfs_ifork *ifp)
{
ifp->if_height--;
- kmem_free(ifp->if_data);
+ kfree(ifp->if_data);
ifp->if_data = NULL;
}
@@ -1048,7 +1048,7 @@ xfs_iext_destroy_node(
}
}
- kmem_free(node);
+ kfree(node);
}
void
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 7de346e87..5e0cb4886 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -469,7 +469,7 @@ xfs_iroot_realloc(
(int)new_size);
memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t));
}
- kmem_free(ifp->if_broot);
+ kfree(ifp->if_broot);
ifp->if_broot = new_broot;
ifp->if_broot_bytes = (int)new_size;
if (ifp->if_broot)
@@ -523,13 +523,13 @@ xfs_idestroy_fork(
struct xfs_ifork *ifp)
{
if (ifp->if_broot != NULL) {
- kmem_free(ifp->if_broot);
+ kfree(ifp->if_broot);
ifp->if_broot = NULL;
}
switch (ifp->if_format) {
case XFS_DINODE_FMT_LOCAL:
- kmem_free(ifp->if_data);
+ kfree(ifp->if_data);
ifp->if_data = NULL;
break;
case XFS_DINODE_FMT_EXTENTS:
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 004/111] xfs: use __GFP_NOLOCKDEP instead of GFP_NOFS
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (2 preceding siblings ...)
2024-05-22 2:49 ` [PATCH 003/111] xfs: convert remaining kmem_free() to kfree() Darrick J. Wong
@ 2024-05-22 2:49 ` Darrick J. Wong
2024-05-22 2:50 ` [PATCH 005/111] xfs: use GFP_KERNEL in pure transaction contexts Darrick J. Wong
` (107 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:49 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 94a69db2367efcd7e0eeb5d4603340aff1d3c340
In the past we've had problems with lockdep false positives stemming
from inode locking occurring in memory reclaim contexts (e.g. from
superblock shrinkers). Lockdep doesn't know that inodes access from
above memory reclaim cannot be accessed from below memory reclaim
(and vice versa) but there has never been a good solution to solving
this problem with lockdep annotations.
This situation isn't unique to inode locks - buffers are also locked
above and below memory reclaim, and we have to maintain lock
ordering for them - and against inodes - appropriately. IOWs, the
same code paths and locks are taken both above and below memory
reclaim and so we always need to make sure the lock orders are
consistent. We are spared the lockdep problems this might cause
by the fact that semaphores and bit locks aren't covered by lockdep.
In general, this sort of lockdep false positive detection is cause
by code that runs GFP_KERNEL memory allocation with an actively
referenced inode locked. When it is run from a transaction, memory
allocation is automatically GFP_NOFS, so we don't have reclaim
recursion issues. So in the places where we do memory allocation
with inodes locked outside of a transaction, we have explicitly set
them to use GFP_NOFS allocations to prevent lockdep false positives
from being reported if the allocation dips into direct memory
reclaim.
More recently, __GFP_NOLOCKDEP was added to the memory allocation
flags to tell lockdep not to track that particular allocation for
the purposes of reclaim recursion detection. This is a much better
way of preventing false positives - it allows us to use GFP_KERNEL
context outside of transactions, and allows direct memory reclaim to
proceed normally without throwing out false positive deadlock
warnings.
The obvious places that lock inodes and do memory allocation are the
lookup paths and inode extent list initialisation. These occur in
non-transactional GFP_KERNEL contexts, and so can run direct reclaim
and lock inodes.
This patch makes a first path through all the explicit GFP_NOFS
allocations in XFS and converts the obvious ones to GFP_KERNEL |
__GFP_NOLOCKDEP as a first step towards removing explicit GFP_NOFS
allocations from the XFS code.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_ag.c | 2 +-
libxfs/xfs_btree.h | 4 +++-
libxfs/xfs_da_btree.c | 8 +++++---
libxfs/xfs_dir2.c | 14 ++++----------
libxfs/xfs_iext_tree.c | 22 +++++++++++++---------
libxfs/xfs_inode_fork.c | 8 +++++---
6 files changed, 31 insertions(+), 27 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 2ea8d06ca..86024ddfd 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -387,7 +387,7 @@ xfs_initialize_perag(
pag->pag_agno = index;
pag->pag_mount = mp;
- error = radix_tree_preload(GFP_NOFS);
+ error = radix_tree_preload(GFP_KERNEL | __GFP_RETRY_MAYFAIL);
if (error)
goto out_free_pag;
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index d906324e2..75a0e2c8e 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -725,7 +725,9 @@ xfs_btree_alloc_cursor(
{
struct xfs_btree_cur *cur;
- cur = kmem_cache_zalloc(cache, GFP_NOFS | __GFP_NOFAIL);
+ /* BMBT allocations can come through from non-transactional context. */
+ cur = kmem_cache_zalloc(cache,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
cur->bc_tp = tp;
cur->bc_mp = mp;
cur->bc_btnum = btnum;
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 910099449..0fea72f33 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -81,7 +81,8 @@ xfs_da_state_alloc(
{
struct xfs_da_state *state;
- state = kmem_cache_zalloc(xfs_da_state_cache, GFP_NOFS | __GFP_NOFAIL);
+ state = kmem_cache_zalloc(xfs_da_state_cache,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
state->args = args;
state->mp = args->dp->i_mount;
return state;
@@ -2515,7 +2516,8 @@ xfs_dabuf_map(
int error = 0, nirecs, i;
if (nfsb > 1)
- irecs = kzalloc(sizeof(irec) * nfsb, GFP_NOFS | __GFP_NOFAIL);
+ irecs = kzalloc(sizeof(irec) * nfsb,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
nirecs = nfsb;
error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs,
@@ -2529,7 +2531,7 @@ xfs_dabuf_map(
*/
if (nirecs > 1) {
map = kzalloc(nirecs * sizeof(struct xfs_buf_map),
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
if (!map) {
error = -ENOMEM;
goto out_free_irecs;
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index c2f0efa06..1a2fb999a 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -332,7 +332,8 @@ xfs_dir_cilookup_result(
!(args->op_flags & XFS_DA_OP_CILOOKUP))
return -EEXIST;
- args->value = kmalloc(len, GFP_NOFS | __GFP_RETRY_MAYFAIL);
+ args->value = kmalloc(len,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_RETRY_MAYFAIL);
if (!args->value)
return -ENOMEM;
@@ -363,15 +364,8 @@ xfs_dir_lookup(
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
- /*
- * We need to use KM_NOFS here so that lockdep will not throw false
- * positive deadlock warnings on a non-transactional lookup path. It is
- * safe to recurse into inode recalim in that case, but lockdep can't
- * easily be taught about it. Hence KM_NOFS avoids having to add more
- * lockdep Doing this avoids having to add a bunch of lockdep class
- * annotations into the reclaim path for the ilock.
- */
- args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
+ args = kzalloc(sizeof(*args),
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name;
args->namelen = name->len;
diff --git a/libxfs/xfs_iext_tree.c b/libxfs/xfs_iext_tree.c
index a3bbd9157..cdbb72d63 100644
--- a/libxfs/xfs_iext_tree.c
+++ b/libxfs/xfs_iext_tree.c
@@ -394,12 +394,18 @@ xfs_iext_leaf_key(
return leaf->recs[n].lo & XFS_IEXT_STARTOFF_MASK;
}
+static inline void *
+xfs_iext_alloc_node(
+ int size)
+{
+ return kzalloc(size, GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
+}
+
static void
xfs_iext_grow(
struct xfs_ifork *ifp)
{
- struct xfs_iext_node *node = kzalloc(NODE_SIZE,
- GFP_NOFS | __GFP_NOFAIL);
+ struct xfs_iext_node *node = xfs_iext_alloc_node(NODE_SIZE);
int i;
if (ifp->if_height == 1) {
@@ -455,8 +461,7 @@ xfs_iext_split_node(
int *nr_entries)
{
struct xfs_iext_node *node = *nodep;
- struct xfs_iext_node *new = kzalloc(NODE_SIZE,
- GFP_NOFS | __GFP_NOFAIL);
+ struct xfs_iext_node *new = xfs_iext_alloc_node(NODE_SIZE);
const int nr_move = KEYS_PER_NODE / 2;
int nr_keep = nr_move + (KEYS_PER_NODE & 1);
int i = 0;
@@ -544,8 +549,7 @@ xfs_iext_split_leaf(
int *nr_entries)
{
struct xfs_iext_leaf *leaf = cur->leaf;
- struct xfs_iext_leaf *new = kzalloc(NODE_SIZE,
- GFP_NOFS | __GFP_NOFAIL);
+ struct xfs_iext_leaf *new = xfs_iext_alloc_node(NODE_SIZE);
const int nr_move = RECS_PER_LEAF / 2;
int nr_keep = nr_move + (RECS_PER_LEAF & 1);
int i;
@@ -586,8 +590,7 @@ xfs_iext_alloc_root(
{
ASSERT(ifp->if_bytes == 0);
- ifp->if_data = kzalloc(sizeof(struct xfs_iext_rec),
- GFP_NOFS | __GFP_NOFAIL);
+ ifp->if_data = xfs_iext_alloc_node(sizeof(struct xfs_iext_rec));
ifp->if_height = 1;
/* now that we have a node step into it */
@@ -607,7 +610,8 @@ xfs_iext_realloc_root(
if (new_size / sizeof(struct xfs_iext_rec) == RECS_PER_LEAF)
new_size = NODE_SIZE;
- new = krealloc(ifp->if_data, new_size, GFP_NOFS | __GFP_NOFAIL);
+ new = krealloc(ifp->if_data, new_size,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
memset(new + ifp->if_bytes, 0, new_size - ifp->if_bytes);
ifp->if_data = new;
cur->leaf = new;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 5e0cb4886..cb1964189 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -48,7 +48,8 @@ xfs_init_local_fork(
mem_size++;
if (size) {
- char *new_data = kmalloc(mem_size, GFP_NOFS | __GFP_NOFAIL);
+ char *new_data = kmalloc(mem_size,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
memcpy(new_data, data, size);
if (zero_terminate)
@@ -203,7 +204,8 @@ xfs_iformat_btree(
}
ifp->if_broot_bytes = size;
- ifp->if_broot = kmalloc(size, GFP_NOFS | __GFP_NOFAIL);
+ ifp->if_broot = kmalloc(size,
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
ASSERT(ifp->if_broot != NULL);
/*
* Copy and convert from the on-disk structure
@@ -688,7 +690,7 @@ xfs_ifork_init_cow(
return;
ip->i_cowfp = kmem_cache_zalloc(xfs_ifork_cache,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 005/111] xfs: use GFP_KERNEL in pure transaction contexts
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (3 preceding siblings ...)
2024-05-22 2:49 ` [PATCH 004/111] xfs: use __GFP_NOLOCKDEP instead of GFP_NOFS Darrick J. Wong
@ 2024-05-22 2:50 ` Darrick J. Wong
2024-05-22 2:50 ` [PATCH 006/111] xfs: clean up remaining GFP_NOFS users Darrick J. Wong
` (106 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:50 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 0b3a76e955ebe3d71a2bcd5990404ed522b40e17
When running in a transaction context, memory allocations are scoped
to GFP_NOFS. Hence we don't need to use GFP_NOFS contexts in pure
transaction context allocations - GFP_KERNEL will automatically get
converted to GFP_NOFS as appropriate.
Go through the code and convert all the obvious GFP_NOFS allocations
in transaction context to use GFP_KERNEL. This further reduces the
explicit use of GFP_NOFS in XFS.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_attr.c | 3 ++-
libxfs/xfs_bmap.c | 2 +-
libxfs/xfs_defer.c | 6 +++---
libxfs/xfs_dir2.c | 8 ++++----
libxfs/xfs_inode_fork.c | 8 ++++----
libxfs/xfs_refcount.c | 2 +-
libxfs/xfs_rmap.c | 2 +-
7 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 630065f1a..8356d4a3c 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -889,7 +889,8 @@ xfs_attr_defer_add(
struct xfs_attr_intent *new;
- new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+ new = kmem_cache_zalloc(xfs_attr_intent_cache,
+ GFP_KERNEL | __GFP_NOFAIL);
new->xattri_op_flags = op_flags;
new->xattri_da_args = args;
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 494994d36..ee4e6c766 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -6092,7 +6092,7 @@ __xfs_bmap_add(
bmap->br_blockcount,
bmap->br_state);
- bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+ bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&bi->bi_list);
bi->bi_type = type;
bi->bi_owner = ip;
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index 1de3faf5e..dae9ad57f 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -819,7 +819,7 @@ xfs_defer_alloc(
struct xfs_defer_pending *dfp;
dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOFAIL);
dfp->dfp_ops = ops;
INIT_LIST_HEAD(&dfp->dfp_work);
list_add_tail(&dfp->dfp_list, &tp->t_dfops);
@@ -882,7 +882,7 @@ xfs_defer_start_recovery(
struct xfs_defer_pending *dfp;
dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOFAIL);
dfp->dfp_ops = ops;
dfp->dfp_intent = lip;
INIT_LIST_HEAD(&dfp->dfp_work);
@@ -973,7 +973,7 @@ xfs_defer_ops_capture(
return ERR_PTR(error);
/* Create an object to capture the defer ops. */
- dfc = kzalloc(sizeof(*dfc), GFP_NOFS | __GFP_NOFAIL);
+ dfc = kzalloc(sizeof(*dfc), GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&dfc->dfc_list);
INIT_LIST_HEAD(&dfc->dfc_dfops);
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index 1a2fb999a..914c75107 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -235,7 +235,7 @@ xfs_dir_init(
if (error)
return error;
- args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
+ args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
@@ -272,7 +272,7 @@ xfs_dir_createname(
XFS_STATS_INC(dp->i_mount, xs_dir_create);
}
- args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
+ args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
@@ -434,7 +434,7 @@ xfs_dir_removename(
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
XFS_STATS_INC(dp->i_mount, xs_dir_remove);
- args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
+ args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
@@ -495,7 +495,7 @@ xfs_dir_replace(
if (rval)
return rval;
- args = kzalloc(sizeof(*args), GFP_NOFS | __GFP_NOFAIL);
+ args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
if (!args)
return -ENOMEM;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index cb1964189..f8f6a7364 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -400,7 +400,7 @@ xfs_iroot_realloc(
if (ifp->if_broot_bytes == 0) {
new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
ifp->if_broot = kmalloc(new_size,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOFAIL);
ifp->if_broot_bytes = (int)new_size;
return;
}
@@ -415,7 +415,7 @@ xfs_iroot_realloc(
new_max = cur_max + rec_diff;
new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
ifp->if_broot = krealloc(ifp->if_broot, new_size,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOFAIL);
op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
ifp->if_broot_bytes);
np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
@@ -441,7 +441,7 @@ xfs_iroot_realloc(
else
new_size = 0;
if (new_size > 0) {
- new_broot = kmalloc(new_size, GFP_NOFS | __GFP_NOFAIL);
+ new_broot = kmalloc(new_size, GFP_KERNEL | __GFP_NOFAIL);
/*
* First copy over the btree block header.
*/
@@ -510,7 +510,7 @@ xfs_idata_realloc(
if (byte_diff) {
ifp->if_data = krealloc(ifp->if_data, new_size,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOFAIL);
if (new_size == 0)
ifp->if_data = NULL;
ifp->if_bytes = new_size;
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index de321ab9d..36dd06e63 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -1448,7 +1448,7 @@ __xfs_refcount_add(
blockcount);
ri = kmem_cache_alloc(xfs_refcount_intent_cache,
- GFP_NOFS | __GFP_NOFAIL);
+ GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&ri->ri_list);
ri->ri_type = type;
ri->ri_startblock = startblock;
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index 4731e10d2..e7681c7c8 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -2558,7 +2558,7 @@ __xfs_rmap_add(
bmap->br_blockcount,
bmap->br_state);
- ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+ ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&ri->ri_list);
ri->ri_type = type;
ri->ri_owner = owner;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 006/111] xfs: clean up remaining GFP_NOFS users
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (4 preceding siblings ...)
2024-05-22 2:50 ` [PATCH 005/111] xfs: use GFP_KERNEL in pure transaction contexts Darrick J. Wong
@ 2024-05-22 2:50 ` Darrick J. Wong
2024-05-22 2:50 ` [PATCH 007/111] xfs: use xfs_defer_alloc a bit more Darrick J. Wong
` (105 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:50 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 204fae32d5f7b9ac673d3d4f636dcef8697db2f0
These few remaining GFP_NOFS callers do not need to use GFP_NOFS at
all. They are only called from a non-transactional context or cannot
be accessed from memory reclaim due to other constraints. Hence they
can just use GFP_KERNEL.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_btree_staging.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 0828cc7e3..45ef6aba8 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -139,7 +139,7 @@ xfs_btree_stage_afakeroot(
ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE));
ASSERT(cur->bc_tp == NULL);
- nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_NOFS | __GFP_NOFAIL);
+ nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
nops->alloc_block = xfs_btree_fakeroot_alloc_block;
nops->free_block = xfs_btree_fakeroot_free_block;
@@ -220,7 +220,7 @@ xfs_btree_stage_ifakeroot(
ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
ASSERT(cur->bc_tp == NULL);
- nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_NOFS | __GFP_NOFAIL);
+ nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
nops->alloc_block = xfs_btree_fakeroot_alloc_block;
nops->free_block = xfs_btree_fakeroot_free_block;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 007/111] xfs: use xfs_defer_alloc a bit more
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (5 preceding siblings ...)
2024-05-22 2:50 ` [PATCH 006/111] xfs: clean up remaining GFP_NOFS users Darrick J. Wong
@ 2024-05-22 2:50 ` Darrick J. Wong
2024-05-22 2:50 ` [PATCH 008/111] xfs: Replace xfs_isilocked with xfs_assert_ilocked Darrick J. Wong
` (104 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:50 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 57b98393b812ddaf9cf33a0d57d70b25cabfed66
Noticed by inspection, simple factoring allows the same allocation
routine to be used for both transaction and recovery contexts.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_defer.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index dae9ad57f..9f960bec4 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -813,7 +813,7 @@ xfs_defer_can_append(
/* Create a new pending item at the end of the transaction list. */
static inline struct xfs_defer_pending *
xfs_defer_alloc(
- struct xfs_trans *tp,
+ struct list_head *dfops,
const struct xfs_defer_op_type *ops)
{
struct xfs_defer_pending *dfp;
@@ -822,7 +822,7 @@ xfs_defer_alloc(
GFP_KERNEL | __GFP_NOFAIL);
dfp->dfp_ops = ops;
INIT_LIST_HEAD(&dfp->dfp_work);
- list_add_tail(&dfp->dfp_list, &tp->t_dfops);
+ list_add_tail(&dfp->dfp_list, dfops);
return dfp;
}
@@ -840,7 +840,7 @@ xfs_defer_add(
dfp = xfs_defer_find_last(tp, ops);
if (!dfp || !xfs_defer_can_append(dfp, ops))
- dfp = xfs_defer_alloc(tp, ops);
+ dfp = xfs_defer_alloc(&tp->t_dfops, ops);
xfs_defer_add_item(dfp, li);
trace_xfs_defer_add_item(tp->t_mountp, dfp, li);
@@ -864,7 +864,7 @@ xfs_defer_add_barrier(
if (dfp)
return;
- xfs_defer_alloc(tp, &xfs_barrier_defer_type);
+ xfs_defer_alloc(&tp->t_dfops, &xfs_barrier_defer_type);
trace_xfs_defer_add_item(tp->t_mountp, dfp, NULL);
}
@@ -879,14 +879,9 @@ xfs_defer_start_recovery(
struct list_head *r_dfops,
const struct xfs_defer_op_type *ops)
{
- struct xfs_defer_pending *dfp;
+ struct xfs_defer_pending *dfp = xfs_defer_alloc(r_dfops, ops);
- dfp = kmem_cache_zalloc(xfs_defer_pending_cache,
- GFP_KERNEL | __GFP_NOFAIL);
- dfp->dfp_ops = ops;
dfp->dfp_intent = lip;
- INIT_LIST_HEAD(&dfp->dfp_work);
- list_add_tail(&dfp->dfp_list, r_dfops);
}
/*
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 008/111] xfs: Replace xfs_isilocked with xfs_assert_ilocked
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (6 preceding siblings ...)
2024-05-22 2:50 ` [PATCH 007/111] xfs: use xfs_defer_alloc a bit more Darrick J. Wong
@ 2024-05-22 2:50 ` Darrick J. Wong
2024-05-22 2:51 ` [PATCH 009/111] xfs: create a static name for the dot entry too Darrick J. Wong
` (103 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:50 UTC (permalink / raw)
To: djwong, cem
Cc: Dave Chinner, Matthew Wilcox (Oracle), Chandan Babu R, linux-xfs
From: Matthew Wilcox (Oracle) <willy@infradead.org>
Source kernel commit: 3fed24fffc76dd1a8105db558e98bc8355d60379
To use the new rwsem_assert_held()/rwsem_assert_held_write(), we can't
use the existing ASSERT macro. Add a new xfs_assert_ilocked() and
convert all the callers.
Fix an apparent bug in xfs_isilocked(): If the caller specifies
XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL, xfs_assert_ilocked() will check both
the IOLOCK and the ILOCK are held for write. xfs_isilocked() only
checked that the ILOCK was held for write.
xfs_assert_ilocked() is always on, even if DEBUG or XFS_WARN aren't
defined. It's a cheap check, so I don't think it's worth defining
it away.
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/libxfs_priv.h | 1 +
libxfs/xfs_attr.c | 2 +-
libxfs/xfs_attr_remote.c | 2 +-
libxfs/xfs_bmap.c | 21 ++++++++++-----------
libxfs/xfs_defer.c | 2 +-
libxfs/xfs_inode_fork.c | 2 +-
libxfs/xfs_rtbitmap.c | 2 +-
libxfs/xfs_trans_inode.c | 6 +++---
8 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 705b66bed..0a4f686d9 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -406,6 +406,7 @@ void __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa);
__mode = __mode; /* no set-but-unused warning */ \
})
#define xfs_lock_two_inodes(ip0,mode0,ip1,mode1) ((void) 0)
+#define xfs_assert_ilocked(ip, flags) ((void) 0)
/* space allocation */
#define XFS_EXTENT_BUSY_DISCARDED 0x01 /* undergoing a discard op. */
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 8356d4a3c..caf04daa7 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -222,7 +222,7 @@ int
xfs_attr_get_ilocked(
struct xfs_da_args *args)
{
- ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
if (!xfs_inode_hasattr(args->dp))
return -ENOATTR;
diff --git a/libxfs/xfs_attr_remote.c b/libxfs/xfs_attr_remote.c
index 4f2b93f81..12d1ba9c3 100644
--- a/libxfs/xfs_attr_remote.c
+++ b/libxfs/xfs_attr_remote.c
@@ -544,7 +544,7 @@ xfs_attr_rmtval_stale(
struct xfs_buf *bp;
int error;
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
if (XFS_IS_CORRUPT(mp, map->br_startblock == DELAYSTARTBLOCK) ||
XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK))
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index ee4e6c766..4f616a547 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -1183,7 +1183,7 @@ xfs_iread_extents(
if (!xfs_need_iread_extents(ifp))
return 0;
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
ir.loaded = 0;
xfs_iext_first(ifp, &ir.icur);
@@ -3892,7 +3892,7 @@ xfs_bmapi_read(
ASSERT(*nmap >= 1);
ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_ENTIRE)));
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
if (WARN_ON_ONCE(!ifp))
return -EFSCORRUPTED;
@@ -4363,7 +4363,7 @@ xfs_bmapi_write(
ASSERT(tp != NULL);
ASSERT(len > 0);
ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL);
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
ASSERT(!(flags & XFS_BMAPI_REMAP));
/* zeroing is for currently only for data extents, not metadata */
@@ -4660,7 +4660,7 @@ xfs_bmapi_remap(
ifp = xfs_ifork_ptr(ip, whichfork);
ASSERT(len > 0);
ASSERT(len <= (xfs_filblks_t)XFS_MAX_BMBT_EXTLEN);
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC |
XFS_BMAPI_NORMAP)));
ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) !=
@@ -5285,7 +5285,7 @@ __xfs_bunmapi(
if (xfs_is_shutdown(mp))
return -EIO;
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
ASSERT(len > 0);
ASSERT(nexts >= 0);
@@ -5629,8 +5629,7 @@ xfs_bmse_merge(
blockcount = left->br_blockcount + got->br_blockcount;
- ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
ASSERT(xfs_bmse_can_merge(left, got, shift));
new = *left;
@@ -5758,7 +5757,7 @@ xfs_bmap_collapse_extents(
if (xfs_is_shutdown(mp))
return -EIO;
- ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
error = xfs_iread_extents(tp, ip, whichfork);
if (error)
@@ -5831,7 +5830,7 @@ xfs_bmap_can_insert_extents(
int is_empty;
int error = 0;
- ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL);
if (xfs_is_shutdown(ip->i_mount))
return -EIO;
@@ -5873,7 +5872,7 @@ xfs_bmap_insert_extents(
if (xfs_is_shutdown(mp))
return -EIO;
- ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
error = xfs_iread_extents(tp, ip, whichfork);
if (error)
@@ -6251,7 +6250,7 @@ xfs_bunmapi_range(
xfs_filblks_t unmap_len = endoff - startoff + 1;
int error = 0;
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
while (unmap_len > 0) {
ASSERT((*tpp)->t_highest_agno == NULLAGNUMBER);
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index 9f960bec4..b80ac04ab 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -1000,7 +1000,7 @@ xfs_defer_ops_capture(
* transaction.
*/
for (i = 0; i < dfc->dfc_held.dr_inos; i++) {
- ASSERT(xfs_isilocked(dfc->dfc_held.dr_ip[i], XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(dfc->dfc_held.dr_ip[i], XFS_ILOCK_EXCL);
ihold(VFS_I(dfc->dfc_held.dr_ip[i]));
}
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index f8f6a7364..6d8175723 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -563,7 +563,7 @@ xfs_iextents_copy(
struct xfs_bmbt_irec rec;
int64_t copied = 0;
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED);
ASSERT(ifp->if_bytes > 0);
for_each_xfs_iext(ifp, &icur, &rec) {
diff --git a/libxfs/xfs_rtbitmap.c b/libxfs/xfs_rtbitmap.c
index 08a4128fc..146e06bd8 100644
--- a/libxfs/xfs_rtbitmap.c
+++ b/libxfs/xfs_rtbitmap.c
@@ -932,7 +932,7 @@ xfs_rtfree_extent(
struct timespec64 atime;
ASSERT(mp->m_rbmip->i_itemp != NULL);
- ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL);
error = xfs_rtcheck_alloc_range(&args, start, len);
if (error)
diff --git a/libxfs/xfs_trans_inode.c b/libxfs/xfs_trans_inode.c
index c171a525c..f8484eb20 100644
--- a/libxfs/xfs_trans_inode.c
+++ b/libxfs/xfs_trans_inode.c
@@ -28,7 +28,7 @@ xfs_trans_ijoin(
{
struct xfs_inode_log_item *iip;
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
if (ip->i_itemp == NULL)
xfs_inode_item_init(ip, ip->i_mount);
iip = ip->i_itemp;
@@ -57,7 +57,7 @@ xfs_trans_ichgtime(
struct timespec64 tv;
ASSERT(tp);
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
tv = current_time(inode);
@@ -87,7 +87,7 @@ xfs_trans_log_inode(
struct inode *inode = VFS_I(ip);
ASSERT(iip);
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
ASSERT(!xfs_iflags_test(ip, XFS_ISTALE));
tp->t_flags |= XFS_TRANS_DIRTY;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 009/111] xfs: create a static name for the dot entry too
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (7 preceding siblings ...)
2024-05-22 2:50 ` [PATCH 008/111] xfs: Replace xfs_isilocked with xfs_assert_ilocked Darrick J. Wong
@ 2024-05-22 2:51 ` Darrick J. Wong
2024-05-22 2:51 ` [PATCH 010/111] xfs: create a predicate to determine if two xfs_names are the same Darrick J. Wong
` (102 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:51 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: e99bfc9e687e208d4ba7e85167b8753e80cf4169
Create an xfs_name_dot object so that upcoming scrub code can compare
against that. Offline repair already has such an object, so we're
really just hoisting it to the kernel.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_dir2.c | 6 ++++++
libxfs/xfs_dir2.h | 1 +
repair/phase6.c | 4 ----
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index 914c75107..ac372bf2a 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -24,6 +24,12 @@ const struct xfs_name xfs_name_dotdot = {
.type = XFS_DIR3_FT_DIR,
};
+const struct xfs_name xfs_name_dot = {
+ .name = (const unsigned char *)".",
+ .len = 1,
+ .type = XFS_DIR3_FT_DIR,
+};
+
/*
* Convert inode mode to directory entry filetype
*/
diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h
index 19af22a16..7d7cd8d80 100644
--- a/libxfs/xfs_dir2.h
+++ b/libxfs/xfs_dir2.h
@@ -22,6 +22,7 @@ struct xfs_dir3_icfree_hdr;
struct xfs_dir3_icleaf_hdr;
extern const struct xfs_name xfs_name_dotdot;
+extern const struct xfs_name xfs_name_dot;
/*
* Convert inode mode to directory entry filetype
diff --git a/repair/phase6.c b/repair/phase6.c
index 36e71857f..ae8935a26 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -23,10 +23,6 @@ static struct cred zerocr;
static struct fsxattr zerofsx;
static xfs_ino_t orphanage_ino;
-static struct xfs_name xfs_name_dot = {(unsigned char *)".",
- 1,
- XFS_DIR3_FT_DIR};
-
/*
* Data structures used to keep track of directories where the ".."
* entries are updated. These must be rebuilt after the initial pass
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 010/111] xfs: create a predicate to determine if two xfs_names are the same
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (8 preceding siblings ...)
2024-05-22 2:51 ` [PATCH 009/111] xfs: create a static name for the dot entry too Darrick J. Wong
@ 2024-05-22 2:51 ` Darrick J. Wong
2024-05-22 2:51 ` [PATCH 011/111] xfs: create a macro for decoding ftypes in tracepoints Darrick J. Wong
` (101 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:51 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: d9c0775897147bab54410611ac2659a7477c770c
Create a simple predicate to determine if two xfs_names are the same
objects or have the exact same name. The comparison is always case
sensitive.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_dir2.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h
index 7d7cd8d80..8497d041f 100644
--- a/libxfs/xfs_dir2.h
+++ b/libxfs/xfs_dir2.h
@@ -24,6 +24,18 @@ struct xfs_dir3_icleaf_hdr;
extern const struct xfs_name xfs_name_dotdot;
extern const struct xfs_name xfs_name_dot;
+static inline bool
+xfs_dir2_samename(
+ const struct xfs_name *n1,
+ const struct xfs_name *n2)
+{
+ if (n1 == n2)
+ return true;
+ if (n1->len != n2->len)
+ return false;
+ return !memcmp(n1->name, n2->name, n1->len);
+}
+
/*
* Convert inode mode to directory entry filetype
*/
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 011/111] xfs: create a macro for decoding ftypes in tracepoints
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (9 preceding siblings ...)
2024-05-22 2:51 ` [PATCH 010/111] xfs: create a predicate to determine if two xfs_names are the same Darrick J. Wong
@ 2024-05-22 2:51 ` Darrick J. Wong
2024-05-22 2:51 ` [PATCH 012/111] xfs: report the health of quota counts Darrick J. Wong
` (100 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:51 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 3c79e6a87221e063064e3680946a8b4bcd9fe78d
Create the XFS_DIR3_FTYPE_STR macro so that we can report ftype as
strings instead of numbers in tracepoints.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_da_format.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h
index 24f9d1461..060e5c96b 100644
--- a/libxfs/xfs_da_format.h
+++ b/libxfs/xfs_da_format.h
@@ -159,6 +159,17 @@ struct xfs_da3_intnode {
#define XFS_DIR3_FT_MAX 9
+#define XFS_DIR3_FTYPE_STR \
+ { XFS_DIR3_FT_UNKNOWN, "unknown" }, \
+ { XFS_DIR3_FT_REG_FILE, "file" }, \
+ { XFS_DIR3_FT_DIR, "directory" }, \
+ { XFS_DIR3_FT_CHRDEV, "char" }, \
+ { XFS_DIR3_FT_BLKDEV, "block" }, \
+ { XFS_DIR3_FT_FIFO, "fifo" }, \
+ { XFS_DIR3_FT_SOCK, "sock" }, \
+ { XFS_DIR3_FT_SYMLINK, "symlink" }, \
+ { XFS_DIR3_FT_WHT, "whiteout" }
+
/*
* Byte offset in data block and shortform entry.
*/
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 012/111] xfs: report the health of quota counts
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (10 preceding siblings ...)
2024-05-22 2:51 ` [PATCH 011/111] xfs: create a macro for decoding ftypes in tracepoints Darrick J. Wong
@ 2024-05-22 2:51 ` Darrick J. Wong
2024-05-22 2:52 ` [PATCH 013/111] xfs: implement live quotacheck inode scan Darrick J. Wong
` (99 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:51 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 3d8f1426977f1bf10f867bcd26df6518ae6c2b2c
Report the health of quota counts.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_fs.h | 1 +
libxfs/xfs_health.h | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 636007386..711e0fc7e 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -195,6 +195,7 @@ struct xfs_fsop_geom {
#define XFS_FSOP_GEOM_SICK_PQUOTA (1 << 3) /* project quota */
#define XFS_FSOP_GEOM_SICK_RT_BITMAP (1 << 4) /* realtime bitmap */
#define XFS_FSOP_GEOM_SICK_RT_SUMMARY (1 << 5) /* realtime summary */
+#define XFS_FSOP_GEOM_SICK_QUOTACHECK (1 << 6) /* quota counts */
/* Output for XFS_FS_COUNTS */
typedef struct xfs_fsop_counts {
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index 6296993ff..5626e53b3 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -41,6 +41,7 @@ struct xfs_fsop_geom;
#define XFS_SICK_FS_UQUOTA (1 << 1) /* user quota */
#define XFS_SICK_FS_GQUOTA (1 << 2) /* group quota */
#define XFS_SICK_FS_PQUOTA (1 << 3) /* project quota */
+#define XFS_SICK_FS_QUOTACHECK (1 << 4) /* quota counts */
/* Observable health issues for realtime volume metadata. */
#define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */
@@ -77,7 +78,8 @@ struct xfs_fsop_geom;
#define XFS_SICK_FS_PRIMARY (XFS_SICK_FS_COUNTERS | \
XFS_SICK_FS_UQUOTA | \
XFS_SICK_FS_GQUOTA | \
- XFS_SICK_FS_PQUOTA)
+ XFS_SICK_FS_PQUOTA | \
+ XFS_SICK_FS_QUOTACHECK)
#define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \
XFS_SICK_RT_SUMMARY)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 013/111] xfs: implement live quotacheck inode scan
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (11 preceding siblings ...)
2024-05-22 2:51 ` [PATCH 012/111] xfs: report the health of quota counts Darrick J. Wong
@ 2024-05-22 2:52 ` Darrick J. Wong
2024-05-22 2:52 ` [PATCH 014/111] xfs: report health of inode link counts Darrick J. Wong
` (98 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:52 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 48dd9117a34fe9a34a6be0b1dba5694e0f19cbd4
Create a new trio of scrub functions to check quota counters. While the
dquots themselves are filesystem metadata and should be checked early,
the dquot counter values are computed from other metadata and are
therefore summary counters. We don't plug these into the scrub dispatch
just yet, because we still need to be able to watch quota updates while
doing our scan.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_fs.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 711e0fc7e..07acbed92 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -710,9 +710,10 @@ struct xfs_scrub_metadata {
#define XFS_SCRUB_TYPE_GQUOTA 22 /* group quotas */
#define XFS_SCRUB_TYPE_PQUOTA 23 /* project quotas */
#define XFS_SCRUB_TYPE_FSCOUNTERS 24 /* fs summary counters */
+#define XFS_SCRUB_TYPE_QUOTACHECK 25 /* quota counters */
/* Number of scrub subcommands. */
-#define XFS_SCRUB_TYPE_NR 25
+#define XFS_SCRUB_TYPE_NR 26
/* i: Repair this metadata. */
#define XFS_SCRUB_IFLAG_REPAIR (1u << 0)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 014/111] xfs: report health of inode link counts
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (12 preceding siblings ...)
2024-05-22 2:52 ` [PATCH 013/111] xfs: implement live quotacheck inode scan Darrick J. Wong
@ 2024-05-22 2:52 ` Darrick J. Wong
2024-05-22 2:52 ` [PATCH 015/111] xfs: teach scrub to check file nlinks Darrick J. Wong
` (97 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:52 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 93687ee2e3748a4a6b541ff0d83d1480815b00a9
Report on the health of the inode link counts.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_fs.h | 1 +
libxfs/xfs_health.h | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 07acbed92..f10d0aa0e 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -196,6 +196,7 @@ struct xfs_fsop_geom {
#define XFS_FSOP_GEOM_SICK_RT_BITMAP (1 << 4) /* realtime bitmap */
#define XFS_FSOP_GEOM_SICK_RT_SUMMARY (1 << 5) /* realtime summary */
#define XFS_FSOP_GEOM_SICK_QUOTACHECK (1 << 6) /* quota counts */
+#define XFS_FSOP_GEOM_SICK_NLINKS (1 << 7) /* inode link counts */
/* Output for XFS_FS_COUNTS */
typedef struct xfs_fsop_counts {
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index 5626e53b3..2bfe2dc40 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -42,6 +42,7 @@ struct xfs_fsop_geom;
#define XFS_SICK_FS_GQUOTA (1 << 2) /* group quota */
#define XFS_SICK_FS_PQUOTA (1 << 3) /* project quota */
#define XFS_SICK_FS_QUOTACHECK (1 << 4) /* quota counts */
+#define XFS_SICK_FS_NLINKS (1 << 5) /* inode link counts */
/* Observable health issues for realtime volume metadata. */
#define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */
@@ -79,7 +80,8 @@ struct xfs_fsop_geom;
XFS_SICK_FS_UQUOTA | \
XFS_SICK_FS_GQUOTA | \
XFS_SICK_FS_PQUOTA | \
- XFS_SICK_FS_QUOTACHECK)
+ XFS_SICK_FS_QUOTACHECK | \
+ XFS_SICK_FS_NLINKS)
#define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \
XFS_SICK_RT_SUMMARY)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 015/111] xfs: teach scrub to check file nlinks
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (13 preceding siblings ...)
2024-05-22 2:52 ` [PATCH 014/111] xfs: report health of inode link counts Darrick J. Wong
@ 2024-05-22 2:52 ` Darrick J. Wong
2024-05-22 2:52 ` [PATCH 016/111] xfs: separate the marking of sick and checked metadata Darrick J. Wong
` (96 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:52 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: f1184081ac97625d30c59851944f4c59ae7ddc2b
Create the necessary scrub code to walk the filesystem's directory tree
so that we can compute file link counts. Similar to quotacheck, we
create an incore shadow array of link count information and then we walk
the filesystem a second time to compare the link counts. We need live
updates to keep the information up to date during the lengthy scan, so
this scrubber remains disabled until the next patch.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_fs.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index f10d0aa0e..515cd27d3 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -712,9 +712,10 @@ struct xfs_scrub_metadata {
#define XFS_SCRUB_TYPE_PQUOTA 23 /* project quotas */
#define XFS_SCRUB_TYPE_FSCOUNTERS 24 /* fs summary counters */
#define XFS_SCRUB_TYPE_QUOTACHECK 25 /* quota counters */
+#define XFS_SCRUB_TYPE_NLINKS 26 /* inode link counts */
/* Number of scrub subcommands. */
-#define XFS_SCRUB_TYPE_NR 26
+#define XFS_SCRUB_TYPE_NR 27
/* i: Repair this metadata. */
#define XFS_SCRUB_IFLAG_REPAIR (1u << 0)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 016/111] xfs: separate the marking of sick and checked metadata
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (14 preceding siblings ...)
2024-05-22 2:52 ` [PATCH 015/111] xfs: teach scrub to check file nlinks Darrick J. Wong
@ 2024-05-22 2:52 ` Darrick J. Wong
2024-05-22 2:53 ` [PATCH 017/111] xfs: report fs corruption errors to the health tracking system Darrick J. Wong
` (95 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:52 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 0b8686f19879d896bbe2d3e893f433a08160452d
Split the setting of the sick and checked masks into separate functions
as part of preparing to add the ability for regular runtime fs code
(i.e. not scrub) to mark metadata structures sick when corruptions are
found. Improve the documentation of libxfs' requirements for helper
behavior.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_health.h | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index 2bfe2dc40..bec7adf9f 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -111,24 +111,45 @@ struct xfs_fsop_geom;
XFS_SICK_INO_DIR_ZAPPED | \
XFS_SICK_INO_SYMLINK_ZAPPED)
-/* These functions must be provided by the xfs implementation. */
+/*
+ * These functions must be provided by the xfs implementation. Function
+ * behavior with respect to the first argument should be as follows:
+ *
+ * xfs_*_mark_sick: Set the sick flags and do not set checked flags.
+ * Runtime code should call this upon encountering
+ * a corruption.
+ *
+ * xfs_*_mark_corrupt: Set the sick and checked flags simultaneously.
+ * Fsck tools should call this when corruption is
+ * found.
+ *
+ * xfs_*_mark_healthy: Clear the sick flags and set the checked flags.
+ * Fsck tools should call this after correcting errors.
+ *
+ * xfs_*_measure_sickness: Return the sick and check status in the provided
+ * out parameters.
+ */
void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask);
+void xfs_fs_mark_corrupt(struct xfs_mount *mp, unsigned int mask);
void xfs_fs_mark_healthy(struct xfs_mount *mp, unsigned int mask);
void xfs_fs_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
unsigned int *checked);
void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask);
+void xfs_rt_mark_corrupt(struct xfs_mount *mp, unsigned int mask);
void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask);
void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
unsigned int *checked);
void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask);
+void xfs_ag_mark_corrupt(struct xfs_perag *pag, unsigned int mask);
void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask);
void xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick,
unsigned int *checked);
void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask);
+void xfs_inode_mark_corrupt(struct xfs_inode *ip, unsigned int mask);
void xfs_inode_mark_healthy(struct xfs_inode *ip, unsigned int mask);
void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
unsigned int *checked);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 017/111] xfs: report fs corruption errors to the health tracking system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (15 preceding siblings ...)
2024-05-22 2:52 ` [PATCH 016/111] xfs: separate the marking of sick and checked metadata Darrick J. Wong
@ 2024-05-22 2:53 ` Darrick J. Wong
2024-05-22 2:53 ` [PATCH 018/111] xfs: report ag header " Darrick J. Wong
` (94 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:53 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 50645ce8822d23ae3e002d3bee775fa8c315f957
Whenever we encounter corrupt fs metadata, we should report that to the
health monitoring system for later reporting. A convenient program for
identifying places to insert xfs_*_mark_sick calls is as follows:
#!/bin/bash
# Detect missing calls to xfs_*_mark_sick
filter=cat
tty -s && filter=less
git grep -B3 EFSCORRUPTED fs/xfs/*.[ch] fs/xfs/libxfs/*.[ch] fs/xfs/scrub/*.[ch] | awk '
BEGIN {
ignore = 0;
lineno = 0;
delete lines;
}
{
if ($0 == "--") {
if (!ignore) {
for (i = 0; i < lineno; i++) {
print(lines[i]);
}
printf("--\n");
}
delete lines;
lineno = 0;
ignore = 0;
} else if ($0 ~ /mark_sick/) {
ignore = 1;
} else if ($0 ~ /if .fa/) {
ignore = 1;
} else if ($0 ~ /failaddr/) {
ignore = 1;
} else if ($0 ~ /_verifier_error/) {
ignore = 1;
} else if ($0 ~ /^ \* .*EFSCORRUPTED/) {
ignore = 1;
} else if ($0 ~ /== -EFSCORRUPTED/) {
ignore = 1;
} else if ($0 ~ /!= -EFSCORRUPTED/) {
ignore = 1;
} else {
lines[lineno++] = $0;
}
}
' | $filter
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 1 +
libxfs/xfs_ag.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/libxfs/util.c b/libxfs/util.c
index 8cea0c150..26339171f 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -728,3 +728,4 @@ xfs_fs_mark_healthy(
}
void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo) { }
+void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask) { }
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 86024ddfd..e001ac11c 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -215,6 +215,7 @@ xfs_initialize_perag_data(
*/
if (fdblocks > sbp->sb_dblocks || ifree > ialloc) {
xfs_alert(mp, "AGF corruption. Please run xfs_repair.");
+ xfs_fs_mark_sick(mp, XFS_SICK_FS_COUNTERS);
error = -EFSCORRUPTED;
goto out;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 018/111] xfs: report ag header corruption errors to the health tracking system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (16 preceding siblings ...)
2024-05-22 2:53 ` [PATCH 017/111] xfs: report fs corruption errors to the health tracking system Darrick J. Wong
@ 2024-05-22 2:53 ` Darrick J. Wong
2024-05-22 2:53 ` [PATCH 019/111] xfs: report block map " Darrick J. Wong
` (93 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:53 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: de6077ec4198b9313c6e09e4c6acbe9179d057c1
Whenever we encounter a corrupt AG header, we should report that to the
health monitoring system for later reporting. Buffer readers that don't
respond to corruption events with a _mark_sick call can be detected with
the following script:
#!/bin/bash
# Detect missing calls to xfs_*_mark_sick
filter=cat
tty -s && filter=less
git grep -A10 -E '( = xfs_trans_read_buf| = xfs_buf_read\()' fs/xfs/*.[ch] fs/xfs/libxfs/*.[ch] | awk '
BEGIN {
ignore = 0;
lineno = 0;
delete lines;
}
{
if ($0 == "--") {
if (!ignore) {
for (i = 0; i < lineno; i++) {
print(lines[i]);
}
printf("--\n");
}
delete lines;
lineno = 0;
ignore = 0;
} else if ($0 ~ /mark_sick/) {
ignore = 1;
} else {
lines[lineno++] = $0;
}
}
' | $filter
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 3 +++
libxfs/xfs_alloc.c | 6 ++++++
libxfs/xfs_health.h | 13 ++++++++++---
libxfs/xfs_ialloc.c | 3 +++
libxfs/xfs_sb.c | 2 ++
5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/libxfs/util.c b/libxfs/util.c
index 26339171f..c30d83a8d 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -729,3 +729,6 @@ xfs_fs_mark_healthy(
void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo) { }
void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask) { }
+void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
+ unsigned int mask) { }
+void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask) { }
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 352efbeca..1894a0913 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -22,6 +22,7 @@
#include "xfs_ag.h"
#include "xfs_ag_resv.h"
#include "xfs_bmap.h"
+#include "xfs_health.h"
struct kmem_cache *xfs_extfree_item_cache;
@@ -751,6 +752,8 @@ xfs_alloc_read_agfl(
mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGFL_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_AGFL);
if (error)
return error;
xfs_buf_set_ref(bp, XFS_AGFL_REF);
@@ -772,6 +775,7 @@ xfs_alloc_update_counters(
if (unlikely(be32_to_cpu(agf->agf_freeblks) >
be32_to_cpu(agf->agf_length))) {
xfs_buf_mark_corrupt(agbp);
+ xfs_ag_mark_sick(agbp->b_pag, XFS_SICK_AG_AGF);
return -EFSCORRUPTED;
}
@@ -3264,6 +3268,8 @@ xfs_read_agf(
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGF_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), flags, agfbpp, &xfs_agf_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF);
if (error)
return error;
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index bec7adf9f..fb3f2b490 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -26,9 +26,11 @@
* and the "sick" field tells us if that piece was found to need repairs.
* Therefore we can conclude that for a given sick flag value:
*
- * - checked && sick => metadata needs repair
- * - checked && !sick => metadata is ok
- * - !checked => has not been examined since mount
+ * - checked && sick => metadata needs repair
+ * - checked && !sick => metadata is ok
+ * - !checked && sick => errors have been observed during normal operation,
+ * but the metadata has not been checked thoroughly
+ * - !checked && !sick => has not been examined since mount
*/
struct xfs_mount;
@@ -142,6 +144,8 @@ void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask);
void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
unsigned int *checked);
+void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
+ unsigned int mask);
void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask);
void xfs_ag_mark_corrupt(struct xfs_perag *pag, unsigned int mask);
void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask);
@@ -222,4 +226,7 @@ void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs);
+#define xfs_metadata_is_sick(error) \
+ (unlikely((error) == -EFSCORRUPTED || (error) == -EFSBADCRC))
+
#endif /* __XFS_HEALTH_H__ */
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 5ff09c8c9..c801250a3 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -22,6 +22,7 @@
#include "xfs_trace.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
/*
* Lookup a record by ino in the btree given by cur.
@@ -2599,6 +2600,8 @@ xfs_read_agi(
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGI_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), 0, agibpp, &xfs_agi_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
if (error)
return error;
if (tp)
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 402f03a55..00b0a937d 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -1288,6 +1288,8 @@ xfs_sb_read_secondary(
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_sb_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_SB);
if (error)
return error;
xfs_buf_set_ref(bp, XFS_SSB_REF);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 019/111] xfs: report block map corruption errors to the health tracking system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (17 preceding siblings ...)
2024-05-22 2:53 ` [PATCH 018/111] xfs: report ag header " Darrick J. Wong
@ 2024-05-22 2:53 ` Darrick J. Wong
2024-05-22 2:53 ` [PATCH 020/111] xfs: report btree block corruption errors to the health system Darrick J. Wong
` (92 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:53 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 1196f3f5abf736809cafac1696967ac318a44ca0
Whenever we encounter a corrupt block mapping, we should report that to
the health monitoring system for later reporting.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 1 +
libxfs/xfs_bmap.c | 35 +++++++++++++++++++++++++++++------
libxfs/xfs_health.h | 1 +
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/libxfs/util.c b/libxfs/util.c
index c30d83a8d..2403d64b4 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -732,3 +732,4 @@ void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask) { }
void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
unsigned int mask) { }
void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask) { }
+void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork) { }
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 4f616a547..4d21720e9 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -30,6 +30,7 @@
#include "xfs_ag_resv.h"
#include "xfs_refcount.h"
#include "xfs_rtbitmap.h"
+#include "xfs_health.h"
struct kmem_cache *xfs_bmap_intent_cache;
@@ -954,6 +955,7 @@ xfs_bmap_add_attrfork_local(
/* should only be called for types that support local format data */
ASSERT(0);
+ xfs_bmap_mark_sick(ip, XFS_ATTR_FORK);
return -EFSCORRUPTED;
}
@@ -1137,6 +1139,7 @@ xfs_iread_bmbt_block(
(unsigned long long)ip->i_ino);
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block,
sizeof(*block), __this_address);
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -1152,6 +1155,7 @@ xfs_iread_bmbt_block(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iread_extents(2)", frp,
sizeof(*frp), fa);
+ xfs_bmap_mark_sick(ip, whichfork);
return xfs_bmap_complain_bad_rec(ip, whichfork, fa,
&new);
}
@@ -1207,6 +1211,8 @@ xfs_iread_extents(
smp_store_release(&ifp->if_needextents, 0);
return 0;
out:
+ if (xfs_metadata_is_sick(error))
+ xfs_bmap_mark_sick(ip, whichfork);
xfs_iext_destroy(ifp);
return error;
}
@@ -1286,6 +1292,7 @@ xfs_bmap_last_before(
break;
default:
ASSERT(0);
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -3894,12 +3901,16 @@ xfs_bmapi_read(
ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_ENTIRE)));
xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
- if (WARN_ON_ONCE(!ifp))
+ if (WARN_ON_ONCE(!ifp)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
+ }
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
- XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT))
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
+ }
if (xfs_is_shutdown(mp))
return -EIO;
@@ -4380,6 +4391,7 @@ xfs_bmapi_write(
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -4607,9 +4619,11 @@ xfs_bmapi_convert_delalloc(
error = -ENOSPC;
if (WARN_ON_ONCE(bma.blkno == NULLFSBLOCK))
goto out_finish;
- error = -EFSCORRUPTED;
- if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock)))
+ if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock))) {
+ xfs_bmap_mark_sick(ip, whichfork);
+ error = -EFSCORRUPTED;
goto out_finish;
+ }
XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, bma.length));
XFS_STATS_INC(mp, xs_xstrat_quick);
@@ -4668,6 +4682,7 @@ xfs_bmapi_remap(
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -5280,8 +5295,10 @@ __xfs_bunmapi(
whichfork = xfs_bmapi_whichfork(flags);
ASSERT(whichfork != XFS_COW_FORK);
ifp = xfs_ifork_ptr(ip, whichfork);
- if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)))
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
+ }
if (xfs_is_shutdown(mp))
return -EIO;
@@ -5751,6 +5768,7 @@ xfs_bmap_collapse_extents(
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -5866,6 +5884,7 @@ xfs_bmap_insert_extents(
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -5969,6 +5988,7 @@ xfs_bmap_split_extent(
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
}
@@ -6151,8 +6171,10 @@ xfs_bmap_finish_one(
bmap->br_startoff, bmap->br_blockcount,
bmap->br_state);
- if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK))
+ if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) {
+ xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
return -EFSCORRUPTED;
+ }
if (XFS_TEST_ERROR(false, tp->t_mountp,
XFS_ERRTAG_BMAP_FINISH_ONE))
@@ -6170,6 +6192,7 @@ xfs_bmap_finish_one(
break;
default:
ASSERT(0);
+ xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
error = -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index fb3f2b490..3c8fd0607 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -159,6 +159,7 @@ void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
unsigned int *checked);
void xfs_health_unmount(struct xfs_mount *mp);
+void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork);
/* Now some helpers. */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 020/111] xfs: report btree block corruption errors to the health system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (18 preceding siblings ...)
2024-05-22 2:53 ` [PATCH 019/111] xfs: report block map " Darrick J. Wong
@ 2024-05-22 2:53 ` Darrick J. Wong
2024-05-22 2:54 ` [PATCH 021/111] xfs: report dir/attr " Darrick J. Wong
` (91 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:53 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: a78d10f45b23149f1b23019a4f4fb57dcf852e39
Whenever we encounter corrupt btree blocks, we should report that to the
health monitoring system for later reporting.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 1 +
libxfs/xfs_alloc.c | 2 ++
libxfs/xfs_bmap.c | 6 ++++++
libxfs/xfs_btree.c | 25 ++++++++++++++++++++++---
libxfs/xfs_health.h | 2 ++
libxfs/xfs_ialloc.c | 1 +
libxfs/xfs_refcount.c | 6 +++++-
libxfs/xfs_rmap.c | 6 +++++-
8 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/libxfs/util.c b/libxfs/util.c
index 2403d64b4..b45d67065 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -733,3 +733,4 @@ void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
unsigned int mask) { }
void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask) { }
void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork) { }
+void xfs_btree_mark_sick(struct xfs_btree_cur *cur) { }
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 1894a0913..aa084120c 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -271,6 +271,7 @@ xfs_alloc_complain_bad_rec(
xfs_warn(mp,
"start block 0x%x block count 0x%x", irec->ar_startblock,
irec->ar_blockcount);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
@@ -2698,6 +2699,7 @@ xfs_exact_minlen_extent_available(
goto out;
if (*stat == 0) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto out;
}
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 4d21720e9..f15631818 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -362,6 +362,8 @@ xfs_bmap_check_leaf_extents(
error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
XFS_BMAP_BTREE_REF,
&xfs_bmbt_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_btree_mark_sick(cur);
if (error)
goto error_norelse;
}
@@ -448,6 +450,8 @@ xfs_bmap_check_leaf_extents(
error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
XFS_BMAP_BTREE_REF,
&xfs_bmbt_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_btree_mark_sick(cur);
if (error)
goto error_norelse;
}
@@ -562,6 +566,8 @@ xfs_bmap_btree_to_extents(
#endif
error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
&xfs_bmbt_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_btree_mark_sick(cur);
if (error)
return error;
cblock = XFS_BUF_TO_BLOCK(cbp);
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 663439ec3..359d3f99e 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -24,6 +24,7 @@
#include "xfs_bmap_btree.h"
#include "xfs_rmap_btree.h"
#include "xfs_refcount_btree.h"
+#include "xfs_health.h"
/*
* Btree magic numbers.
@@ -174,6 +175,7 @@ xfs_btree_check_lblock(
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) {
if (bp)
trace_xfs_btree_corrupt(bp, _RET_IP_);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
return 0;
@@ -240,6 +242,7 @@ xfs_btree_check_sblock(
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) {
if (bp)
trace_xfs_btree_corrupt(bp, _RET_IP_);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
return 0;
@@ -315,6 +318,7 @@ xfs_btree_check_ptr(
level, index);
}
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
@@ -495,6 +499,8 @@ xfs_btree_dup_cursor(
xfs_buf_daddr(bp), mp->m_bsize,
0, &bp,
cur->bc_ops->buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_btree_mark_sick(new);
if (error) {
xfs_btree_del_cursor(new, error);
*ncur = NULL;
@@ -1348,6 +1354,8 @@ xfs_btree_read_buf_block(
error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
mp->m_bsize, flags, bpp,
cur->bc_ops->buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_btree_mark_sick(cur);
if (error)
return error;
@@ -1658,6 +1666,7 @@ xfs_btree_increment(
if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
goto out0;
ASSERT(0);
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1751,6 +1760,7 @@ xfs_btree_decrement(
if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
goto out0;
ASSERT(0);
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1843,6 +1853,7 @@ xfs_btree_lookup_get_block(
*blkp = NULL;
xfs_buf_mark_corrupt(bp);
xfs_trans_brelse(cur->bc_tp, bp);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
@@ -1889,8 +1900,10 @@ xfs_btree_lookup(
XFS_BTREE_STATS_INC(cur, lookup);
/* No such thing as a zero-level tree. */
- if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0))
+ if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
block = NULL;
keyno = 0;
@@ -1933,6 +1946,7 @@ xfs_btree_lookup(
XFS_ERRLEVEL_LOW,
cur->bc_mp, block,
sizeof(*block));
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
@@ -4366,12 +4380,16 @@ xfs_btree_visit_block(
*/
if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
if (be64_to_cpu(rptr.l) == XFS_DADDR_TO_FSB(cur->bc_mp,
- xfs_buf_daddr(bp)))
+ xfs_buf_daddr(bp))) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
} else {
if (be32_to_cpu(rptr.s) == xfs_daddr_to_agbno(cur->bc_mp,
- xfs_buf_daddr(bp)))
+ xfs_buf_daddr(bp))) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
}
return xfs_btree_lookup_get_block(cur, level, &rptr, &block);
}
@@ -5230,6 +5248,7 @@ xfs_btree_goto_left_edge(
return error;
if (stat != 0) {
ASSERT(0);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index 3c8fd0607..8f566a787 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -37,6 +37,7 @@ struct xfs_mount;
struct xfs_perag;
struct xfs_inode;
struct xfs_fsop_geom;
+struct xfs_btree_cur;
/* Observable health issues for metadata spanning the entire filesystem. */
#define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */
@@ -160,6 +161,7 @@ void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
void xfs_health_unmount(struct xfs_mount *mp);
void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork);
+void xfs_btree_mark_sick(struct xfs_btree_cur *cur);
/* Now some helpers. */
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index c801250a3..92ca3d460 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -143,6 +143,7 @@ xfs_inobt_complain_bad_rec(
"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x",
irec->ir_startino, irec->ir_count, irec->ir_freecount,
irec->ir_free, irec->ir_holemask);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index 36dd06e63..00df1e64a 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -22,6 +22,7 @@
#include "xfs_refcount.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
struct kmem_cache *xfs_refcount_intent_cache;
@@ -155,6 +156,7 @@ xfs_refcount_complain_bad_rec(
xfs_warn(mp,
"Start block 0x%x, block count 0x%x, references 0x%x",
irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
@@ -1888,8 +1890,10 @@ xfs_refcount_recover_extent(
struct xfs_refcount_recovery *rr;
if (XFS_IS_CORRUPT(cur->bc_mp,
- be32_to_cpu(rec->refc.rc_refcount) != 1))
+ be32_to_cpu(rec->refc.rc_refcount) != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
rr = kmalloc(sizeof(struct xfs_refcount_recovery),
GFP_KERNEL | __GFP_NOFAIL);
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index e7681c7c8..8fbc9583d 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -22,6 +22,7 @@
#include "xfs_errortag.h"
#include "xfs_inode.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
struct kmem_cache *xfs_rmap_intent_cache;
@@ -55,8 +56,10 @@ xfs_rmap_lookup_le(
error = xfs_rmap_get_rec(cur, irec, &get_stat);
if (error)
return error;
- if (!get_stat)
+ if (!get_stat) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
return 0;
}
@@ -276,6 +279,7 @@ xfs_rmap_complain_bad_rec(
"Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
irec->rm_owner, irec->rm_flags, irec->rm_startblock,
irec->rm_blockcount);
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 021/111] xfs: report dir/attr block corruption errors to the health system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (19 preceding siblings ...)
2024-05-22 2:53 ` [PATCH 020/111] xfs: report btree block corruption errors to the health system Darrick J. Wong
@ 2024-05-22 2:54 ` Darrick J. Wong
2024-05-22 2:54 ` [PATCH 022/111] xfs: report inode " Darrick J. Wong
` (90 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:54 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: ca14c0968c1f693ab4bcb5368c800c33e7a2ad7e
Whenever we encounter corrupt directory or extended attribute blocks, we
should report that to the health monitoring system for later reporting.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 2 ++
libxfs/xfs_attr_leaf.c | 4 ++++
libxfs/xfs_attr_remote.c | 27 ++++++++++++++++-----------
libxfs/xfs_da_btree.c | 37 ++++++++++++++++++++++++++++++++-----
libxfs/xfs_dir2.c | 5 ++++-
libxfs/xfs_dir2_block.c | 2 ++
libxfs/xfs_dir2_data.c | 3 +++
libxfs/xfs_dir2_leaf.c | 3 +++
libxfs/xfs_dir2_node.c | 7 +++++++
libxfs/xfs_health.h | 3 +++
10 files changed, 76 insertions(+), 17 deletions(-)
diff --git a/libxfs/util.c b/libxfs/util.c
index b45d67065..6c326e84a 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -734,3 +734,5 @@ void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask) { }
void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork) { }
void xfs_btree_mark_sick(struct xfs_btree_cur *cur) { }
+void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork) { }
+void xfs_da_mark_sick(struct xfs_da_args *args) { }
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index fdc53451c..a44312cdc 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -26,6 +26,7 @@
#include "xfs_dir2.h"
#include "xfs_ag.h"
#include "xfs_errortag.h"
+#include "xfs_health.h"
/*
@@ -2340,6 +2341,7 @@ xfs_attr3_leaf_lookup_int(
entries = xfs_attr3_leaf_entryp(leaf);
if (ichdr.count >= args->geo->blksize / 8) {
xfs_buf_mark_corrupt(bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
@@ -2359,10 +2361,12 @@ xfs_attr3_leaf_lookup_int(
}
if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
xfs_buf_mark_corrupt(bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
xfs_buf_mark_corrupt(bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_attr_remote.c b/libxfs/xfs_attr_remote.c
index 12d1ba9c3..a400a22d3 100644
--- a/libxfs/xfs_attr_remote.c
+++ b/libxfs/xfs_attr_remote.c
@@ -21,6 +21,7 @@
#include "xfs_attr.h"
#include "xfs_attr_remote.h"
#include "xfs_trace.h"
+#include "xfs_health.h"
#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
@@ -275,17 +276,18 @@ xfs_attr3_rmt_hdr_set(
*/
STATIC int
xfs_attr_rmtval_copyout(
- struct xfs_mount *mp,
- struct xfs_buf *bp,
- xfs_ino_t ino,
- int *offset,
- int *valuelen,
- uint8_t **dst)
+ struct xfs_mount *mp,
+ struct xfs_buf *bp,
+ struct xfs_inode *dp,
+ int *offset,
+ int *valuelen,
+ uint8_t **dst)
{
- char *src = bp->b_addr;
- xfs_daddr_t bno = xfs_buf_daddr(bp);
- int len = BBTOB(bp->b_length);
- int blksize = mp->m_attr_geo->blksize;
+ char *src = bp->b_addr;
+ xfs_ino_t ino = dp->i_ino;
+ xfs_daddr_t bno = xfs_buf_daddr(bp);
+ int len = BBTOB(bp->b_length);
+ int blksize = mp->m_attr_geo->blksize;
ASSERT(len >= blksize);
@@ -301,6 +303,7 @@ xfs_attr_rmtval_copyout(
xfs_alert(mp,
"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)",
bno, *offset, byte_cnt, ino);
+ xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
return -EFSCORRUPTED;
}
hdr_size = sizeof(struct xfs_attr3_rmt_hdr);
@@ -417,10 +420,12 @@ xfs_attr_rmtval_get(
dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
error = xfs_buf_read(mp->m_ddev_targp, dblkno, dblkcnt,
0, &bp, &xfs_attr3_rmt_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_dirattr_mark_sick(args->dp, XFS_ATTR_FORK);
if (error)
return error;
- error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino,
+ error = xfs_attr_rmtval_copyout(mp, bp, args->dp,
&offset, &valuelen,
&dst);
xfs_buf_relse(bp);
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 0fea72f33..8ace7622a 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -19,6 +19,7 @@
#include "xfs_bmap.h"
#include "xfs_attr_leaf.h"
#include "xfs_trace.h"
+#include "xfs_health.h"
/*
* xfs_da_btree.c
@@ -349,6 +350,8 @@ const struct xfs_buf_ops xfs_da3_node_buf_ops = {
static int
xfs_da3_node_set_type(
struct xfs_trans *tp,
+ struct xfs_inode *dp,
+ int whichfork,
struct xfs_buf *bp)
{
struct xfs_da_blkinfo *info = bp->b_addr;
@@ -370,6 +373,7 @@ xfs_da3_node_set_type(
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp,
info, sizeof(*info));
xfs_trans_brelse(tp, bp);
+ xfs_dirattr_mark_sick(dp, whichfork);
return -EFSCORRUPTED;
}
}
@@ -388,7 +392,7 @@ xfs_da3_node_read(
&xfs_da3_node_buf_ops);
if (error || !*bpp || !tp)
return error;
- return xfs_da3_node_set_type(tp, *bpp);
+ return xfs_da3_node_set_type(tp, dp, whichfork, *bpp);
}
int
@@ -405,6 +409,8 @@ xfs_da3_node_read_mapped(
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno,
XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0,
bpp, &xfs_da3_node_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_dirattr_mark_sick(dp, whichfork);
if (error || !*bpp)
return error;
@@ -415,7 +421,7 @@ xfs_da3_node_read_mapped(
if (!tp)
return 0;
- return xfs_da3_node_set_type(tp, *bpp);
+ return xfs_da3_node_set_type(tp, dp, whichfork, *bpp);
}
/*
@@ -628,6 +634,7 @@ xfs_da3_split(
if (node->hdr.info.forw) {
if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
xfs_buf_mark_corrupt(oldblk->bp);
+ xfs_da_mark_sick(state->args);
error = -EFSCORRUPTED;
goto out;
}
@@ -641,6 +648,7 @@ xfs_da3_split(
if (node->hdr.info.back) {
if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
xfs_buf_mark_corrupt(oldblk->bp);
+ xfs_da_mark_sick(state->args);
error = -EFSCORRUPTED;
goto out;
}
@@ -1632,6 +1640,7 @@ xfs_da3_node_lookup_int(
if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {
xfs_buf_mark_corrupt(blk->bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
@@ -1647,6 +1656,7 @@ xfs_da3_node_lookup_int(
/* Tree taller than we can handle; bail out! */
if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
xfs_buf_mark_corrupt(blk->bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
@@ -1655,6 +1665,7 @@ xfs_da3_node_lookup_int(
expected_level = nodehdr.level - 1;
else if (expected_level != nodehdr.level) {
xfs_buf_mark_corrupt(blk->bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
} else
expected_level--;
@@ -1706,12 +1717,16 @@ xfs_da3_node_lookup_int(
}
/* We can't point back to the root. */
- if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk))
+ if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk)) {
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
+ }
}
- if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0))
+ if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0)) {
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
+ }
/*
* A leaf block that ends in the hashval that we are interested in
@@ -1729,6 +1744,7 @@ xfs_da3_node_lookup_int(
args->blkno = blk->blkno;
} else {
ASSERT(0);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
if (((retval == -ENOENT) || (retval == -ENOATTR)) &&
@@ -2295,8 +2311,10 @@ xfs_da3_swap_lastblock(
error = xfs_bmap_last_before(tp, dp, &lastoff, w);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, lastoff == 0))
+ if (XFS_IS_CORRUPT(mp, lastoff == 0)) {
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
+ }
/*
* Read the last block in the btree space.
*/
@@ -2346,6 +2364,7 @@ xfs_da3_swap_lastblock(
if (XFS_IS_CORRUPT(mp,
be32_to_cpu(sib_info->forw) != last_blkno ||
sib_info->magic != dead_info->magic)) {
+ xfs_da_mark_sick(args);
error = -EFSCORRUPTED;
goto done;
}
@@ -2366,6 +2385,7 @@ xfs_da3_swap_lastblock(
if (XFS_IS_CORRUPT(mp,
be32_to_cpu(sib_info->back) != last_blkno ||
sib_info->magic != dead_info->magic)) {
+ xfs_da_mark_sick(args);
error = -EFSCORRUPTED;
goto done;
}
@@ -2388,6 +2408,7 @@ xfs_da3_swap_lastblock(
xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
if (XFS_IS_CORRUPT(mp,
level >= 0 && level != par_hdr.level + 1)) {
+ xfs_da_mark_sick(args);
error = -EFSCORRUPTED;
goto done;
}
@@ -2399,6 +2420,7 @@ xfs_da3_swap_lastblock(
entno++)
continue;
if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) {
+ xfs_da_mark_sick(args);
error = -EFSCORRUPTED;
goto done;
}
@@ -2424,6 +2446,7 @@ xfs_da3_swap_lastblock(
xfs_trans_brelse(tp, par_buf);
par_buf = NULL;
if (XFS_IS_CORRUPT(mp, par_blkno == 0)) {
+ xfs_da_mark_sick(args);
error = -EFSCORRUPTED;
goto done;
}
@@ -2433,6 +2456,7 @@ xfs_da3_swap_lastblock(
par_node = par_buf->b_addr;
xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) {
+ xfs_da_mark_sick(args);
error = -EFSCORRUPTED;
goto done;
}
@@ -2563,6 +2587,7 @@ xfs_dabuf_map(
invalid_mapping:
/* Caller ok with no mapping. */
if (XFS_IS_CORRUPT(mp, !(flags & XFS_DABUF_MAP_HOLE_OK))) {
+ xfs_dirattr_mark_sick(dp, whichfork);
error = -EFSCORRUPTED;
if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
xfs_alert(mp, "%s: bno %u inode %llu",
@@ -2644,6 +2669,8 @@ xfs_da_read_buf(
error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0,
&bp, ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_dirattr_mark_sick(dp, whichfork);
if (error)
goto out_free;
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index ac372bf2a..530c3e22a 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -17,6 +17,7 @@
#include "xfs_dir2_priv.h"
#include "xfs_errortag.h"
#include "xfs_trace.h"
+#include "xfs_health.h"
const struct xfs_name xfs_name_dotdot = {
.name = (const unsigned char *)"..",
@@ -625,8 +626,10 @@ xfs_dir2_isblock(
return 0;
*isblock = true;
- if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize))
+ if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) {
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
+ }
return 0;
}
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index aed3c14a8..9d87735e7 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -17,6 +17,7 @@
#include "xfs_dir2.h"
#include "xfs_dir2_priv.h"
#include "xfs_trace.h"
+#include "xfs_health.h"
/*
* Local function prototypes.
@@ -149,6 +150,7 @@ xfs_dir3_block_read(
__xfs_buf_mark_corrupt(*bpp, fa);
xfs_trans_brelse(tp, *bpp);
*bpp = NULL;
+ xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index 4e207986b..aaf3f62af 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -15,6 +15,7 @@
#include "xfs_dir2.h"
#include "xfs_dir2_priv.h"
#include "xfs_trans.h"
+#include "xfs_health.h"
static xfs_failaddr_t xfs_dir2_data_freefind_verify(
struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
@@ -430,6 +431,7 @@ xfs_dir3_data_read(
__xfs_buf_mark_corrupt(*bpp, fa);
xfs_trans_brelse(tp, *bpp);
*bpp = NULL;
+ xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
return -EFSCORRUPTED;
}
@@ -1195,6 +1197,7 @@ xfs_dir2_data_use_free(
corrupt:
xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount,
hdr, sizeof(*hdr), __FILE__, __LINE__, fa);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index 5da66006c..80cea8a27 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -17,6 +17,7 @@
#include "xfs_dir2_priv.h"
#include "xfs_trace.h"
#include "xfs_trans.h"
+#include "xfs_health.h"
/*
* Local function declarations.
@@ -1391,8 +1392,10 @@ xfs_dir2_leaf_removename(
bestsp = xfs_dir2_leaf_bests_p(ltp);
if (be16_to_cpu(bestsp[db]) != oldbest) {
xfs_buf_mark_corrupt(lbp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
+
/*
* Mark the former data entry unused.
*/
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index c0eb335c3..44c8f3f2b 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -17,6 +17,7 @@
#include "xfs_dir2_priv.h"
#include "xfs_trace.h"
#include "xfs_trans.h"
+#include "xfs_health.h"
/*
* Function declarations.
@@ -228,6 +229,7 @@ __xfs_dir3_free_read(
__xfs_buf_mark_corrupt(*bpp, fa);
xfs_trans_brelse(tp, *bpp);
*bpp = NULL;
+ xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
return -EFSCORRUPTED;
}
@@ -440,6 +442,7 @@ xfs_dir2_leaf_to_node(
if (be32_to_cpu(ltp->bestcount) >
(uint)dp->i_disk_size / args->geo->blksize) {
xfs_buf_mark_corrupt(lbp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
@@ -514,6 +517,7 @@ xfs_dir2_leafn_add(
*/
if (index < 0) {
xfs_buf_mark_corrupt(bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
@@ -733,6 +737,7 @@ xfs_dir2_leafn_lookup_for_addname(
cpu_to_be16(NULLDATAOFF))) {
if (curfdb != newfdb)
xfs_trans_brelse(tp, curbp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
curfdb = newfdb;
@@ -801,6 +806,7 @@ xfs_dir2_leafn_lookup_for_entry(
xfs_dir3_leaf_check(dp, bp);
if (leafhdr.count <= 0) {
xfs_buf_mark_corrupt(bp);
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
@@ -1736,6 +1742,7 @@ xfs_dir2_node_add_datablk(
} else {
xfs_alert(mp, " ... fblk is NULL");
}
+ xfs_da_mark_sick(args);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index 8f566a787..ff98c0321 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -38,6 +38,7 @@ struct xfs_perag;
struct xfs_inode;
struct xfs_fsop_geom;
struct xfs_btree_cur;
+struct xfs_da_args;
/* Observable health issues for metadata spanning the entire filesystem. */
#define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */
@@ -162,6 +163,8 @@ void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
void xfs_health_unmount(struct xfs_mount *mp);
void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork);
void xfs_btree_mark_sick(struct xfs_btree_cur *cur);
+void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork);
+void xfs_da_mark_sick(struct xfs_da_args *args);
/* Now some helpers. */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 022/111] xfs: report inode corruption errors to the health system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (20 preceding siblings ...)
2024-05-22 2:54 ` [PATCH 021/111] xfs: report dir/attr " Darrick J. Wong
@ 2024-05-22 2:54 ` Darrick J. Wong
2024-05-22 2:54 ` [PATCH 023/111] xfs: report realtime metadata " Darrick J. Wong
` (89 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:54 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: baf44fa5c37a2357a7ae92889f74bc1824f33fd4
Whenever we encounter corrupt inode records, we should report that to
the health monitoring system for later reporting.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 1 +
libxfs/xfs_ialloc.c | 1 +
libxfs/xfs_inode_buf.c | 12 +++++++++---
libxfs/xfs_inode_fork.c | 8 ++++++++
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/libxfs/util.c b/libxfs/util.c
index 6c326e84a..6d8847363 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -736,3 +736,4 @@ void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork) { }
void xfs_btree_mark_sick(struct xfs_btree_cur *cur) { }
void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork) { }
void xfs_da_mark_sick(struct xfs_da_args *args) { }
+void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask) { }
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 92ca3d460..63922f44f 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -2994,6 +2994,7 @@ xfs_ialloc_check_shrink(
goto out;
if (!has) {
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_INOBT);
error = -EFSCORRUPTED;
goto out;
}
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index fd351c252..83d936981 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -16,6 +16,7 @@
#include "xfs_trans.h"
#include "xfs_ialloc.h"
#include "xfs_dir2.h"
+#include "xfs_health.h"
/*
@@ -129,9 +130,14 @@ xfs_imap_to_bp(
struct xfs_imap *imap,
struct xfs_buf **bpp)
{
- return xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
- imap->im_len, XBF_UNMAPPED, bpp,
- &xfs_inode_buf_ops);
+ int error;
+
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
+ imap->im_len, XBF_UNMAPPED, bpp, &xfs_inode_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, imap->im_blkno),
+ XFS_SICK_AG_INOBT);
+ return error;
}
static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts)
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 6d8175723..53ff82678 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -23,6 +23,7 @@
#include "xfs_attr_leaf.h"
#include "xfs_types.h"
#include "xfs_errortag.h"
+#include "xfs_health.h"
struct kmem_cache *xfs_ifork_cache;
@@ -86,6 +87,7 @@ xfs_iformat_local(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_local", dip, sizeof(*dip),
__this_address);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED;
}
@@ -123,6 +125,7 @@ xfs_iformat_extents(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_extents(1)", dip, sizeof(*dip),
__this_address);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED;
}
@@ -142,6 +145,7 @@ xfs_iformat_extents(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_extents(2)",
dp, sizeof(*dp), fa);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return xfs_bmap_complain_bad_rec(ip, whichfork,
fa, &new);
}
@@ -200,6 +204,7 @@ xfs_iformat_btree(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_btree", dfp, size,
__this_address);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED;
}
@@ -265,12 +270,14 @@ xfs_iformat_data_fork(
default:
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
dip, sizeof(*dip), __this_address);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED;
}
break;
default:
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
sizeof(*dip), __this_address);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED;
}
}
@@ -342,6 +349,7 @@ xfs_iformat_attr_fork(
default:
xfs_inode_verifier_error(ip, error, __func__, dip,
sizeof(*dip), __this_address);
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
error = -EFSCORRUPTED;
break;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 023/111] xfs: report realtime metadata corruption errors to the health system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (21 preceding siblings ...)
2024-05-22 2:54 ` [PATCH 022/111] xfs: report inode " Darrick J. Wong
@ 2024-05-22 2:54 ` Darrick J. Wong
2024-05-22 2:55 ` [PATCH 024/111] xfs: report XFS_IS_CORRUPT " Darrick J. Wong
` (88 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:54 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 8368ad49aaf771a6283840140149440b958b20fb
Whenever we encounter corrupt realtime metadat blocks, we should report
that to the health monitoring system for later reporting.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/util.c | 1 +
libxfs/xfs_rtbitmap.c | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libxfs/util.c b/libxfs/util.c
index 6d8847363..841f4b963 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -737,3 +737,4 @@ void xfs_btree_mark_sick(struct xfs_btree_cur *cur) { }
void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork) { }
void xfs_da_mark_sick(struct xfs_da_args *args) { }
void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask) { }
+void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask) { }
diff --git a/libxfs/xfs_rtbitmap.c b/libxfs/xfs_rtbitmap.c
index 146e06bd8..543cfd2fb 100644
--- a/libxfs/xfs_rtbitmap.c
+++ b/libxfs/xfs_rtbitmap.c
@@ -15,6 +15,7 @@
#include "xfs_bmap.h"
#include "xfs_trans.h"
#include "xfs_rtbitmap.h"
+#include "xfs_health.h"
/*
* Realtime allocator bitmap functions shared with userspace.
@@ -113,13 +114,19 @@ xfs_rtbuf_get(
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map)))
+ if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
+ xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
+ XFS_SICK_RT_BITMAP);
return -EFSCORRUPTED;
+ }
ASSERT(map.br_startblock != NULLFSBLOCK);
error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp,
XFS_FSB_TO_DADDR(mp, map.br_startblock),
mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
+ XFS_SICK_RT_BITMAP);
if (error)
return error;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 024/111] xfs: report XFS_IS_CORRUPT errors to the health system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (22 preceding siblings ...)
2024-05-22 2:54 ` [PATCH 023/111] xfs: report realtime metadata " Darrick J. Wong
@ 2024-05-22 2:55 ` Darrick J. Wong
2024-05-22 2:55 ` [PATCH 025/111] xfs: add secondary and indirect classes to the health tracking system Darrick J. Wong
` (87 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:55 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 989d5ec3175be7c0012d7744c667ae6a266fab06
Whenever we encounter XFS_IS_CORRUPT failures, we should report that to
the health monitoring system for later reporting.
I started with this semantic patch and massaged everything until it
built:
@@
expression mp, test;
@@
- if (XFS_IS_CORRUPT(mp, test)) return -EFSCORRUPTED;
+ if (XFS_IS_CORRUPT(mp, test)) { xfs_btree_mark_sick(cur); return -EFSCORRUPTED; }
@@
expression mp, test;
identifier label, error;
@@
- if (XFS_IS_CORRUPT(mp, test)) { error = -EFSCORRUPTED; goto label; }
+ if (XFS_IS_CORRUPT(mp, test)) { xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto label; }
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_ag.c | 4 +-
libxfs/xfs_alloc.c | 97 ++++++++++++++++++++++++++++++++++++++--------
libxfs/xfs_attr_remote.c | 8 +++-
libxfs/xfs_bmap.c | 94 ++++++++++++++++++++++++++++++++++++++++-----
libxfs/xfs_btree.c | 14 ++++++-
libxfs/xfs_ialloc.c | 52 ++++++++++++++++++++-----
libxfs/xfs_refcount.c | 37 +++++++++++++++++-
libxfs/xfs_rmap.c | 77 +++++++++++++++++++++++++++++++++++--
8 files changed, 339 insertions(+), 44 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index e001ac11c..b16f9c5c5 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -949,8 +949,10 @@ xfs_ag_shrink_space(
agf = agfbp->b_addr;
aglen = be32_to_cpu(agi->agi_length);
/* some extra paranoid checks before we shrink the ag */
- if (XFS_IS_CORRUPT(mp, agf->agf_length != agi->agi_length))
+ if (XFS_IS_CORRUPT(mp, agf->agf_length != agi->agi_length)) {
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF);
return -EFSCORRUPTED;
+ }
if (delta >= aglen)
return -EINVAL;
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index aa084120c..3d7686ead 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -495,14 +495,18 @@ xfs_alloc_fixup_trees(
if (XFS_IS_CORRUPT(mp,
i != 1 ||
nfbno1 != fbno ||
- nflen1 != flen))
+ nflen1 != flen)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
#endif
} else {
if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
}
/*
* Look up the record in the by-block tree if necessary.
@@ -514,14 +518,18 @@ xfs_alloc_fixup_trees(
if (XFS_IS_CORRUPT(mp,
i != 1 ||
nfbno1 != fbno ||
- nflen1 != flen))
+ nflen1 != flen)) {
+ xfs_btree_mark_sick(bno_cur);
return -EFSCORRUPTED;
+ }
#endif
} else {
if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
return -EFSCORRUPTED;
+ }
}
#ifdef DEBUG
@@ -534,8 +542,10 @@ xfs_alloc_fixup_trees(
if (XFS_IS_CORRUPT(mp,
bnoblock->bb_numrecs !=
- cntblock->bb_numrecs))
+ cntblock->bb_numrecs)) {
+ xfs_btree_mark_sick(bno_cur);
return -EFSCORRUPTED;
+ }
}
#endif
@@ -565,30 +575,40 @@ xfs_alloc_fixup_trees(
*/
if ((error = xfs_btree_delete(cnt_cur, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
/*
* Add new by-size btree entry(s).
*/
if (nfbno1 != NULLAGBLOCK) {
if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 0))
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
if ((error = xfs_btree_insert(cnt_cur, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
}
if (nfbno2 != NULLAGBLOCK) {
if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 0))
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
if ((error = xfs_btree_insert(cnt_cur, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
return -EFSCORRUPTED;
+ }
}
/*
* Fix up the by-block btree entry(s).
@@ -599,8 +619,10 @@ xfs_alloc_fixup_trees(
*/
if ((error = xfs_btree_delete(bno_cur, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
return -EFSCORRUPTED;
+ }
} else {
/*
* Update the by-block entry to start later|be shorter.
@@ -614,12 +636,16 @@ xfs_alloc_fixup_trees(
*/
if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 0))
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(bno_cur);
return -EFSCORRUPTED;
+ }
if ((error = xfs_btree_insert(bno_cur, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
return -EFSCORRUPTED;
+ }
}
return 0;
}
@@ -892,8 +918,10 @@ xfs_alloc_cur_check(
error = xfs_alloc_get_rec(cur, &bno, &len, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(args->mp, i != 1))
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
/*
* Check minlen and deactivate a cntbt cursor if out of acceptable size
@@ -1099,6 +1127,7 @@ xfs_alloc_ag_vextent_small(
if (error)
goto error;
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(ccur);
error = -EFSCORRUPTED;
goto error;
}
@@ -1133,6 +1162,7 @@ xfs_alloc_ag_vextent_small(
*fbnop = args->agbno = fbno;
*flenp = args->len = 1;
if (XFS_IS_CORRUPT(args->mp, fbno >= be32_to_cpu(agf->agf_length))) {
+ xfs_btree_mark_sick(ccur);
error = -EFSCORRUPTED;
goto error;
}
@@ -1219,6 +1249,7 @@ xfs_alloc_ag_vextent_exact(
if (error)
goto error0;
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1498,8 +1529,10 @@ xfs_alloc_ag_vextent_lastblock(
error = xfs_alloc_get_rec(acur->cnt, bno, len, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(args->mp, i != 1))
+ if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(acur->cnt);
return -EFSCORRUPTED;
+ }
if (*len >= args->minlen)
break;
error = xfs_btree_increment(acur->cnt, 0, &i);
@@ -1711,6 +1744,7 @@ xfs_alloc_ag_vextent_size(
if (error)
goto error0;
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1757,6 +1791,7 @@ xfs_alloc_ag_vextent_size(
rlen != 0 &&
(rlen > flen ||
rbno + rlen > fbno + flen))) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1779,6 +1814,7 @@ xfs_alloc_ag_vextent_size(
&i)))
goto error0;
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1791,6 +1827,7 @@ xfs_alloc_ag_vextent_size(
rlen != 0 &&
(rlen > flen ||
rbno + rlen > fbno + flen))) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1807,6 +1844,7 @@ xfs_alloc_ag_vextent_size(
&i)))
goto error0;
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1845,6 +1883,7 @@ xfs_alloc_ag_vextent_size(
rlen = args->len;
if (XFS_IS_CORRUPT(args->mp, rlen > flen)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1864,6 +1903,7 @@ xfs_alloc_ag_vextent_size(
if (XFS_IS_CORRUPT(args->mp,
args->agbno + args->len >
be32_to_cpu(agf->agf_length))) {
+ xfs_ag_mark_sick(args->pag, XFS_SICK_AG_BNOBT);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1939,6 +1979,7 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1954,6 +1995,7 @@ xfs_free_ag_extent(
* Very bad.
*/
if (XFS_IS_CORRUPT(mp, ltbno + ltlen > bno)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1972,6 +2014,7 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1987,6 +2030,7 @@ xfs_free_ag_extent(
* Very bad.
*/
if (XFS_IS_CORRUPT(mp, bno + len > gtbno)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2007,12 +2051,14 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
if ((error = xfs_btree_delete(cnt_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2022,12 +2068,14 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
if ((error = xfs_btree_delete(cnt_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2037,6 +2085,7 @@ xfs_free_ag_extent(
if ((error = xfs_btree_delete(bno_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2046,6 +2095,7 @@ xfs_free_ag_extent(
if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2065,6 +2115,7 @@ xfs_free_ag_extent(
i != 1 ||
xxbno != ltbno ||
xxlen != ltlen)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2089,12 +2140,14 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
if ((error = xfs_btree_delete(cnt_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2105,6 +2158,7 @@ xfs_free_ag_extent(
if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2124,12 +2178,14 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
if ((error = xfs_btree_delete(cnt_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2152,6 +2208,7 @@ xfs_free_ag_extent(
if ((error = xfs_btree_insert(bno_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bno_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2164,12 +2221,14 @@ xfs_free_ag_extent(
if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
if ((error = xfs_btree_insert(cnt_cur, &i)))
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cnt_cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -3899,17 +3958,23 @@ __xfs_free_extent(
return -EIO;
error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
- if (error)
+ if (error) {
+ if (xfs_metadata_is_sick(error))
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_BNOBT);
return error;
+ }
+
agf = agbp->b_addr;
if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_BNOBT);
error = -EFSCORRUPTED;
goto err_release;
}
/* validate the extent size is legal now we have the agf locked */
if (XFS_IS_CORRUPT(mp, agbno + len > be32_to_cpu(agf->agf_length))) {
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_BNOBT);
error = -EFSCORRUPTED;
goto err_release;
}
diff --git a/libxfs/xfs_attr_remote.c b/libxfs/xfs_attr_remote.c
index a400a22d3..855d090c9 100644
--- a/libxfs/xfs_attr_remote.c
+++ b/libxfs/xfs_attr_remote.c
@@ -552,8 +552,10 @@ xfs_attr_rmtval_stale(
xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
if (XFS_IS_CORRUPT(mp, map->br_startblock == DELAYSTARTBLOCK) ||
- XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK))
+ XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK)) {
+ xfs_bmap_mark_sick(ip, XFS_ATTR_FORK);
return -EFSCORRUPTED;
+ }
error = xfs_buf_incore(mp->m_ddev_targp,
XFS_FSB_TO_DADDR(mp, map->br_startblock),
@@ -663,8 +665,10 @@ xfs_attr_rmtval_invalidate(
blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK);
if (error)
return error;
- if (XFS_IS_CORRUPT(args->dp->i_mount, nmap != 1))
+ if (XFS_IS_CORRUPT(args->dp->i_mount, nmap != 1)) {
+ xfs_bmap_mark_sick(args->dp, XFS_ATTR_FORK);
return -EFSCORRUPTED;
+ }
error = xfs_attr_rmtval_stale(args->dp, &map, XBF_TRYLOCK);
if (error)
return error;
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index f15631818..7d7486ca6 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -380,6 +380,7 @@ xfs_bmap_check_leaf_extents(
pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
bno = be64_to_cpu(*pp);
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -561,8 +562,10 @@ xfs_bmap_btree_to_extents(
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
cbno = be64_to_cpu(*pp);
#ifdef DEBUG
- if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1)))
+ if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
#endif
error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
&xfs_bmbt_buf_ops);
@@ -879,6 +882,7 @@ xfs_bmap_add_attrfork_btree(
goto error0;
/* must be at least one entry */
if (XFS_IS_CORRUPT(mp, stat != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1205,6 +1209,7 @@ xfs_iread_extents(
goto out;
if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) {
+ xfs_bmap_mark_sick(ip, whichfork);
error = -EFSCORRUPTED;
goto out;
}
@@ -1395,8 +1400,10 @@ xfs_bmap_last_offset(
if (ifp->if_format == XFS_DINODE_FMT_LOCAL)
return 0;
- if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp)))
+ if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) {
+ xfs_bmap_mark_sick(ip, whichfork);
return -EFSCORRUPTED;
+ }
error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
if (error || is_empty)
@@ -1535,6 +1542,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1542,6 +1550,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1549,6 +1558,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1578,6 +1588,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1611,6 +1622,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1639,6 +1651,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1646,6 +1659,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1680,6 +1694,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1705,6 +1720,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1712,6 +1728,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1756,6 +1773,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1792,6 +1810,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1799,6 +1818,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1878,6 +1898,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1885,6 +1906,7 @@ xfs_bmap_add_extent_delay_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(bma->cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2081,30 +2103,35 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_delete(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_decrement(cur, 0, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_delete(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_decrement(cur, 0, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2133,18 +2160,21 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_delete(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_decrement(cur, 0, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2176,18 +2206,21 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_delete(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_decrement(cur, 0, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2214,6 +2247,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2247,6 +2281,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2284,6 +2319,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2294,6 +2330,7 @@ xfs_bmap_add_extent_unwritten_real(
if ((error = xfs_btree_insert(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2324,6 +2361,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2360,6 +2398,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2370,12 +2409,14 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if ((error = xfs_btree_insert(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2412,6 +2453,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2424,6 +2466,7 @@ xfs_bmap_add_extent_unwritten_real(
if ((error = xfs_btree_insert(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2436,6 +2479,7 @@ xfs_bmap_add_extent_unwritten_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2443,6 +2487,7 @@ xfs_bmap_add_extent_unwritten_real(
if ((error = xfs_btree_insert(cur, &i)))
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2728,6 +2773,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2735,6 +2781,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2742,6 +2789,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2771,6 +2819,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2801,6 +2850,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2827,6 +2877,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2834,6 +2885,7 @@ xfs_bmap_add_extent_hole_real(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -5103,8 +5155,10 @@ xfs_bmap_del_extent_real(
error = xfs_bmbt_lookup_eq(cur, &got, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
}
if (got.br_startoff == del->br_startoff)
@@ -5128,8 +5182,10 @@ xfs_bmap_del_extent_real(
}
if ((error = xfs_btree_delete(cur, &i)))
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
break;
case BMAP_LEFT_FILLING:
/*
@@ -5201,8 +5257,10 @@ xfs_bmap_del_extent_real(
error = xfs_bmbt_lookup_eq(cur, &got, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
/*
* Update the btree record back
* to the original value.
@@ -5218,8 +5276,10 @@ xfs_bmap_del_extent_real(
*logflagsp = 0;
return -ENOSPC;
}
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
} else
*logflagsp |= xfs_ilog_fext(whichfork);
@@ -5673,21 +5733,27 @@ xfs_bmse_merge(
error = xfs_bmbt_lookup_eq(cur, got, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
error = xfs_btree_delete(cur, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
/* lookup and update size of the previous extent */
error = xfs_bmbt_lookup_eq(cur, left, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
error = xfs_bmbt_update(cur, &new);
if (error)
@@ -5735,8 +5801,10 @@ xfs_bmap_shift_update_extent(
error = xfs_bmbt_lookup_eq(cur, &prev, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(mp, i != 1))
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
error = xfs_bmbt_update(cur, got);
if (error)
@@ -5797,6 +5865,7 @@ xfs_bmap_collapse_extents(
goto del_cursor;
}
if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
+ xfs_bmap_mark_sick(ip, whichfork);
error = -EFSCORRUPTED;
goto del_cursor;
}
@@ -5922,11 +5991,13 @@ xfs_bmap_insert_extents(
}
}
if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
+ xfs_bmap_mark_sick(ip, whichfork);
error = -EFSCORRUPTED;
goto del_cursor;
}
if (XFS_IS_CORRUPT(mp, stop_fsb > got.br_startoff)) {
+ xfs_bmap_mark_sick(ip, whichfork);
error = -EFSCORRUPTED;
goto del_cursor;
}
@@ -6026,6 +6097,7 @@ xfs_bmap_split_extent(
if (error)
goto del_cursor;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto del_cursor;
}
@@ -6053,6 +6125,7 @@ xfs_bmap_split_extent(
if (error)
goto del_cursor;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto del_cursor;
}
@@ -6060,6 +6133,7 @@ xfs_bmap_split_extent(
if (error)
goto del_cursor;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto del_cursor;
}
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 359d3f99e..b9af447ab 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -2023,8 +2023,10 @@ xfs_btree_lookup(
error = xfs_btree_increment(cur, 0, &i);
if (error)
goto error0;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
*stat = 1;
return 0;
}
@@ -2477,6 +2479,7 @@ xfs_btree_lshift(
goto error0;
i = xfs_btree_firstrec(tcur, level);
if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2647,6 +2650,7 @@ xfs_btree_rshift(
goto error0;
i = xfs_btree_lastrec(tcur, level);
if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -3535,6 +3539,7 @@ xfs_btree_insert(
}
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -3942,6 +3947,7 @@ xfs_btree_delrec(
*/
i = xfs_btree_lastrec(tcur, level);
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -3950,12 +3956,14 @@ xfs_btree_delrec(
if (error)
goto error0;
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
i = xfs_btree_lastrec(tcur, level);
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -4003,6 +4011,7 @@ xfs_btree_delrec(
if (!xfs_btree_ptr_is_null(cur, &lptr)) {
i = xfs_btree_firstrec(tcur, level);
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -4011,6 +4020,7 @@ xfs_btree_delrec(
if (error)
goto error0;
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -4028,6 +4038,7 @@ xfs_btree_delrec(
*/
i = xfs_btree_firstrec(tcur, level);
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -4037,6 +4048,7 @@ xfs_btree_delrec(
goto error0;
i = xfs_btree_firstrec(tcur, level);
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 63922f44f..21577a50f 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -568,6 +568,7 @@ xfs_inobt_insert_sprec(
if (error)
goto error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
@@ -584,10 +585,12 @@ xfs_inobt_insert_sprec(
if (error)
goto error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
@@ -597,6 +600,7 @@ xfs_inobt_insert_sprec(
* cannot merge, something is seriously wrong.
*/
if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
@@ -946,8 +950,10 @@ xfs_ialloc_next_rec(
error = xfs_inobt_get_rec(cur, rec, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
}
return 0;
@@ -971,8 +977,10 @@ xfs_ialloc_get_rec(
error = xfs_inobt_get_rec(cur, rec, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
}
return 0;
@@ -1050,6 +1058,7 @@ xfs_dialloc_ag_inobt(
if (error)
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1058,6 +1067,7 @@ xfs_dialloc_ag_inobt(
if (error)
goto error0;
if (XFS_IS_CORRUPT(mp, j != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1216,6 +1226,7 @@ xfs_dialloc_ag_inobt(
if (error)
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1225,6 +1236,7 @@ xfs_dialloc_ag_inobt(
if (error)
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1234,6 +1246,7 @@ xfs_dialloc_ag_inobt(
if (error)
goto error0;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1294,8 +1307,10 @@ xfs_dialloc_ag_finobt_near(
error = xfs_inobt_get_rec(lcur, rec, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(lcur);
return -EFSCORRUPTED;
+ }
/*
* See if we've landed in the parent inode record. The finobt
@@ -1319,12 +1334,14 @@ xfs_dialloc_ag_finobt_near(
if (error)
goto error_rcur;
if (XFS_IS_CORRUPT(lcur->bc_mp, j != 1)) {
+ xfs_btree_mark_sick(lcur);
error = -EFSCORRUPTED;
goto error_rcur;
}
}
if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1 && j != 1)) {
+ xfs_btree_mark_sick(lcur);
error = -EFSCORRUPTED;
goto error_rcur;
}
@@ -1380,8 +1397,10 @@ xfs_dialloc_ag_finobt_newino(
error = xfs_inobt_get_rec(cur, rec, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
return 0;
}
}
@@ -1392,14 +1411,18 @@ xfs_dialloc_ag_finobt_newino(
error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
error = xfs_inobt_get_rec(cur, rec, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
return 0;
}
@@ -1421,14 +1444,18 @@ xfs_dialloc_ag_update_inobt(
error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
error = xfs_inobt_get_rec(cur, &rec, &i);
if (error)
return error;
- if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
+ if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) %
XFS_INODES_PER_CHUNK) == 0);
@@ -1437,8 +1464,10 @@ xfs_dialloc_ag_update_inobt(
if (XFS_IS_CORRUPT(cur->bc_mp,
rec.ir_free != frec->ir_free ||
- rec.ir_freecount != frec->ir_freecount))
+ rec.ir_freecount != frec->ir_freecount)) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
return xfs_inobt_update(cur, &rec);
}
@@ -1955,6 +1984,7 @@ xfs_difree_inobt(
goto error0;
}
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -1965,6 +1995,7 @@ xfs_difree_inobt(
goto error0;
}
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error0;
}
@@ -2077,6 +2108,7 @@ xfs_difree_finobt(
* something is out of sync.
*/
if (XFS_IS_CORRUPT(mp, ibtrec->ir_freecount != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
@@ -2103,6 +2135,7 @@ xfs_difree_finobt(
if (error)
goto error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
@@ -2113,6 +2146,7 @@ xfs_difree_finobt(
if (XFS_IS_CORRUPT(mp,
rec.ir_free != ibtrec->ir_free ||
rec.ir_freecount != ibtrec->ir_freecount)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto error;
}
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index 00df1e64a..d0d0d8617 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -239,6 +239,7 @@ xfs_refcount_insert(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -269,12 +270,14 @@ xfs_refcount_delete(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
trace_xfs_refcount_delete(cur->bc_mp, cur->bc_ag.pag->pag_agno, &irec);
error = xfs_btree_delete(cur, i);
if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -399,6 +402,7 @@ xfs_refcount_split_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -426,6 +430,7 @@ xfs_refcount_split_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -471,6 +476,7 @@ xfs_refcount_merge_center_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -479,6 +485,7 @@ xfs_refcount_merge_center_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -488,6 +495,7 @@ xfs_refcount_merge_center_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -499,6 +507,7 @@ xfs_refcount_merge_center_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -543,6 +552,7 @@ xfs_refcount_merge_left_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -551,6 +561,7 @@ xfs_refcount_merge_left_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -562,6 +573,7 @@ xfs_refcount_merge_left_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -609,6 +621,7 @@ xfs_refcount_merge_right_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -617,6 +630,7 @@ xfs_refcount_merge_right_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -628,6 +642,7 @@ xfs_refcount_merge_right_extent(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -675,6 +690,7 @@ xfs_refcount_find_left_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -694,6 +710,7 @@ xfs_refcount_find_left_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -768,6 +785,7 @@ xfs_refcount_find_right_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -787,6 +805,7 @@ xfs_refcount_find_right_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1143,6 +1162,7 @@ xfs_refcount_adjust_extents(
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp,
found_tmp != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1181,6 +1201,7 @@ xfs_refcount_adjust_extents(
*/
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount == 0) ||
XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount > *aglen)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1204,6 +1225,7 @@ xfs_refcount_adjust_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1328,8 +1350,10 @@ xfs_refcount_continue_op(
struct xfs_perag *pag = cur->bc_ag.pag;
if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno,
- ri->ri_blockcount)))
+ ri->ri_blockcount))) {
+ xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
+ }
ri->ri_startblock = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
@@ -1536,6 +1560,7 @@ xfs_refcount_find_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1553,6 +1578,7 @@ xfs_refcount_find_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1586,6 +1612,7 @@ xfs_refcount_find_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1683,6 +1710,7 @@ xfs_refcount_adjust_cow_extents(
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec &&
ext.rc_domain != XFS_REFC_DOMAIN_COW)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1698,6 +1726,7 @@ xfs_refcount_adjust_cow_extents(
/* Adding a CoW reservation, there should be nothing here. */
if (XFS_IS_CORRUPT(cur->bc_mp,
agbno + aglen > ext.rc_startblock)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1715,6 +1744,7 @@ xfs_refcount_adjust_cow_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_tmp != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1722,14 +1752,17 @@ xfs_refcount_adjust_cow_extents(
case XFS_REFCOUNT_ADJUST_COW_FREE:
/* Removing a CoW reservation, there should be one extent. */
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_startblock != agbno)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount != aglen)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_refcount != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1741,6 +1774,7 @@ xfs_refcount_adjust_cow_extents(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1903,6 +1937,7 @@ xfs_refcount_recover_extent(
if (xfs_refcount_check_irec(cur->bc_ag.pag, &rr->rr_rrec) != NULL ||
XFS_IS_CORRUPT(cur->bc_mp,
rr->rr_rrec.rc_domain != XFS_REFC_DOMAIN_COW)) {
+ xfs_btree_mark_sick(cur);
kfree(rr);
return -EFSCORRUPTED;
}
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index 8fbc9583d..2d96cb60c 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -134,6 +134,7 @@ xfs_rmap_insert(
if (error)
goto done;
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) {
+ xfs_btree_mark_sick(rcur);
error = -EFSCORRUPTED;
goto done;
}
@@ -147,6 +148,7 @@ xfs_rmap_insert(
if (error)
goto done;
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(rcur);
error = -EFSCORRUPTED;
goto done;
}
@@ -176,6 +178,7 @@ xfs_rmap_delete(
if (error)
goto done;
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(rcur);
error = -EFSCORRUPTED;
goto done;
}
@@ -184,6 +187,7 @@ xfs_rmap_delete(
if (error)
goto done;
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
+ xfs_btree_mark_sick(rcur);
error = -EFSCORRUPTED;
goto done;
}
@@ -515,7 +519,7 @@ xfs_rmap_lookup_le_range(
*/
static int
xfs_rmap_free_check_owner(
- struct xfs_mount *mp,
+ struct xfs_btree_cur *cur,
uint64_t ltoff,
struct xfs_rmap_irec *rec,
xfs_filblks_t len,
@@ -523,6 +527,7 @@ xfs_rmap_free_check_owner(
uint64_t offset,
unsigned int flags)
{
+ struct xfs_mount *mp = cur->bc_mp;
int error = 0;
if (owner == XFS_RMAP_OWN_UNKNOWN)
@@ -532,12 +537,14 @@ xfs_rmap_free_check_owner(
if (XFS_IS_CORRUPT(mp,
(flags & XFS_RMAP_UNWRITTEN) !=
(rec->rm_flags & XFS_RMAP_UNWRITTEN))) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out;
}
/* Make sure the owner matches what we expect to find in the tree. */
if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out;
}
@@ -549,16 +556,19 @@ xfs_rmap_free_check_owner(
if (flags & XFS_RMAP_BMBT_BLOCK) {
if (XFS_IS_CORRUPT(mp,
!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out;
}
} else {
if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out;
}
if (XFS_IS_CORRUPT(mp,
offset + len > ltoff + rec->rm_blockcount)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out;
}
@@ -621,6 +631,7 @@ xfs_rmap_unmap(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -642,6 +653,7 @@ xfs_rmap_unmap(
if (XFS_IS_CORRUPT(mp,
bno <
ltrec.rm_startblock + ltrec.rm_blockcount)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -668,6 +680,7 @@ xfs_rmap_unmap(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -680,12 +693,13 @@ xfs_rmap_unmap(
ltrec.rm_startblock > bno ||
ltrec.rm_startblock + ltrec.rm_blockcount <
bno + len)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
/* Check owner information. */
- error = xfs_rmap_free_check_owner(mp, ltoff, <rec, len, owner,
+ error = xfs_rmap_free_check_owner(cur, ltoff, <rec, len, owner,
offset, flags);
if (error)
goto out_error;
@@ -700,6 +714,7 @@ xfs_rmap_unmap(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -903,6 +918,7 @@ xfs_rmap_map(
if (XFS_IS_CORRUPT(mp,
have_lt != 0 &&
ltrec.rm_startblock + ltrec.rm_blockcount > bno)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -920,10 +936,12 @@ xfs_rmap_map(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -977,6 +995,7 @@ xfs_rmap_map(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1024,6 +1043,7 @@ xfs_rmap_map(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -1119,6 +1139,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1156,12 +1177,14 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if (XFS_IS_CORRUPT(mp,
LEFT.rm_startblock + LEFT.rm_blockcount >
bno)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1184,6 +1207,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1196,10 +1220,12 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1230,6 +1256,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1249,6 +1276,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1260,6 +1288,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1267,6 +1296,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1278,6 +1308,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1285,6 +1316,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1308,6 +1340,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1315,6 +1348,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1334,6 +1368,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1345,6 +1380,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1352,6 +1388,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1422,6 +1459,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1464,6 +1502,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1479,6 +1518,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1512,6 +1552,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1525,6 +1566,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 0)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1537,6 +1579,7 @@ xfs_rmap_convert(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1609,6 +1652,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1637,6 +1681,7 @@ xfs_rmap_convert_shared(
if (XFS_IS_CORRUPT(mp,
LEFT.rm_startblock + LEFT.rm_blockcount >
bno)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1655,10 +1700,12 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1709,6 +1756,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1735,6 +1783,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1761,6 +1810,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1784,6 +1834,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1819,6 +1870,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1864,6 +1916,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1899,6 +1952,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -1937,6 +1991,7 @@ xfs_rmap_convert_shared(
if (error)
goto done;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto done;
}
@@ -2026,6 +2081,7 @@ xfs_rmap_unmap_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2036,12 +2092,14 @@ xfs_rmap_unmap_shared(
ltrec.rm_startblock > bno ||
ltrec.rm_startblock + ltrec.rm_blockcount <
bno + len)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
/* Make sure the owner matches what we expect to find in the tree. */
if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2050,16 +2108,19 @@ xfs_rmap_unmap_shared(
if (XFS_IS_CORRUPT(mp,
(flags & XFS_RMAP_UNWRITTEN) !=
(ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
/* Check the offset. */
if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2116,6 +2177,7 @@ xfs_rmap_unmap_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2145,6 +2207,7 @@ xfs_rmap_unmap_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2224,6 +2287,7 @@ xfs_rmap_map_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2276,6 +2340,7 @@ xfs_rmap_map_shared(
if (error)
goto out_error;
if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
goto out_error;
}
@@ -2479,10 +2544,14 @@ xfs_rmap_finish_one(
* allocate blocks.
*/
error = xfs_free_extent_fix_freelist(tp, ri->ri_pag, &agbp);
- if (error)
+ if (error) {
+ xfs_ag_mark_sick(ri->ri_pag, XFS_SICK_AG_AGFL);
return error;
- if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
+ }
+ if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
+ xfs_ag_mark_sick(ri->ri_pag, XFS_SICK_AG_AGFL);
return -EFSCORRUPTED;
+ }
rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, ri->ri_pag);
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 025/111] xfs: add secondary and indirect classes to the health tracking system
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (23 preceding siblings ...)
2024-05-22 2:55 ` [PATCH 024/111] xfs: report XFS_IS_CORRUPT " Darrick J. Wong
@ 2024-05-22 2:55 ` Darrick J. Wong
2024-05-22 2:55 ` [PATCH 026/111] xfs: remember sick inodes that get inactivated Darrick J. Wong
` (86 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:55 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 4e587917ee1cc28ac3a04cd55937419b9e65d81d
Establish two more classes of health tracking bits:
* Indirect problems, which suggest problems in other health domains
that we weren't able to preserve.
* Secondary problems, which track state that's related to primary
evidence of health problems; and
The first class we'll use in an upcoming patch to record in the AG
health status the fact that we ran out of memory and had to inactivate
an inode with defective metadata. The second class we use to indicate
that repair knows that an inode is bad and we need to fix it later.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_health.h | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index ff98c0321..032d45fcb 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -31,6 +31,19 @@
* - !checked && sick => errors have been observed during normal operation,
* but the metadata has not been checked thoroughly
* - !checked && !sick => has not been examined since mount
+ *
+ * Evidence of health problems can be sorted into three basic categories:
+ *
+ * a) Primary evidence, which signals that something is defective within the
+ * general grouping of metadata.
+ *
+ * b) Secondary evidence, which are side effects of primary problem but are
+ * not themselves problems. These can be forgotten when the primary
+ * health problems are addressed.
+ *
+ * c) Indirect evidence, which points to something being wrong in another
+ * group, but we had to release resources and this is all that's left of
+ * that state.
*/
struct xfs_mount;
@@ -115,6 +128,36 @@ struct xfs_da_args;
XFS_SICK_INO_DIR_ZAPPED | \
XFS_SICK_INO_SYMLINK_ZAPPED)
+/* Secondary state related to (but not primary evidence of) health problems. */
+#define XFS_SICK_FS_SECONDARY (0)
+#define XFS_SICK_RT_SECONDARY (0)
+#define XFS_SICK_AG_SECONDARY (0)
+#define XFS_SICK_INO_SECONDARY (0)
+
+/* Evidence of health problems elsewhere. */
+#define XFS_SICK_FS_INDIRECT (0)
+#define XFS_SICK_RT_INDIRECT (0)
+#define XFS_SICK_AG_INDIRECT (0)
+#define XFS_SICK_INO_INDIRECT (0)
+
+/* All health masks. */
+#define XFS_SICK_FS_ALL (XFS_SICK_FS_PRIMARY | \
+ XFS_SICK_FS_SECONDARY | \
+ XFS_SICK_FS_INDIRECT)
+
+#define XFS_SICK_RT_ALL (XFS_SICK_RT_PRIMARY | \
+ XFS_SICK_RT_SECONDARY | \
+ XFS_SICK_RT_INDIRECT)
+
+#define XFS_SICK_AG_ALL (XFS_SICK_AG_PRIMARY | \
+ XFS_SICK_AG_SECONDARY | \
+ XFS_SICK_AG_INDIRECT)
+
+#define XFS_SICK_INO_ALL (XFS_SICK_INO_PRIMARY | \
+ XFS_SICK_INO_SECONDARY | \
+ XFS_SICK_INO_INDIRECT | \
+ XFS_SICK_INO_ZAPPED)
+
/*
* These functions must be provided by the xfs implementation. Function
* behavior with respect to the first argument should be as follows:
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 026/111] xfs: remember sick inodes that get inactivated
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (24 preceding siblings ...)
2024-05-22 2:55 ` [PATCH 025/111] xfs: add secondary and indirect classes to the health tracking system Darrick J. Wong
@ 2024-05-22 2:55 ` Darrick J. Wong
2024-05-22 2:55 ` [PATCH 027/111] xfs: update health status if we get a clean bill of health Darrick J. Wong
` (85 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:55 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 0e24ec3c56fbc797b34fc94073320c336336b4f9
If an unhealthy inode gets inactivated, remember this fact in the
per-fs health summary.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_fs.h | 1 +
libxfs/xfs_health.h | 8 ++++++--
libxfs/xfs_inode_buf.c | 2 +-
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 515cd27d3..b5c8da7e6 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -294,6 +294,7 @@ struct xfs_ag_geometry {
#define XFS_AG_GEOM_SICK_FINOBT (1 << 7) /* free inode index */
#define XFS_AG_GEOM_SICK_RMAPBT (1 << 8) /* reverse mappings */
#define XFS_AG_GEOM_SICK_REFCNTBT (1 << 9) /* reference counts */
+#define XFS_AG_GEOM_SICK_INODES (1 << 10) /* bad inodes were seen */
/*
* Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index 032d45fcb..3c64b5f9b 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -76,6 +76,7 @@ struct xfs_da_args;
#define XFS_SICK_AG_FINOBT (1 << 7) /* free inode index */
#define XFS_SICK_AG_RMAPBT (1 << 8) /* reverse mappings */
#define XFS_SICK_AG_REFCNTBT (1 << 9) /* reference counts */
+#define XFS_SICK_AG_INODES (1 << 10) /* inactivated bad inodes */
/* Observable health issues for inode metadata. */
#define XFS_SICK_INO_CORE (1 << 0) /* inode core */
@@ -92,6 +93,9 @@ struct xfs_da_args;
#define XFS_SICK_INO_DIR_ZAPPED (1 << 10) /* directory erased */
#define XFS_SICK_INO_SYMLINK_ZAPPED (1 << 11) /* symlink erased */
+/* Don't propagate sick status to ag health summary during inactivation */
+#define XFS_SICK_INO_FORGET (1 << 12)
+
/* Primary evidence of health problems in a given group. */
#define XFS_SICK_FS_PRIMARY (XFS_SICK_FS_COUNTERS | \
XFS_SICK_FS_UQUOTA | \
@@ -132,12 +136,12 @@ struct xfs_da_args;
#define XFS_SICK_FS_SECONDARY (0)
#define XFS_SICK_RT_SECONDARY (0)
#define XFS_SICK_AG_SECONDARY (0)
-#define XFS_SICK_INO_SECONDARY (0)
+#define XFS_SICK_INO_SECONDARY (XFS_SICK_INO_FORGET)
/* Evidence of health problems elsewhere. */
#define XFS_SICK_FS_INDIRECT (0)
#define XFS_SICK_RT_INDIRECT (0)
-#define XFS_SICK_AG_INDIRECT (0)
+#define XFS_SICK_AG_INDIRECT (XFS_SICK_AG_INODES)
#define XFS_SICK_INO_INDIRECT (0)
/* All health masks. */
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 83d936981..82cf64db9 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -136,7 +136,7 @@ xfs_imap_to_bp(
imap->im_len, XBF_UNMAPPED, bpp, &xfs_inode_buf_ops);
if (xfs_metadata_is_sick(error))
xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, imap->im_blkno),
- XFS_SICK_AG_INOBT);
+ XFS_SICK_AG_INODES);
return error;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 027/111] xfs: update health status if we get a clean bill of health
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (25 preceding siblings ...)
2024-05-22 2:55 ` [PATCH 026/111] xfs: remember sick inodes that get inactivated Darrick J. Wong
@ 2024-05-22 2:55 ` Darrick J. Wong
2024-05-22 2:56 ` [PATCH 028/111] xfs: consolidate btree block freeing tracepoints Darrick J. Wong
` (84 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:55 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: a1f3e0cca41036c3c66abb6a2ed8fedc214e9a4c
If scrub finds that everything is ok with the filesystem, we need a way
to tell the health tracking that it can let go of indirect health flags,
since indirect flags only mean that at some point in the past we lost
some context.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_fs.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index b5c8da7e6..ca1b17d01 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -714,9 +714,10 @@ struct xfs_scrub_metadata {
#define XFS_SCRUB_TYPE_FSCOUNTERS 24 /* fs summary counters */
#define XFS_SCRUB_TYPE_QUOTACHECK 25 /* quota counters */
#define XFS_SCRUB_TYPE_NLINKS 26 /* inode link counts */
+#define XFS_SCRUB_TYPE_HEALTHY 27 /* everything checked out ok */
/* Number of scrub subcommands. */
-#define XFS_SCRUB_TYPE_NR 27
+#define XFS_SCRUB_TYPE_NR 28
/* i: Repair this metadata. */
#define XFS_SCRUB_IFLAG_REPAIR (1u << 0)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 028/111] xfs: consolidate btree block freeing tracepoints
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (26 preceding siblings ...)
2024-05-22 2:55 ` [PATCH 027/111] xfs: update health status if we get a clean bill of health Darrick J. Wong
@ 2024-05-22 2:56 ` Darrick J. Wong
2024-05-22 2:56 ` [PATCH 029/111] xfs: consolidate btree block allocation tracepoints Darrick J. Wong
` (83 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:56 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 78067b92b9096a70ca731a6cde1c286582ff03d7
Don't waste memory on extra per-btree block freeing tracepoints when we
can do it from the generic btree code.
With this patch applied, two tracepoints are collapsed into one
tracepoint, with the following effects on objdump -hx xfs.ko output:
Before:
10 __tracepoints_ptrs 00000b3c 0000000000000000 0000000000000000 00140eb0 2**2
14 __tracepoints_strings 00005453 0000000000000000 0000000000000000 00168540 2**5
29 __tracepoints 00010d90 0000000000000000 0000000000000000 0023f5e0 2**5
After:
10 __tracepoints_ptrs 00000b38 0000000000000000 0000000000000000 001412f0 2**2
14 __tracepoints_strings 00005433 0000000000000000 0000000000000000 001689a0 2**5
29 __tracepoints 00010d30 0000000000000000 0000000000000000 0023fe00 2**5
Column 3 is the section size in bytes; removing these two tracepoints
reduces the size of the ELF segments by 132 bytes.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/xfs_trace.h | 3 +--
libxfs/xfs_btree.c | 2 ++
libxfs/xfs_refcount_btree.c | 2 --
libxfs/xfs_rmap_btree.c | 2 --
4 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index f172b61d6..98819653b 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -68,6 +68,7 @@
#define trace_xfs_btree_commit_ifakeroot(a) ((void) 0)
#define trace_xfs_btree_bload_level_geometry(a,b,c,d,e,f,g) ((void) 0)
#define trace_xfs_btree_bload_block(a,b,c,d,e,f) ((void) 0)
+#define trace_xfs_btree_free_block(...) ((void) 0)
#define trace_xfs_free_extent(a,b,c,d,e,f,g) ((void) 0)
#define trace_xfs_agf(a,b,c,d) ((void) 0)
@@ -256,7 +257,6 @@
#define trace_xfs_rmap_find_left_neighbor_result(...) ((void) 0)
#define trace_xfs_rmap_lookup_le_range_result(...) ((void) 0)
-#define trace_xfs_rmapbt_free_block(...) ((void) 0)
#define trace_xfs_rmapbt_alloc_block(...) ((void) 0)
#define trace_xfs_ag_resv_critical(...) ((void) 0)
@@ -276,7 +276,6 @@
#define trace_xfs_refcount_insert_error(...) ((void) 0)
#define trace_xfs_refcount_delete(...) ((void) 0)
#define trace_xfs_refcount_delete_error(...) ((void) 0)
-#define trace_xfs_refcountbt_free_block(...) ((void) 0)
#define trace_xfs_refcountbt_alloc_block(...) ((void) 0)
#define trace_xfs_refcount_rec_order_error(...) ((void) 0)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index b9af447ab..fb36a3b69 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -411,6 +411,8 @@ xfs_btree_free_block(
{
int error;
+ trace_xfs_btree_free_block(cur, bp);
+
error = cur->bc_ops->free_block(cur, bp);
if (!error) {
xfs_trans_binval(cur->bc_tp, bp);
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index ac1c3ab86..67551df02 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -106,8 +106,6 @@ xfs_refcountbt_free_block(
struct xfs_agf *agf = agbp->b_addr;
xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
- trace_xfs_refcountbt_free_block(cur->bc_mp, cur->bc_ag.pag->pag_agno,
- XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1);
be32_add_cpu(&agf->agf_refcount_blocks, -1);
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index d6e2fc0a3..7966a3e6a 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -123,8 +123,6 @@ xfs_rmapbt_free_block(
int error;
bno = xfs_daddr_to_agbno(cur->bc_mp, xfs_buf_daddr(bp));
- trace_xfs_rmapbt_free_block(cur->bc_mp, pag->pag_agno,
- bno, 1);
be32_add_cpu(&agf->agf_rmap_blocks, -1);
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS);
error = xfs_alloc_put_freelist(pag, cur->bc_tp, agbp, NULL, bno, 1);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 029/111] xfs: consolidate btree block allocation tracepoints
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (27 preceding siblings ...)
2024-05-22 2:56 ` [PATCH 028/111] xfs: consolidate btree block freeing tracepoints Darrick J. Wong
@ 2024-05-22 2:56 ` Darrick J. Wong
2024-05-22 2:56 ` [PATCH 030/111] xfs: set the btree cursor bc_ops in xfs_btree_alloc_cursor Darrick J. Wong
` (82 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:56 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 2ed0b2c7f33159825af1a1a83face66edb52348a
Don't waste tracepoint segment memory on per-btree block allocation
tracepoints when we can do it from the generic btree code.
With this patch applied, two tracepoints are collapsed into one
tracepoint, with the following effects on objdump -hx xfs.ko output:
Before:
10 __tracepoints_ptrs 00000b38 0000000000000000 0000000000000000 001412f0 2**2
14 __tracepoints_strings 00005433 0000000000000000 0000000000000000 001689a0 2**5
29 __tracepoints 00010d30 0000000000000000 0000000000000000 0023fe00 2**5
After:
10 __tracepoints_ptrs 00000b34 0000000000000000 0000000000000000 001417b0 2**2
14 __tracepoints_strings 00005413 0000000000000000 0000000000000000 00168e80 2**5
29 __tracepoints 00010cd0 0000000000000000 0000000000000000 00240760 2**5
Column 3 is the section size in bytes; removing these two tracepoints
reduces the size of the ELF segments by 132 bytes.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/xfs_trace.h | 4 +---
libxfs/xfs_btree.c | 20 +++++++++++++++++---
libxfs/xfs_refcount_btree.c | 2 --
libxfs/xfs_rmap_btree.c | 2 --
4 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index 98819653b..e7cbd0d9d 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -69,6 +69,7 @@
#define trace_xfs_btree_bload_level_geometry(a,b,c,d,e,f,g) ((void) 0)
#define trace_xfs_btree_bload_block(a,b,c,d,e,f) ((void) 0)
#define trace_xfs_btree_free_block(...) ((void) 0)
+#define trace_xfs_btree_alloc_block(...) ((void) 0)
#define trace_xfs_free_extent(a,b,c,d,e,f,g) ((void) 0)
#define trace_xfs_agf(a,b,c,d) ((void) 0)
@@ -257,8 +258,6 @@
#define trace_xfs_rmap_find_left_neighbor_result(...) ((void) 0)
#define trace_xfs_rmap_lookup_le_range_result(...) ((void) 0)
-#define trace_xfs_rmapbt_alloc_block(...) ((void) 0)
-
#define trace_xfs_ag_resv_critical(...) ((void) 0)
#define trace_xfs_ag_resv_needed(...) ((void) 0)
#define trace_xfs_ag_resv_free(...) ((void) 0)
@@ -276,7 +275,6 @@
#define trace_xfs_refcount_insert_error(...) ((void) 0)
#define trace_xfs_refcount_delete(...) ((void) 0)
#define trace_xfs_refcount_delete_error(...) ((void) 0)
-#define trace_xfs_refcountbt_alloc_block(...) ((void) 0)
#define trace_xfs_refcount_rec_order_error(...) ((void) 0)
#define trace_xfs_refcount_lookup(...) ((void) 0)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index fb36a3b69..3a2b627fd 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -2690,6 +2690,20 @@ xfs_btree_rshift(
return error;
}
+static inline int
+xfs_btree_alloc_block(
+ struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *hint_block,
+ union xfs_btree_ptr *new_block,
+ int *stat)
+{
+ int error;
+
+ error = cur->bc_ops->alloc_block(cur, hint_block, new_block, stat);
+ trace_xfs_btree_alloc_block(cur, new_block, *stat, error);
+ return error;
+}
+
/*
* Split cur/level block in half.
* Return new block number and the key to its first
@@ -2733,7 +2747,7 @@ __xfs_btree_split(
xfs_btree_buf_to_ptr(cur, lbp, &lptr);
/* Allocate the new block. If we can't do it, we're toast. Give up. */
- error = cur->bc_ops->alloc_block(cur, &lptr, &rptr, stat);
+ error = xfs_btree_alloc_block(cur, &lptr, &rptr, stat);
if (error)
goto error0;
if (*stat == 0)
@@ -3013,7 +3027,7 @@ xfs_btree_new_iroot(
pp = xfs_btree_ptr_addr(cur, 1, block);
/* Allocate the new block. If we can't do it, we're toast. Give up. */
- error = cur->bc_ops->alloc_block(cur, pp, &nptr, stat);
+ error = xfs_btree_alloc_block(cur, pp, &nptr, stat);
if (error)
goto error0;
if (*stat == 0)
@@ -3113,7 +3127,7 @@ xfs_btree_new_root(
cur->bc_ops->init_ptr_from_cur(cur, &rptr);
/* Allocate the new block. If we can't do it, we're toast. Give up. */
- error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, stat);
+ error = xfs_btree_alloc_block(cur, &rptr, &lptr, stat);
if (error)
goto error0;
if (*stat == 0)
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 67551df02..9a3c2270c 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -76,8 +76,6 @@ xfs_refcountbt_alloc_block(
xfs_refc_block(args.mp)));
if (error)
goto out_error;
- trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno,
- args.agbno, 1);
if (args.fsbno == NULLFSBLOCK) {
*stat = 0;
return 0;
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 7966a3e6a..e894a22e0 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -92,8 +92,6 @@ xfs_rmapbt_alloc_block(
&bno, 1);
if (error)
return error;
-
- trace_xfs_rmapbt_alloc_block(cur->bc_mp, pag->pag_agno, bno, 1);
if (bno == NULLAGBLOCK) {
*stat = 0;
return 0;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 030/111] xfs: set the btree cursor bc_ops in xfs_btree_alloc_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (28 preceding siblings ...)
2024-05-22 2:56 ` [PATCH 029/111] xfs: consolidate btree block allocation tracepoints Darrick J. Wong
@ 2024-05-22 2:56 ` Darrick J. Wong
2024-05-22 2:56 ` [PATCH 031/111] xfs: drop XFS_BTREE_CRC_BLOCKS Darrick J. Wong
` (81 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:56 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 056d22c87132cf4968f5e702116439bea9795930
This is a precursor to putting more static data in the btree ops structure.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_alloc_btree.c | 11 +++++------
libxfs/xfs_bmap_btree.c | 3 +--
libxfs/xfs_btree.h | 2 ++
libxfs/xfs_ialloc_btree.c | 10 ++++++----
libxfs/xfs_refcount_btree.c | 4 ++--
libxfs/xfs_rmap_btree.c | 3 +--
6 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index a472ec6d2..16f683e1d 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -510,18 +510,17 @@ xfs_allocbt_init_common(
ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, mp->m_alloc_maxlevels,
- xfs_allocbt_cur_cache);
- cur->bc_ag.abt.active = false;
-
if (btnum == XFS_BTNUM_CNT) {
- cur->bc_ops = &xfs_cntbt_ops;
+ cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_cntbt_ops,
+ mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
} else {
- cur->bc_ops = &xfs_bnobt_ops;
+ cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_bnobt_ops,
+ mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
}
+ cur->bc_ag.abt.active = false;
cur->bc_ag.pag = xfs_perag_hold(pag);
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 887ba56f3..751ae73c5 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -548,11 +548,10 @@ xfs_bmbt_init_common(
ASSERT(whichfork != XFS_COW_FORK);
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP,
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP, &xfs_bmbt_ops,
mp->m_bm_maxlevels[whichfork], xfs_bmbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
- cur->bc_ops = &xfs_bmbt_ops;
cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
if (xfs_has_crc(mp))
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 75a0e2c8e..c053fb934 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -720,6 +720,7 @@ xfs_btree_alloc_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
xfs_btnum_t btnum,
+ const struct xfs_btree_ops *ops,
uint8_t maxlevels,
struct kmem_cache *cache)
{
@@ -728,6 +729,7 @@ xfs_btree_alloc_cursor(
/* BMBT allocations can come through from non-transactional context. */
cur = kmem_cache_zalloc(cache,
GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
+ cur->bc_ops = ops;
cur->bc_tp = tp;
cur->bc_mp = mp;
cur->bc_btnum = btnum;
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 593cb1fcc..5ea08cca2 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -453,14 +453,16 @@ xfs_inobt_init_common(
struct xfs_mount *mp = pag->pag_mount;
struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, btnum,
- M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
if (btnum == XFS_BTNUM_INO) {
+ cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_inobt_ops,
+ M_IGEO(mp)->inobt_maxlevels,
+ xfs_inobt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2);
- cur->bc_ops = &xfs_inobt_ops;
} else {
+ cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_finobt_ops,
+ M_IGEO(mp)->inobt_maxlevels,
+ xfs_inobt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
- cur->bc_ops = &xfs_finobt_ops;
}
if (xfs_has_crc(mp))
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 9a3c2270c..561b732b4 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -352,7 +352,8 @@ xfs_refcountbt_init_common(
ASSERT(pag->pag_agno < mp->m_sb.sb_agcount);
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC,
- mp->m_refc_maxlevels, xfs_refcountbt_cur_cache);
+ &xfs_refcountbt_ops, mp->m_refc_maxlevels,
+ xfs_refcountbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
@@ -360,7 +361,6 @@ xfs_refcountbt_init_common(
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.refc.nr_ops = 0;
cur->bc_ag.refc.shape_changes = 0;
- cur->bc_ops = &xfs_refcountbt_ops;
return cur;
}
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index e894a22e0..362312729 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -501,11 +501,10 @@ xfs_rmapbt_init_common(
struct xfs_btree_cur *cur;
/* Overlapping btree; 2 keys per pointer. */
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP,
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
- cur->bc_ops = &xfs_rmapbt_ops;
cur->bc_ag.pag = xfs_perag_hold(pag);
return cur;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 031/111] xfs: drop XFS_BTREE_CRC_BLOCKS
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (29 preceding siblings ...)
2024-05-22 2:56 ` [PATCH 030/111] xfs: set the btree cursor bc_ops in xfs_btree_alloc_cursor Darrick J. Wong
@ 2024-05-22 2:56 ` Darrick J. Wong
2024-05-22 2:57 ` [PATCH 032/111] xfs: encode the btree geometry flags in the btree ops structure Darrick J. Wong
` (80 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:56 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: f9e325bf61d1fb3ef5f705268a22de95809db9fa
All existing btree types set XFS_BTREE_CRC_BLOCKS when running against a
V5 filesystem. All currently proposed btree types are V5 only and use
the richer XFS_BTREE_CRC_BLOCKS format. Therefore, we can drop this
flag and change the conditional to xfs_has_crc.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_alloc_btree.c | 3 ---
libxfs/xfs_bmap_btree.c | 2 --
libxfs/xfs_btree.c | 8 ++++----
libxfs/xfs_btree.h | 1 -
libxfs/xfs_ialloc_btree.c | 3 ---
libxfs/xfs_refcount_btree.c | 2 --
libxfs/xfs_rmap_btree.c | 2 +-
7 files changed, 5 insertions(+), 16 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 16f683e1d..626d8e4b8 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -524,9 +524,6 @@ xfs_allocbt_init_common(
cur->bc_ag.pag = xfs_perag_hold(pag);
- if (xfs_has_crc(mp))
- cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
-
return cur;
}
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 751ae73c5..8ffef40ba 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -553,8 +553,6 @@ xfs_bmbt_init_common(
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
- if (xfs_has_crc(mp))
- cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
cur->bc_ino.ip = ip;
cur->bc_ino.allocated = 0;
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 3a2b627fd..38d82c03a 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -595,11 +595,11 @@ xfs_btree_dup_cursor(
static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
{
if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
- if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS)
+ if (xfs_has_crc(cur->bc_mp))
return XFS_BTREE_LBLOCK_CRC_LEN;
return XFS_BTREE_LBLOCK_LEN;
}
- if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS)
+ if (xfs_has_crc(cur->bc_mp))
return XFS_BTREE_SBLOCK_CRC_LEN;
return XFS_BTREE_SBLOCK_LEN;
}
@@ -1573,7 +1573,7 @@ xfs_btree_log_block(
if (bp) {
int nbits;
- if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
+ if (xfs_has_crc(cur->bc_mp)) {
/*
* We don't log the CRC when updating a btree
* block but instead recreate it during log
@@ -3045,7 +3045,7 @@ xfs_btree_new_iroot(
* In that case have to also ensure the blkno remains correct
*/
memcpy(cblock, block, xfs_btree_block_len(cur));
- if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
+ if (xfs_has_crc(cur->bc_mp)) {
__be64 bno = cpu_to_be64(xfs_buf_daddr(cbp));
if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
cblock->bb_u.l.bb_blkno = bno;
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index c053fb934..36fd07b32 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -308,7 +308,6 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
#define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */
#define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */
#define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */
-#define XFS_BTREE_CRC_BLOCKS (1<<3) /* uses extended btree blocks */
#define XFS_BTREE_OVERLAPPING (1<<4) /* overlapping intervals */
/*
* The root of this btree is a fakeroot structure so that we can stage a btree
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 5ea08cca2..dea661afc 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -465,9 +465,6 @@ xfs_inobt_init_common(
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
}
- if (xfs_has_crc(mp))
- cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
-
cur->bc_ag.pag = xfs_perag_hold(pag);
return cur;
}
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 561b732b4..1ecd670a9 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -356,8 +356,6 @@ xfs_refcountbt_init_common(
xfs_refcountbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
- cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
-
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.refc.nr_ops = 0;
cur->bc_ag.refc.shape_changes = 0;
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 362312729..da6bfb901 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -503,7 +503,7 @@ xfs_rmapbt_init_common(
/* Overlapping btree; 2 keys per pointer. */
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
- cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING;
+ cur->bc_flags = XFS_BTREE_OVERLAPPING;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
cur->bc_ag.pag = xfs_perag_hold(pag);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 032/111] xfs: encode the btree geometry flags in the btree ops structure
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (30 preceding siblings ...)
2024-05-22 2:56 ` [PATCH 031/111] xfs: drop XFS_BTREE_CRC_BLOCKS Darrick J. Wong
@ 2024-05-22 2:57 ` Darrick J. Wong
2024-05-22 2:57 ` [PATCH 033/111] xfs: remove bc_ino.flags Darrick J. Wong
` (79 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:57 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: fd9c7f7722d815527269b80d9990aecffa06957c
Certain btree flags never change for the life of a btree cursor because
they describe the geometry of the btree itself. Encode these in the
btree ops structure and reduce the amount of code required in each btree
type's init_cursor functions. This also frees up most of the bits in
bc_flags.
A previous version of this patch also converted the open-coded flags
logic to helpers. This was removed due to the pending refactoring (that
follows this patch) to eliminate most of the state flags.
Conversion script:
sed \
-e 's/XFS_BTREE_LONG_PTRS/XFS_BTGEO_LONG_PTRS/g' \
-e 's/XFS_BTREE_ROOT_IN_INODE/XFS_BTGEO_ROOT_IN_INODE/g' \
-e 's/XFS_BTREE_LASTREC_UPDATE/XFS_BTGEO_LASTREC_UPDATE/g' \
-e 's/XFS_BTREE_OVERLAPPING/XFS_BTGEO_OVERLAPPING/g' \
-e 's/cur->bc_flags & XFS_BTGEO_/cur->bc_ops->geom_flags \& XFS_BTGEO_/g' \
-i $(git ls-files fs/xfs/*.[ch] fs/xfs/libxfs/*.[ch] fs/xfs/scrub/*.[ch])
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_alloc_btree.c | 4 +-
libxfs/xfs_bmap.c | 4 +-
libxfs/xfs_bmap_btree.c | 6 +-
libxfs/xfs_btree.c | 110 ++++++++++++++++++++++----------------------
libxfs/xfs_btree.h | 23 ++++++---
libxfs/xfs_btree_staging.c | 14 +++---
libxfs/xfs_btree_staging.h | 2 -
libxfs/xfs_rmap_btree.c | 3 +
repair/bulkload.c | 2 -
9 files changed, 87 insertions(+), 81 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 626d8e4b8..d3ecd513d 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -476,6 +476,8 @@ static const struct xfs_btree_ops xfs_bnobt_ops = {
};
static const struct xfs_btree_ops xfs_cntbt_ops = {
+ .geom_flags = XFS_BTGEO_LASTREC_UPDATE,
+
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
@@ -514,7 +516,6 @@ xfs_allocbt_init_common(
cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_cntbt_ops,
mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
- cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
} else {
cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_bnobt_ops,
mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
@@ -589,7 +590,6 @@ xfs_allocbt_commit_staged_btree(
if (cur->bc_btnum == XFS_BTNUM_BNO) {
xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_bnobt_ops);
} else {
- cur->bc_flags |= XFS_BTREE_LASTREC_UPDATE;
xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_cntbt_ops);
}
}
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 7d7486ca6..72d35f664 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -640,7 +640,7 @@ xfs_bmap_extents_to_btree(
block = ifp->if_broot;
xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
XFS_BTNUM_BMAP, 1, 1, ip->i_ino,
- XFS_BTREE_LONG_PTRS);
+ XFS_BTGEO_LONG_PTRS);
/*
* Need a cursor. Can't allocate until bb_level is filled in.
*/
@@ -687,7 +687,7 @@ xfs_bmap_extents_to_btree(
ablock = XFS_BUF_TO_BLOCK(abp);
xfs_btree_init_block_int(mp, ablock, xfs_buf_daddr(abp),
XFS_BTNUM_BMAP, 0, 0, ip->i_ino,
- XFS_BTREE_LONG_PTRS);
+ XFS_BTGEO_LONG_PTRS);
for_each_xfs_iext(ifp, &icur, &rec) {
if (isnullstartblock(rec.br_startblock))
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 8ffef40ba..acb83443f 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -45,7 +45,7 @@ xfs_bmdr_to_bmbt(
xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL,
XFS_BTNUM_BMAP, 0, 0, ip->i_ino,
- XFS_BTREE_LONG_PTRS);
+ XFS_BTGEO_LONG_PTRS);
rblock->bb_level = dblock->bb_level;
ASSERT(be16_to_cpu(rblock->bb_level) > 0);
rblock->bb_numrecs = dblock->bb_numrecs;
@@ -515,6 +515,8 @@ xfs_bmbt_keys_contiguous(
}
static const struct xfs_btree_ops xfs_bmbt_ops = {
+ .geom_flags = XFS_BTGEO_LONG_PTRS | XFS_BTGEO_ROOT_IN_INODE,
+
.rec_len = sizeof(xfs_bmbt_rec_t),
.key_len = sizeof(xfs_bmbt_key_t),
@@ -552,8 +554,6 @@ xfs_bmbt_init_common(
mp->m_bm_maxlevels[whichfork], xfs_bmbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
- cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
-
cur->bc_ino.ip = ip;
cur->bc_ino.allocated = 0;
cur->bc_ino.flags = 0;
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 38d82c03a..cd8cb2def 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -258,7 +258,7 @@ xfs_btree_check_block(
int level, /* level of the btree block */
struct xfs_buf *bp) /* buffer containing block, if any */
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
return xfs_btree_check_lblock(cur, block, level, bp);
else
return xfs_btree_check_sblock(cur, block, level, bp);
@@ -299,7 +299,7 @@ xfs_btree_check_ptr(
int index,
int level)
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]),
level))
return 0;
@@ -455,7 +455,7 @@ xfs_btree_del_cursor(
xfs_is_shutdown(cur->bc_mp) || error != 0);
if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
kfree(cur->bc_ops);
- if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS) && cur->bc_ag.pag)
+ if (!(cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) && cur->bc_ag.pag)
xfs_perag_put(cur->bc_ag.pag);
kmem_cache_free(cur->bc_cache, cur);
}
@@ -544,7 +544,7 @@ xfs_btree_dup_cursor(
* record, key or pointer (xfs_btree_*_addr). Note that all addressing
* inside the btree block is done using indices starting at one, not zero!
*
- * If XFS_BTREE_OVERLAPPING is set, then this btree supports keys containing
+ * If XFS_BTGEO_OVERLAPPING is set, then this btree supports keys containing
* overlapping intervals. In such a tree, records are still sorted lowest to
* highest and indexed by the smallest key value that refers to the record.
* However, nodes are different: each pointer has two associated keys -- one
@@ -594,7 +594,7 @@ xfs_btree_dup_cursor(
*/
static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (xfs_has_crc(cur->bc_mp))
return XFS_BTREE_LBLOCK_CRC_LEN;
return XFS_BTREE_LBLOCK_LEN;
@@ -609,7 +609,7 @@ static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
*/
static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur)
{
- return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
+ return (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) ?
sizeof(__be64) : sizeof(__be32);
}
@@ -723,7 +723,7 @@ struct xfs_ifork *
xfs_btree_ifork_ptr(
struct xfs_btree_cur *cur)
{
- ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
if (cur->bc_flags & XFS_BTREE_STAGING)
return cur->bc_ino.ifake->if_fork;
@@ -755,7 +755,7 @@ xfs_btree_get_block(
int level, /* level in btree */
struct xfs_buf **bpp) /* buffer containing the block */
{
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
(level == cur->bc_nlevels - 1)) {
*bpp = NULL;
return xfs_btree_get_iroot(cur);
@@ -998,7 +998,7 @@ xfs_btree_readahead(
* No readahead needed if we are at the root level and the
* btree root is stored in the inode.
*/
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
(lev == cur->bc_nlevels - 1))
return 0;
@@ -1008,7 +1008,7 @@ xfs_btree_readahead(
cur->bc_levels[lev].ra |= lr;
block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
return xfs_btree_readahead_lblock(cur, lr, block);
return xfs_btree_readahead_sblock(cur, lr, block);
}
@@ -1027,7 +1027,7 @@ xfs_btree_ptr_to_daddr(
if (error)
return error;
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
fsbno = be64_to_cpu(ptr->l);
*daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno);
} else {
@@ -1077,7 +1077,7 @@ xfs_btree_setbuf(
cur->bc_levels[lev].ra = 0;
b = XFS_BUF_TO_BLOCK(bp);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK))
cur->bc_levels[lev].ra |= XFS_BTCUR_LEFTRA;
if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK))
@@ -1095,7 +1095,7 @@ xfs_btree_ptr_is_null(
struct xfs_btree_cur *cur,
const union xfs_btree_ptr *ptr)
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
return ptr->l == cpu_to_be64(NULLFSBLOCK);
else
return ptr->s == cpu_to_be32(NULLAGBLOCK);
@@ -1106,7 +1106,7 @@ xfs_btree_set_ptr_null(
struct xfs_btree_cur *cur,
union xfs_btree_ptr *ptr)
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
ptr->l = cpu_to_be64(NULLFSBLOCK);
else
ptr->s = cpu_to_be32(NULLAGBLOCK);
@@ -1124,7 +1124,7 @@ xfs_btree_get_sibling(
{
ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (lr == XFS_BB_RIGHTSIB)
ptr->l = block->bb_u.l.bb_rightsib;
else
@@ -1146,7 +1146,7 @@ xfs_btree_set_sibling(
{
ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (lr == XFS_BB_RIGHTSIB)
block->bb_u.l.bb_rightsib = ptr->l;
else
@@ -1168,16 +1168,16 @@ xfs_btree_init_block_int(
__u16 level,
__u16 numrecs,
__u64 owner,
- unsigned int flags)
+ unsigned int geom_flags)
{
- int crc = xfs_has_crc(mp);
+ bool crc = xfs_has_crc(mp);
__u32 magic = xfs_btree_magic(crc, btnum);
buf->bb_magic = cpu_to_be32(magic);
buf->bb_level = cpu_to_be16(level);
buf->bb_numrecs = cpu_to_be16(numrecs);
- if (flags & XFS_BTREE_LONG_PTRS) {
+ if (geom_flags & XFS_BTGEO_LONG_PTRS) {
buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK);
buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK);
if (crc) {
@@ -1230,14 +1230,14 @@ xfs_btree_init_block_cur(
* change in future, but is safe for current users of the generic btree
* code.
*/
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
owner = cur->bc_ino.ip->i_ino;
else
owner = cur->bc_ag.pag->pag_agno;
xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp),
xfs_buf_daddr(bp), cur->bc_btnum, level,
- numrecs, owner, cur->bc_flags);
+ numrecs, owner, cur->bc_ops->geom_flags);
}
/*
@@ -1255,7 +1255,7 @@ xfs_btree_is_lastrec(
if (level > 0)
return 0;
- if (!(cur->bc_flags & XFS_BTREE_LASTREC_UPDATE))
+ if (!(cur->bc_ops->geom_flags & XFS_BTGEO_LASTREC_UPDATE))
return 0;
xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
@@ -1270,7 +1270,7 @@ xfs_btree_buf_to_ptr(
struct xfs_buf *bp,
union xfs_btree_ptr *ptr)
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp,
xfs_buf_daddr(bp)));
else {
@@ -1588,7 +1588,7 @@ xfs_btree_log_block(
nbits = XFS_BB_NUM_BITS;
}
xfs_btree_offsets(fields,
- (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
+ (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) ?
loffsets : soffsets,
nbits, &first, &last);
xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
@@ -1665,7 +1665,7 @@ xfs_btree_increment(
* confused or have the tree root in an inode.
*/
if (lev == cur->bc_nlevels) {
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
goto out0;
ASSERT(0);
xfs_btree_mark_sick(cur);
@@ -1759,7 +1759,7 @@ xfs_btree_decrement(
* or the root of the tree is in an inode.
*/
if (lev == cur->bc_nlevels) {
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
goto out0;
ASSERT(0);
xfs_btree_mark_sick(cur);
@@ -1807,7 +1807,7 @@ xfs_btree_lookup_get_block(
int error = 0;
/* special case the root block if in an inode */
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
(level == cur->bc_nlevels - 1)) {
*blkp = xfs_btree_get_iroot(cur);
return 0;
@@ -1835,7 +1835,7 @@ xfs_btree_lookup_get_block(
/* Check the inode owner since the verifiers don't. */
if (xfs_has_crc(cur->bc_mp) &&
!(cur->bc_ino.flags & XFS_BTCUR_BMBT_INVALID_OWNER) &&
- (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
+ (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) &&
be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
cur->bc_ino.ip->i_ino)
goto out_bad;
@@ -2055,7 +2055,7 @@ xfs_btree_high_key_from_key(
struct xfs_btree_cur *cur,
union xfs_btree_key *key)
{
- ASSERT(cur->bc_flags & XFS_BTREE_OVERLAPPING);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING);
return (union xfs_btree_key *)((char *)key +
(cur->bc_ops->key_len / 2));
}
@@ -2076,7 +2076,7 @@ xfs_btree_get_leaf_keys(
rec = xfs_btree_rec_addr(cur, 1, block);
cur->bc_ops->init_key_from_rec(key, rec);
- if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING) {
cur->bc_ops->init_high_key_from_rec(&max_hkey, rec);
for (n = 2; n <= xfs_btree_get_numrecs(block); n++) {
@@ -2103,7 +2103,7 @@ xfs_btree_get_node_keys(
union xfs_btree_key *high;
int n;
- if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING) {
memcpy(key, xfs_btree_key_addr(cur, 1, block),
cur->bc_ops->key_len / 2);
@@ -2147,7 +2147,7 @@ xfs_btree_needs_key_update(
struct xfs_btree_cur *cur,
int ptr)
{
- return (cur->bc_flags & XFS_BTREE_OVERLAPPING) || ptr == 1;
+ return (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING) || ptr == 1;
}
/*
@@ -2171,7 +2171,7 @@ __xfs_btree_updkeys(
struct xfs_buf *bp;
int ptr;
- ASSERT(cur->bc_flags & XFS_BTREE_OVERLAPPING);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING);
/* Exit if there aren't any parent levels to update. */
if (level + 1 >= cur->bc_nlevels)
@@ -2240,7 +2240,7 @@ xfs_btree_update_keys(
ASSERT(level >= 0);
block = xfs_btree_get_block(cur, level, &bp);
- if (cur->bc_flags & XFS_BTREE_OVERLAPPING)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING)
return __xfs_btree_updkeys(cur, level, block, bp, false);
/*
@@ -2347,7 +2347,7 @@ xfs_btree_lshift(
int error; /* error return value */
int i;
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
level == cur->bc_nlevels - 1)
goto out0;
@@ -2475,7 +2475,7 @@ xfs_btree_lshift(
* Using a temporary cursor, update the parent key values of the
* block on the left.
*/
- if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING) {
error = xfs_btree_dup_cursor(cur, &tcur);
if (error)
goto error0;
@@ -2543,7 +2543,7 @@ xfs_btree_rshift(
int error; /* error return value */
int i; /* loop counter */
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
(level == cur->bc_nlevels - 1))
goto out0;
@@ -2662,7 +2662,7 @@ xfs_btree_rshift(
goto error1;
/* Update the parent high keys of the left block, if needed. */
- if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING) {
error = xfs_btree_update_keys(cur, level);
if (error)
goto error1;
@@ -2854,7 +2854,7 @@ __xfs_btree_split(
}
/* Update the parent high keys of the left block, if needed. */
- if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING) {
error = xfs_btree_update_keys(cur, level);
if (error)
goto error0;
@@ -3019,7 +3019,7 @@ xfs_btree_new_iroot(
XFS_BTREE_STATS_INC(cur, newroot);
- ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
level = cur->bc_nlevels - 1;
@@ -3047,7 +3047,7 @@ xfs_btree_new_iroot(
memcpy(cblock, block, xfs_btree_block_len(cur));
if (xfs_has_crc(cur->bc_mp)) {
__be64 bno = cpu_to_be64(xfs_buf_daddr(cbp));
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
cblock->bb_u.l.bb_blkno = bno;
else
cblock->bb_u.s.bb_blkno = bno;
@@ -3244,7 +3244,7 @@ xfs_btree_make_block_unfull(
{
int error = 0;
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
level == cur->bc_nlevels - 1) {
struct xfs_inode *ip = cur->bc_ino.ip;
@@ -3330,7 +3330,7 @@ xfs_btree_insrec(
* If we have an external root pointer, and we've made it to the
* root level, allocate a new root block and we're done.
*/
- if (!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if (!(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
(level >= cur->bc_nlevels)) {
error = xfs_btree_new_root(cur, stat);
xfs_btree_set_ptr_null(cur, ptrp);
@@ -3618,7 +3618,7 @@ xfs_btree_kill_iroot(
#endif
int i;
- ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
ASSERT(cur->bc_nlevels > 1);
/*
@@ -3855,7 +3855,7 @@ xfs_btree_delrec(
* nothing left to do.
*/
if (level == cur->bc_nlevels - 1) {
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
xfs_iroot_realloc(cur->bc_ino.ip, -1,
cur->bc_ino.whichfork);
@@ -3923,7 +3923,7 @@ xfs_btree_delrec(
xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
xfs_btree_get_sibling(cur, block, &lptr, XFS_BB_LEFTSIB);
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
/*
* One child of root, need to get a chance to copy its contents
* into the root and delete it. Can't go up to next level,
@@ -4240,7 +4240,7 @@ xfs_btree_delrec(
* If we joined with the right neighbor and there's a level above
* us, increment the cursor at that level.
*/
- else if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) ||
+ else if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) ||
(level + 1 < cur->bc_nlevels)) {
error = xfs_btree_increment(cur, level + 1, &i);
if (error)
@@ -4309,7 +4309,7 @@ xfs_btree_delete(
* If we combined blocks as part of deleting the record, delrec won't
* have updated the parent high keys so we have to do that here.
*/
- if (joined && (cur->bc_flags & XFS_BTREE_OVERLAPPING)) {
+ if (joined && (cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING)) {
error = xfs_btree_updkeys_force(cur, 0);
if (error)
goto error0;
@@ -4406,7 +4406,7 @@ xfs_btree_visit_block(
* return the same block without checking if the right sibling points
* back to us and creates a cyclic reference in the btree.
*/
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (be64_to_cpu(rptr.l) == XFS_DADDR_TO_FSB(cur->bc_mp,
xfs_buf_daddr(bp))) {
xfs_btree_mark_sick(cur);
@@ -4514,7 +4514,7 @@ xfs_btree_block_change_owner(
/* modify the owner */
block = xfs_btree_get_block(cur, level, &bp);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
if (block->bb_u.l.bb_owner == cpu_to_be64(bbcoi->new_owner))
return 0;
block->bb_u.l.bb_owner = cpu_to_be64(bbcoi->new_owner);
@@ -4532,7 +4532,7 @@ xfs_btree_block_change_owner(
* though, so everything is consistent in memory.
*/
if (!bp) {
- ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
ASSERT(level == cur->bc_nlevels - 1);
return 0;
}
@@ -5009,7 +5009,7 @@ xfs_btree_query_range(
if (!xfs_btree_keycmp_le(cur, &low_key, &high_key))
return -EINVAL;
- if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
+ if (!(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING))
return xfs_btree_simple_query_range(cur, &low_key,
&high_key, fn, priv);
return xfs_btree_overlapped_query_range(cur, &low_key, &high_key,
@@ -5063,7 +5063,7 @@ xfs_btree_diff_two_ptrs(
const union xfs_btree_ptr *a,
const union xfs_btree_ptr *b)
{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
return (int64_t)be64_to_cpu(a->l) - be64_to_cpu(b->l);
return (int64_t)be32_to_cpu(a->s) - be32_to_cpu(b->s);
}
@@ -5117,7 +5117,7 @@ xfs_btree_has_records_helper(
key_contig = cur->bc_ops->keys_contiguous(cur, &info->high_key,
&rec_key, info->key_mask);
if (key_contig == XBTREE_KEY_OVERLAP &&
- !(cur->bc_flags & XFS_BTREE_OVERLAPPING))
+ !(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING))
return -EFSCORRUPTED;
if (key_contig == XBTREE_KEY_GAP)
return -ECANCELED;
@@ -5211,7 +5211,7 @@ xfs_btree_has_more_records(
return true;
/* There are more record blocks. */
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
return block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK);
else
return block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK);
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 36fd07b32..5a292d7a70 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -112,6 +112,9 @@ static inline enum xbtree_key_contig xbtree_key_contig(uint64_t x, uint64_t y)
}
struct xfs_btree_ops {
+ /* XFS_BTGEO_* flags that determine the geometry of the btree */
+ unsigned int geom_flags;
+
/* size of the key and record structures */
size_t key_len;
size_t rec_len;
@@ -199,6 +202,12 @@ struct xfs_btree_ops {
const union xfs_btree_key *mask);
};
+/* btree geometry flags */
+#define XFS_BTGEO_LONG_PTRS (1U << 0) /* pointers are 64bits long */
+#define XFS_BTGEO_ROOT_IN_INODE (1U << 1) /* root may be variable size */
+#define XFS_BTGEO_LASTREC_UPDATE (1U << 2) /* track last rec externally */
+#define XFS_BTGEO_OVERLAPPING (1U << 3) /* overlapping intervals */
+
/*
* Reasons for the update_lastrec method to be called.
*/
@@ -281,7 +290,7 @@ struct xfs_btree_cur
/*
* Short btree pointers need an agno to be able to turn the pointers
* into physical addresses for IO, so the btree cursor switches between
- * bc_ino and bc_ag based on whether XFS_BTREE_LONG_PTRS is set for the
+ * bc_ino and bc_ag based on whether XFS_BTGEO_LONG_PTRS is set for the
* cursor.
*/
union {
@@ -304,17 +313,13 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
return struct_size_t(struct xfs_btree_cur, bc_levels, nlevels);
}
-/* cursor flags */
-#define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */
-#define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */
-#define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */
-#define XFS_BTREE_OVERLAPPING (1<<4) /* overlapping intervals */
+/* cursor state flags */
/*
* The root of this btree is a fakeroot structure so that we can stage a btree
* rebuild without leaving it accessible via primary metadata. The ops struct
* is dynamically allocated and must be freed when the cursor is deleted.
*/
-#define XFS_BTREE_STAGING (1<<5)
+#define XFS_BTREE_STAGING (1U << 0)
#define XFS_BTREE_NOERROR 0
#define XFS_BTREE_ERROR 1
@@ -447,7 +452,7 @@ xfs_btree_init_block_int(
__u16 level,
__u16 numrecs,
__u64 owner,
- unsigned int flags);
+ unsigned int geom_flags);
/*
* Common btree core entry points.
@@ -689,7 +694,7 @@ xfs_btree_islastblock(
block = xfs_btree_get_block(cur, level, &bp);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK);
return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK);
}
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 45ef6aba8..ac99543e0 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -136,7 +136,7 @@ xfs_btree_stage_afakeroot(
struct xfs_btree_ops *nops;
ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
- ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE));
+ ASSERT(!(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE));
ASSERT(cur->bc_tp == NULL);
nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
@@ -217,7 +217,7 @@ xfs_btree_stage_ifakeroot(
struct xfs_btree_ops *nops;
ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
- ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
ASSERT(cur->bc_tp == NULL);
nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
@@ -397,7 +397,7 @@ xfs_btree_bload_prep_block(
struct xfs_btree_block *new_block;
int ret;
- if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
level == cur->bc_nlevels - 1) {
struct xfs_ifork *ifp = xfs_btree_ifork_ptr(cur);
size_t new_size;
@@ -413,7 +413,7 @@ xfs_btree_bload_prep_block(
xfs_btree_init_block_int(cur->bc_mp, ifp->if_broot,
XFS_BUF_DADDR_NULL, cur->bc_btnum, level,
nr_this_block, cur->bc_ino.ip->i_ino,
- cur->bc_flags);
+ cur->bc_ops->geom_flags);
*bpp = NULL;
*blockp = ifp->if_broot;
@@ -704,7 +704,7 @@ xfs_btree_bload_compute_geometry(
xfs_btree_bload_level_geometry(cur, bbl, level, nr_this_level,
&avg_per_block, &level_blocks, &dontcare64);
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
/*
* If all the items we want to store at this level
* would fit in the inode root block, then we have our
@@ -763,7 +763,7 @@ xfs_btree_bload_compute_geometry(
return -EOVERFLOW;
bbl->btree_height = cur->bc_nlevels;
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
bbl->nr_blocks = nr_blocks - 1;
else
bbl->nr_blocks = nr_blocks;
@@ -890,7 +890,7 @@ xfs_btree_bload(
}
/* Initialize the new root. */
- if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
cur->bc_ino.ifake->if_levels = cur->bc_nlevels;
cur->bc_ino.ifake->if_blocks = total_blocks - 1;
diff --git a/libxfs/xfs_btree_staging.h b/libxfs/xfs_btree_staging.h
index 055ea43b1..9624ae06c 100644
--- a/libxfs/xfs_btree_staging.h
+++ b/libxfs/xfs_btree_staging.h
@@ -76,7 +76,7 @@ struct xfs_btree_bload {
/*
* This function should return the size of the in-core btree root
- * block. It is only necessary for XFS_BTREE_ROOT_IN_INODE btree
+ * block. It is only necessary for XFS_BTGEO_ROOT_IN_INODE btree
* types.
*/
xfs_btree_bload_iroot_size_fn iroot_size;
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index da6bfb901..7f815522c 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -471,6 +471,8 @@ xfs_rmapbt_keys_contiguous(
}
static const struct xfs_btree_ops xfs_rmapbt_ops = {
+ .geom_flags = XFS_BTGEO_OVERLAPPING,
+
.rec_len = sizeof(struct xfs_rmap_rec),
.key_len = 2 * sizeof(struct xfs_rmap_key),
@@ -503,7 +505,6 @@ xfs_rmapbt_init_common(
/* Overlapping btree; 2 keys per pointer. */
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
- cur->bc_flags = XFS_BTREE_OVERLAPPING;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
cur->bc_ag.pag = xfs_perag_hold(pag);
diff --git a/repair/bulkload.c b/repair/bulkload.c
index a97839f54..31d136bb8 100644
--- a/repair/bulkload.c
+++ b/repair/bulkload.c
@@ -314,7 +314,7 @@ bulkload_claim_block(
if (resv->used == resv->len)
list_move_tail(&resv->list, &bkl->resv_list);
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
ptr->l = cpu_to_be64(XFS_AGB_TO_FSB(mp, resv->pag->pag_agno,
agbno));
else
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 033/111] xfs: remove bc_ino.flags
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (31 preceding siblings ...)
2024-05-22 2:57 ` [PATCH 032/111] xfs: encode the btree geometry flags in the btree ops structure Darrick J. Wong
@ 2024-05-22 2:57 ` Darrick J. Wong
2024-05-22 2:57 ` [PATCH 034/111] xfs: consolidate the xfs_alloc_lookup_* helpers Darrick J. Wong
` (78 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:57 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: e9e66df8bfa4132d905543a6b099ec8a3380b732
Just move the two flags into bc_flags where there is plenty of space.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap.c | 27 +++++++++------------------
libxfs/xfs_bmap_btree.c | 14 ++++----------
libxfs/xfs_btree.c | 2 +-
libxfs/xfs_btree.h | 12 ++++++------
4 files changed, 20 insertions(+), 35 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 72d35f664..9e44f4cae 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -645,7 +645,8 @@ xfs_bmap_extents_to_btree(
* Need a cursor. Can't allocate until bb_level is filled in.
*/
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
- cur->bc_ino.flags = wasdel ? XFS_BTCUR_BMBT_WASDEL : 0;
+ if (wasdel)
+ cur->bc_flags |= XFS_BTREE_BMBT_WASDEL;
/*
* Convert to a btree with two levels, one record in root.
*/
@@ -1443,8 +1444,7 @@ xfs_bmap_add_extent_delay_real(
ASSERT(whichfork != XFS_ATTR_FORK);
ASSERT(!isnullstartblock(new->br_startblock));
- ASSERT(!bma->cur ||
- (bma->cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL));
+ ASSERT(!bma->cur || (bma->cur->bc_flags & XFS_BTREE_BMBT_WASDEL));
XFS_STATS_INC(mp, xs_add_exlist);
@@ -2703,7 +2703,7 @@ xfs_bmap_add_extent_hole_real(
struct xfs_bmbt_irec old;
ASSERT(!isnullstartblock(new->br_startblock));
- ASSERT(!cur || !(cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL));
+ ASSERT(!cur || !(cur->bc_flags & XFS_BTREE_BMBT_WASDEL));
XFS_STATS_INC(mp, xs_add_exlist);
@@ -4223,9 +4223,8 @@ xfs_bmapi_allocate(
*/
bma->nallocs++;
- if (bma->cur)
- bma->cur->bc_ino.flags =
- bma->wasdel ? XFS_BTCUR_BMBT_WASDEL : 0;
+ if (bma->cur && bma->wasdel)
+ bma->cur->bc_flags |= XFS_BTREE_BMBT_WASDEL;
bma->got.br_startoff = bma->offset;
bma->got.br_startblock = bma->blkno;
@@ -4760,10 +4759,8 @@ xfs_bmapi_remap(
ip->i_nblocks += len;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- if (ifp->if_format == XFS_DINODE_FMT_BTREE) {
+ if (ifp->if_format == XFS_DINODE_FMT_BTREE)
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
- cur->bc_ino.flags = 0;
- }
got.br_startoff = bno;
got.br_startblock = startblock;
@@ -5394,7 +5391,6 @@ __xfs_bunmapi(
if (ifp->if_format == XFS_DINODE_FMT_BTREE) {
ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE);
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
- cur->bc_ino.flags = 0;
} else
cur = NULL;
@@ -5855,10 +5851,8 @@ xfs_bmap_collapse_extents(
if (error)
return error;
- if (ifp->if_format == XFS_DINODE_FMT_BTREE) {
+ if (ifp->if_format == XFS_DINODE_FMT_BTREE)
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
- cur->bc_ino.flags = 0;
- }
if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) {
*done = true;
@@ -5972,10 +5966,8 @@ xfs_bmap_insert_extents(
if (error)
return error;
- if (ifp->if_format == XFS_DINODE_FMT_BTREE) {
+ if (ifp->if_format == XFS_DINODE_FMT_BTREE)
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
- cur->bc_ino.flags = 0;
- }
if (*next_fsb == NULLFSBLOCK) {
xfs_iext_last(ifp, &icur);
@@ -6092,7 +6084,6 @@ xfs_bmap_split_extent(
if (ifp->if_format == XFS_DINODE_FMT_BTREE) {
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
- cur->bc_ino.flags = 0;
error = xfs_bmbt_lookup_eq(cur, &got, &i);
if (error)
goto del_cursor;
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index acb83443f..52a1ce460 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -170,13 +170,8 @@ xfs_bmbt_dup_cursor(
new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp,
cur->bc_ino.ip, cur->bc_ino.whichfork);
-
- /*
- * Copy the firstblock, dfops, and flags values,
- * since init cursor doesn't get them.
- */
- new->bc_ino.flags = cur->bc_ino.flags;
-
+ new->bc_flags |= (cur->bc_flags &
+ (XFS_BTREE_BMBT_INVALID_OWNER | XFS_BTREE_BMBT_WASDEL));
return new;
}
@@ -210,7 +205,7 @@ xfs_bmbt_alloc_block(
xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_ino.ip->i_ino,
cur->bc_ino.whichfork);
args.minlen = args.maxlen = args.prod = 1;
- args.wasdel = cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL;
+ args.wasdel = cur->bc_flags & XFS_BTREE_BMBT_WASDEL;
if (!args.wasdel && args.tp->t_blk_res == 0)
return -ENOSPC;
@@ -556,7 +551,6 @@ xfs_bmbt_init_common(
cur->bc_ino.ip = ip;
cur->bc_ino.allocated = 0;
- cur->bc_ino.flags = 0;
return cur;
}
@@ -747,7 +741,7 @@ xfs_bmbt_change_owner(
ASSERT(xfs_ifork_ptr(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE);
cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork);
- cur->bc_ino.flags |= XFS_BTCUR_BMBT_INVALID_OWNER;
+ cur->bc_flags |= XFS_BTREE_BMBT_INVALID_OWNER;
error = xfs_btree_change_owner(cur, new_owner, buffer_list);
xfs_btree_del_cursor(cur, error);
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index cd8cb2def..3b9c95bcf 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1834,7 +1834,7 @@ xfs_btree_lookup_get_block(
/* Check the inode owner since the verifiers don't. */
if (xfs_has_crc(cur->bc_mp) &&
- !(cur->bc_ino.flags & XFS_BTCUR_BMBT_INVALID_OWNER) &&
+ !(cur->bc_flags & XFS_BTREE_BMBT_INVALID_OWNER) &&
(cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) &&
be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
cur->bc_ino.ip->i_ino)
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 5a292d7a70..17a0324a3 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -249,12 +249,6 @@ struct xfs_btree_cur_ino {
int allocated;
short forksize;
char whichfork;
- char flags;
-/* We are converting a delalloc reservation */
-#define XFS_BTCUR_BMBT_WASDEL (1 << 0)
-
-/* For extent swap, ignore owner check in verifier */
-#define XFS_BTCUR_BMBT_INVALID_OWNER (1 << 1)
};
struct xfs_btree_level {
@@ -321,6 +315,12 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
*/
#define XFS_BTREE_STAGING (1U << 0)
+/* We are converting a delalloc reservation (only for bmbt btrees) */
+#define XFS_BTREE_BMBT_WASDEL (1U << 1)
+
+/* For extent swap, ignore owner check in verifier (only for bmbt btrees) */
+#define XFS_BTREE_BMBT_INVALID_OWNER (1U << 2)
+
#define XFS_BTREE_NOERROR 0
#define XFS_BTREE_ERROR 1
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 034/111] xfs: consolidate the xfs_alloc_lookup_* helpers
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (32 preceding siblings ...)
2024-05-22 2:57 ` [PATCH 033/111] xfs: remove bc_ino.flags Darrick J. Wong
@ 2024-05-22 2:57 ` Darrick J. Wong
2024-05-22 2:57 ` [PATCH 035/111] xfs: turn the allocbt cursor active field into a btree flag Darrick J. Wong
` (77 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:57 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 73a8fd93c421c4a6ac2c581c4d3478d3d68a0def
Add a single xfs_alloc_lookup helper to sort out the argument passing and
setting of the active flag instead of duplicating the logic three times.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc.c | 43 ++++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 3d7686ead..458436166 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -147,23 +147,35 @@ xfs_alloc_ag_max_usable(
return mp->m_sb.sb_agblocks - blocks;
}
+
+static int
+xfs_alloc_lookup(
+ struct xfs_btree_cur *cur,
+ xfs_lookup_t dir,
+ xfs_agblock_t bno,
+ xfs_extlen_t len,
+ int *stat)
+{
+ int error;
+
+ cur->bc_rec.a.ar_startblock = bno;
+ cur->bc_rec.a.ar_blockcount = len;
+ error = xfs_btree_lookup(cur, dir, stat);
+ cur->bc_ag.abt.active = (*stat == 1);
+ return error;
+}
+
/*
* Lookup the record equal to [bno, len] in the btree given by cur.
*/
-STATIC int /* error */
+static inline int /* error */
xfs_alloc_lookup_eq(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_agblock_t bno, /* starting block of extent */
xfs_extlen_t len, /* length of extent */
int *stat) /* success/failure */
{
- int error;
-
- cur->bc_rec.a.ar_startblock = bno;
- cur->bc_rec.a.ar_blockcount = len;
- error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
- cur->bc_ag.abt.active = (*stat == 1);
- return error;
+ return xfs_alloc_lookup(cur, XFS_LOOKUP_EQ, bno, len, stat);
}
/*
@@ -177,13 +189,7 @@ xfs_alloc_lookup_ge(
xfs_extlen_t len, /* length of extent */
int *stat) /* success/failure */
{
- int error;
-
- cur->bc_rec.a.ar_startblock = bno;
- cur->bc_rec.a.ar_blockcount = len;
- error = xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
- cur->bc_ag.abt.active = (*stat == 1);
- return error;
+ return xfs_alloc_lookup(cur, XFS_LOOKUP_GE, bno, len, stat);
}
/*
@@ -197,12 +203,7 @@ xfs_alloc_lookup_le(
xfs_extlen_t len, /* length of extent */
int *stat) /* success/failure */
{
- int error;
- cur->bc_rec.a.ar_startblock = bno;
- cur->bc_rec.a.ar_blockcount = len;
- error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
- cur->bc_ag.abt.active = (*stat == 1);
- return error;
+ return xfs_alloc_lookup(cur, XFS_LOOKUP_LE, bno, len, stat);
}
static inline bool
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 035/111] xfs: turn the allocbt cursor active field into a btree flag
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (33 preceding siblings ...)
2024-05-22 2:57 ` [PATCH 034/111] xfs: consolidate the xfs_alloc_lookup_* helpers Darrick J. Wong
@ 2024-05-22 2:57 ` Darrick J. Wong
2024-05-22 2:58 ` [PATCH 036/111] xfs: extern some btree ops structures Darrick J. Wong
` (76 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:57 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: b20775ed644af0cbaee9632ad63ae6ec5ee502cc
Add a new XFS_BTREE_ALLOCBT_ACTIVE flag to replace the active field.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc.c | 13 ++++++++-----
libxfs/xfs_alloc_btree.c | 1 -
libxfs/xfs_btree.h | 6 +++---
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 458436166..e5ae53948 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -161,7 +161,10 @@ xfs_alloc_lookup(
cur->bc_rec.a.ar_startblock = bno;
cur->bc_rec.a.ar_blockcount = len;
error = xfs_btree_lookup(cur, dir, stat);
- cur->bc_ag.abt.active = (*stat == 1);
+ if (*stat == 1)
+ cur->bc_flags |= XFS_BTREE_ALLOCBT_ACTIVE;
+ else
+ cur->bc_flags &= ~XFS_BTREE_ALLOCBT_ACTIVE;
return error;
}
@@ -210,7 +213,7 @@ static inline bool
xfs_alloc_cur_active(
struct xfs_btree_cur *cur)
{
- return cur && cur->bc_ag.abt.active;
+ return cur && (cur->bc_flags & XFS_BTREE_ALLOCBT_ACTIVE);
}
/*
@@ -988,7 +991,7 @@ xfs_alloc_cur_check(
deactivate = true;
out:
if (deactivate)
- cur->bc_ag.abt.active = false;
+ cur->bc_flags &= ~XFS_BTREE_ALLOCBT_ACTIVE;
trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff,
*new);
return 0;
@@ -1363,7 +1366,7 @@ xfs_alloc_walk_iter(
if (error)
return error;
if (i == 0)
- cur->bc_ag.abt.active = false;
+ cur->bc_flags &= ~XFS_BTREE_ALLOCBT_ACTIVE;
if (count > 0)
count--;
@@ -1477,7 +1480,7 @@ xfs_alloc_ag_vextent_locality(
if (error)
return error;
if (i) {
- acur->cnt->bc_ag.abt.active = true;
+ acur->cnt->bc_flags |= XFS_BTREE_ALLOCBT_ACTIVE;
fbcur = acur->cnt;
fbinc = false;
}
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index d3ecd513d..e3c2f90eb 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -521,7 +521,6 @@ xfs_allocbt_init_common(
mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
}
- cur->bc_ag.abt.active = false;
cur->bc_ag.pag = xfs_perag_hold(pag);
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 17a0324a3..b36530e56 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -236,9 +236,6 @@ struct xfs_btree_cur_ag {
unsigned int nr_ops; /* # record updates */
unsigned int shape_changes; /* # of extent splits */
} refc;
- struct {
- bool active; /* allocation cursor state */
- } abt;
};
};
@@ -321,6 +318,9 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
/* For extent swap, ignore owner check in verifier (only for bmbt btrees) */
#define XFS_BTREE_BMBT_INVALID_OWNER (1U << 2)
+/* Cursor is active (only for allocbt btrees) */
+#define XFS_BTREE_ALLOCBT_ACTIVE (1U << 3)
+
#define XFS_BTREE_NOERROR 0
#define XFS_BTREE_ERROR 1
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 036/111] xfs: extern some btree ops structures
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (34 preceding siblings ...)
2024-05-22 2:57 ` [PATCH 035/111] xfs: turn the allocbt cursor active field into a btree flag Darrick J. Wong
@ 2024-05-22 2:58 ` Darrick J. Wong
2024-05-22 2:58 ` [PATCH 037/111] xfs: initialize btree blocks using btree_ops structure Darrick J. Wong
` (75 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:58 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: d8d6df4253adcdb5862a9410d962e9168b973c88
Expose these static btree ops structures so that we can reference them
in the AG initialization code in the next patch.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_alloc_btree.c | 4 ++--
libxfs/xfs_bmap_btree.c | 2 +-
libxfs/xfs_ialloc_btree.c | 4 ++--
libxfs/xfs_refcount_btree.c | 2 +-
libxfs/xfs_rmap_btree.c | 2 +-
libxfs/xfs_shared.h | 9 +++++++++
6 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index e3c2f90eb..6c9781fcf 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -452,7 +452,7 @@ xfs_allocbt_keys_contiguous(
be32_to_cpu(key2->alloc.ar_startblock));
}
-static const struct xfs_btree_ops xfs_bnobt_ops = {
+const struct xfs_btree_ops xfs_bnobt_ops = {
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
@@ -475,7 +475,7 @@ static const struct xfs_btree_ops xfs_bnobt_ops = {
.keys_contiguous = xfs_allocbt_keys_contiguous,
};
-static const struct xfs_btree_ops xfs_cntbt_ops = {
+const struct xfs_btree_ops xfs_cntbt_ops = {
.geom_flags = XFS_BTGEO_LASTREC_UPDATE,
.rec_len = sizeof(xfs_alloc_rec_t),
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 52a1ce460..41b4419b5 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -509,7 +509,7 @@ xfs_bmbt_keys_contiguous(
be64_to_cpu(key2->bmbt.br_startoff));
}
-static const struct xfs_btree_ops xfs_bmbt_ops = {
+const struct xfs_btree_ops xfs_bmbt_ops = {
.geom_flags = XFS_BTGEO_LONG_PTRS | XFS_BTGEO_ROOT_IN_INODE,
.rec_len = sizeof(xfs_bmbt_rec_t),
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index dea661afc..52cc00e4f 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -397,7 +397,7 @@ xfs_inobt_keys_contiguous(
be32_to_cpu(key2->inobt.ir_startino));
}
-static const struct xfs_btree_ops xfs_inobt_ops = {
+const struct xfs_btree_ops xfs_inobt_ops = {
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
@@ -419,7 +419,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
.keys_contiguous = xfs_inobt_keys_contiguous,
};
-static const struct xfs_btree_ops xfs_finobt_ops = {
+const struct xfs_btree_ops xfs_finobt_ops = {
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 1ecd670a9..2f91c7b62 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -316,7 +316,7 @@ xfs_refcountbt_keys_contiguous(
be32_to_cpu(key2->refc.rc_startblock));
}
-static const struct xfs_btree_ops xfs_refcountbt_ops = {
+const struct xfs_btree_ops xfs_refcountbt_ops = {
.rec_len = sizeof(struct xfs_refcount_rec),
.key_len = sizeof(struct xfs_refcount_key),
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 7f815522c..c3a113c88 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -470,7 +470,7 @@ xfs_rmapbt_keys_contiguous(
be32_to_cpu(key2->rmap.rm_startblock));
}
-static const struct xfs_btree_ops xfs_rmapbt_ops = {
+const struct xfs_btree_ops xfs_rmapbt_ops = {
.geom_flags = XFS_BTGEO_OVERLAPPING,
.rec_len = sizeof(struct xfs_rmap_rec),
diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h
index 4220d3584..518ea9456 100644
--- a/libxfs/xfs_shared.h
+++ b/libxfs/xfs_shared.h
@@ -43,6 +43,15 @@ extern const struct xfs_buf_ops xfs_sb_buf_ops;
extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops;
extern const struct xfs_buf_ops xfs_symlink_buf_ops;
+/* btree ops */
+extern const struct xfs_btree_ops xfs_bnobt_ops;
+extern const struct xfs_btree_ops xfs_cntbt_ops;
+extern const struct xfs_btree_ops xfs_inobt_ops;
+extern const struct xfs_btree_ops xfs_finobt_ops;
+extern const struct xfs_btree_ops xfs_bmbt_ops;
+extern const struct xfs_btree_ops xfs_refcountbt_ops;
+extern const struct xfs_btree_ops xfs_rmapbt_ops;
+
/* log size calculation functions */
int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes);
int xfs_log_calc_minimum_size(struct xfs_mount *);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 037/111] xfs: initialize btree blocks using btree_ops structure
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (35 preceding siblings ...)
2024-05-22 2:58 ` [PATCH 036/111] xfs: extern some btree ops structures Darrick J. Wong
@ 2024-05-22 2:58 ` Darrick J. Wong
2024-05-22 2:58 ` [PATCH 038/111] xfs: rename btree block/buffer init functions Darrick J. Wong
` (74 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:58 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: c87e3bf7802477cb4500dfafe0ab039313aa2dda
Notice now that the btree ops structure encodes btree geometry flags and
the magic number through the buffer ops. Refactor the btree block
initialization functions to use the btree ops so that we no longer have
to open code all that.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_ag.c | 33 ++++++++++---------------
libxfs/xfs_ag.h | 2 +-
libxfs/xfs_bmap.c | 8 ++----
libxfs/xfs_bmap_btree.c | 20 +++++++++++++--
libxfs/xfs_bmap_btree.h | 3 ++
libxfs/xfs_btree.c | 57 ++++++++++++++++++--------------------------
libxfs/xfs_btree.h | 28 ++++++----------------
libxfs/xfs_btree_staging.c | 5 ++--
8 files changed, 69 insertions(+), 87 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index b16f9c5c5..932bdfb8d 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -490,7 +490,7 @@ xfs_btroot_init(
struct xfs_buf *bp,
struct aghdr_init_data *id)
{
- xfs_btree_init_block(mp, bp, id->type, 0, 0, id->agno);
+ xfs_btree_init_block(mp, bp, id->bc_ops, 0, 0, id->agno);
}
/* Finish initializing a free space btree. */
@@ -548,7 +548,7 @@ xfs_freesp_init_recs(
}
/*
- * Alloc btree root block init functions
+ * bnobt/cntbt btree root block init functions
*/
static void
xfs_bnoroot_init(
@@ -556,17 +556,7 @@ xfs_bnoroot_init(
struct xfs_buf *bp,
struct aghdr_init_data *id)
{
- xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 0, id->agno);
- xfs_freesp_init_recs(mp, bp, id);
-}
-
-static void
-xfs_cntroot_init(
- struct xfs_mount *mp,
- struct xfs_buf *bp,
- struct aghdr_init_data *id)
-{
- xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 0, id->agno);
+ xfs_btree_init_block(mp, bp, id->bc_ops, 0, 0, id->agno);
xfs_freesp_init_recs(mp, bp, id);
}
@@ -582,7 +572,7 @@ xfs_rmaproot_init(
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
struct xfs_rmap_rec *rrec;
- xfs_btree_init_block(mp, bp, XFS_BTNUM_RMAP, 0, 4, id->agno);
+ xfs_btree_init_block(mp, bp, id->bc_ops, 0, 4, id->agno);
/*
* mark the AG header regions as static metadata The BNO
@@ -795,7 +785,7 @@ struct xfs_aghdr_grow_data {
size_t numblks;
const struct xfs_buf_ops *ops;
aghdr_init_work_f work;
- xfs_btnum_t type;
+ const struct xfs_btree_ops *bc_ops;
bool need_init;
};
@@ -849,13 +839,15 @@ xfs_ag_init_headers(
.numblks = BTOBB(mp->m_sb.sb_blocksize),
.ops = &xfs_bnobt_buf_ops,
.work = &xfs_bnoroot_init,
+ .bc_ops = &xfs_bnobt_ops,
.need_init = true
},
{ /* CNT root block */
.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_CNT_BLOCK(mp)),
.numblks = BTOBB(mp->m_sb.sb_blocksize),
.ops = &xfs_cntbt_buf_ops,
- .work = &xfs_cntroot_init,
+ .work = &xfs_bnoroot_init,
+ .bc_ops = &xfs_cntbt_ops,
.need_init = true
},
{ /* INO root block */
@@ -863,7 +855,7 @@ xfs_ag_init_headers(
.numblks = BTOBB(mp->m_sb.sb_blocksize),
.ops = &xfs_inobt_buf_ops,
.work = &xfs_btroot_init,
- .type = XFS_BTNUM_INO,
+ .bc_ops = &xfs_inobt_ops,
.need_init = true
},
{ /* FINO root block */
@@ -871,7 +863,7 @@ xfs_ag_init_headers(
.numblks = BTOBB(mp->m_sb.sb_blocksize),
.ops = &xfs_finobt_buf_ops,
.work = &xfs_btroot_init,
- .type = XFS_BTNUM_FINO,
+ .bc_ops = &xfs_finobt_ops,
.need_init = xfs_has_finobt(mp)
},
{ /* RMAP root block */
@@ -879,6 +871,7 @@ xfs_ag_init_headers(
.numblks = BTOBB(mp->m_sb.sb_blocksize),
.ops = &xfs_rmapbt_buf_ops,
.work = &xfs_rmaproot_init,
+ .bc_ops = &xfs_rmapbt_ops,
.need_init = xfs_has_rmapbt(mp)
},
{ /* REFC root block */
@@ -886,7 +879,7 @@ xfs_ag_init_headers(
.numblks = BTOBB(mp->m_sb.sb_blocksize),
.ops = &xfs_refcountbt_buf_ops,
.work = &xfs_btroot_init,
- .type = XFS_BTNUM_REFC,
+ .bc_ops = &xfs_refcountbt_ops,
.need_init = xfs_has_reflink(mp)
},
{ /* NULL terminating block */
@@ -904,7 +897,7 @@ xfs_ag_init_headers(
id->daddr = dp->daddr;
id->numblks = dp->numblks;
- id->type = dp->type;
+ id->bc_ops = dp->bc_ops;
error = xfs_ag_init_hdr(mp, id, dp->work, dp->ops);
if (error)
break;
diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h
index 4b343c4fa..77c0fa2bb 100644
--- a/libxfs/xfs_ag.h
+++ b/libxfs/xfs_ag.h
@@ -331,7 +331,7 @@ struct aghdr_init_data {
/* per header data */
xfs_daddr_t daddr; /* header location */
size_t numblks; /* size of header */
- xfs_btnum_t type; /* type of btree root block */
+ const struct xfs_btree_ops *bc_ops; /* btree ops */
};
int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 9e44f4cae..a7b6c44f1 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -638,9 +638,7 @@ xfs_bmap_extents_to_btree(
* Fill in the root.
*/
block = ifp->if_broot;
- xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
- XFS_BTNUM_BMAP, 1, 1, ip->i_ino,
- XFS_BTGEO_LONG_PTRS);
+ xfs_bmbt_init_block(ip, block, NULL, 1, 1);
/*
* Need a cursor. Can't allocate until bb_level is filled in.
*/
@@ -686,9 +684,7 @@ xfs_bmap_extents_to_btree(
*/
abp->b_ops = &xfs_bmbt_buf_ops;
ablock = XFS_BUF_TO_BLOCK(abp);
- xfs_btree_init_block_int(mp, ablock, xfs_buf_daddr(abp),
- XFS_BTNUM_BMAP, 0, 0, ip->i_ino,
- XFS_BTGEO_LONG_PTRS);
+ xfs_bmbt_init_block(ip, ablock, abp, 0, 0);
for_each_xfs_iext(ifp, &icur, &rec) {
if (isnullstartblock(rec.br_startblock))
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 41b4419b5..a3732b4c4 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -25,6 +25,22 @@
static struct kmem_cache *xfs_bmbt_cur_cache;
+void
+xfs_bmbt_init_block(
+ struct xfs_inode *ip,
+ struct xfs_btree_block *buf,
+ struct xfs_buf *bp,
+ __u16 level,
+ __u16 numrecs)
+{
+ if (bp)
+ xfs_btree_init_block(ip->i_mount, bp, &xfs_bmbt_ops, level,
+ numrecs, ip->i_ino);
+ else
+ xfs_btree_init_block_int(ip->i_mount, buf, &xfs_bmbt_ops,
+ XFS_BUF_DADDR_NULL, level, numrecs, ip->i_ino);
+}
+
/*
* Convert on-disk form of btree root to in-memory form.
*/
@@ -43,9 +59,7 @@ xfs_bmdr_to_bmbt(
xfs_bmbt_key_t *tkp;
__be64 *tpp;
- xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL,
- XFS_BTNUM_BMAP, 0, 0, ip->i_ino,
- XFS_BTGEO_LONG_PTRS);
+ xfs_bmbt_init_block(ip, rblock, NULL, 0, 0);
rblock->bb_level = dblock->bb_level;
ASSERT(be16_to_cpu(rblock->bb_level) > 0);
rblock->bb_numrecs = dblock->bb_numrecs;
diff --git a/libxfs/xfs_bmap_btree.h b/libxfs/xfs_bmap_btree.h
index 151b8491f..e93aa42e2 100644
--- a/libxfs/xfs_bmap_btree.h
+++ b/libxfs/xfs_bmap_btree.h
@@ -120,4 +120,7 @@ unsigned int xfs_bmbt_maxlevels_ondisk(void);
int __init xfs_bmbt_init_cur_cache(void);
void xfs_bmbt_destroy_cur_cache(void);
+void xfs_bmbt_init_block(struct xfs_inode *ip, struct xfs_btree_block *buf,
+ struct xfs_buf *bp, __u16 level, __u16 numrecs);
+
#endif /* __XFS_BMAP_BTREE_H__ */
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 3b9c95bcf..5675dd5ae 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -29,24 +29,17 @@
/*
* Btree magic numbers.
*/
-static const uint32_t xfs_magics[2][XFS_BTNUM_MAX] = {
- { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC,
- XFS_FIBT_MAGIC, 0 },
- { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC,
- XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC,
- XFS_REFC_CRC_MAGIC }
-};
-
uint32_t
xfs_btree_magic(
- int crc,
- xfs_btnum_t btnum)
+ struct xfs_mount *mp,
+ const struct xfs_btree_ops *ops)
{
- uint32_t magic = xfs_magics[crc][btnum];
+ int idx = xfs_has_crc(mp) ? 1 : 0;
+ __be32 magic = ops->buf_ops->magic[idx];
/* Ensure we asked for crc for crc-only magics. */
ASSERT(magic != 0);
- return magic;
+ return be32_to_cpu(magic);
}
/*
@@ -125,8 +118,7 @@ __xfs_btree_check_lblock(
struct xfs_buf *bp)
{
struct xfs_mount *mp = cur->bc_mp;
- xfs_btnum_t btnum = cur->bc_btnum;
- int crc = xfs_has_crc(mp);
+ bool crc = xfs_has_crc(mp);
xfs_failaddr_t fa;
xfs_fsblock_t fsb = NULLFSBLOCK;
@@ -140,7 +132,7 @@ __xfs_btree_check_lblock(
return __this_address;
}
- if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(crc, btnum))
+ if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(mp, cur->bc_ops))
return __this_address;
if (be16_to_cpu(block->bb_level) != level)
return __this_address;
@@ -194,8 +186,7 @@ __xfs_btree_check_sblock(
{
struct xfs_mount *mp = cur->bc_mp;
struct xfs_perag *pag = cur->bc_ag.pag;
- xfs_btnum_t btnum = cur->bc_btnum;
- int crc = xfs_has_crc(mp);
+ bool crc = xfs_has_crc(mp);
xfs_failaddr_t fa;
xfs_agblock_t agbno = NULLAGBLOCK;
@@ -207,7 +198,7 @@ __xfs_btree_check_sblock(
return __this_address;
}
- if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(crc, btnum))
+ if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(mp, cur->bc_ops))
return __this_address;
if (be16_to_cpu(block->bb_level) != level)
return __this_address;
@@ -1163,21 +1154,20 @@ void
xfs_btree_init_block_int(
struct xfs_mount *mp,
struct xfs_btree_block *buf,
+ const struct xfs_btree_ops *ops,
xfs_daddr_t blkno,
- xfs_btnum_t btnum,
__u16 level,
__u16 numrecs,
- __u64 owner,
- unsigned int geom_flags)
+ __u64 owner)
{
bool crc = xfs_has_crc(mp);
- __u32 magic = xfs_btree_magic(crc, btnum);
+ __u32 magic = xfs_btree_magic(mp, ops);
buf->bb_magic = cpu_to_be32(magic);
buf->bb_level = cpu_to_be16(level);
buf->bb_numrecs = cpu_to_be16(numrecs);
- if (geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK);
buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK);
if (crc) {
@@ -1204,15 +1194,15 @@ xfs_btree_init_block_int(
void
xfs_btree_init_block(
- struct xfs_mount *mp,
- struct xfs_buf *bp,
- xfs_btnum_t btnum,
- __u16 level,
- __u16 numrecs,
- __u64 owner)
+ struct xfs_mount *mp,
+ struct xfs_buf *bp,
+ const struct xfs_btree_ops *ops,
+ __u16 level,
+ __u16 numrecs,
+ __u64 owner)
{
- xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), xfs_buf_daddr(bp),
- btnum, level, numrecs, owner, 0);
+ xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), ops,
+ xfs_buf_daddr(bp), level, numrecs, owner);
}
void
@@ -1235,9 +1225,8 @@ xfs_btree_init_block_cur(
else
owner = cur->bc_ag.pag->pag_agno;
- xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp),
- xfs_buf_daddr(bp), cur->bc_btnum, level,
- numrecs, owner, cur->bc_ops->geom_flags);
+ xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), cur->bc_ops,
+ xfs_buf_daddr(bp), level, numrecs, owner);
}
/*
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index b36530e56..923f884fe 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -63,7 +63,8 @@ union xfs_btree_rec {
#define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi)
#define XFS_BTNUM_REFC ((xfs_btnum_t)XFS_BTNUM_REFCi)
-uint32_t xfs_btree_magic(int crc, xfs_btnum_t btnum);
+struct xfs_btree_ops;
+uint32_t xfs_btree_magic(struct xfs_mount *mp, const struct xfs_btree_ops *ops);
/*
* For logging record fields.
@@ -434,25 +435,12 @@ xfs_btree_reada_bufs(
/*
* Initialise a new btree block header
*/
-void
-xfs_btree_init_block(
- struct xfs_mount *mp,
- struct xfs_buf *bp,
- xfs_btnum_t btnum,
- __u16 level,
- __u16 numrecs,
- __u64 owner);
-
-void
-xfs_btree_init_block_int(
- struct xfs_mount *mp,
- struct xfs_btree_block *buf,
- xfs_daddr_t blkno,
- xfs_btnum_t btnum,
- __u16 level,
- __u16 numrecs,
- __u64 owner,
- unsigned int geom_flags);
+void xfs_btree_init_block(struct xfs_mount *mp, struct xfs_buf *bp,
+ const struct xfs_btree_ops *ops, __u16 level, __u16 numrecs,
+ __u64 owner);
+void xfs_btree_init_block_int(struct xfs_mount *mp,
+ struct xfs_btree_block *buf, const struct xfs_btree_ops *ops,
+ xfs_daddr_t blkno, __u16 level, __u16 numrecs, __u64 owner);
/*
* Common btree core entry points.
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index ac99543e0..ba3383cad 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -411,9 +411,8 @@ xfs_btree_bload_prep_block(
/* Initialize it and send it out. */
xfs_btree_init_block_int(cur->bc_mp, ifp->if_broot,
- XFS_BUF_DADDR_NULL, cur->bc_btnum, level,
- nr_this_block, cur->bc_ino.ip->i_ino,
- cur->bc_ops->geom_flags);
+ cur->bc_ops, XFS_BUF_DADDR_NULL, level,
+ nr_this_block, cur->bc_ino.ip->i_ino);
*bpp = NULL;
*blockp = ifp->if_broot;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 038/111] xfs: rename btree block/buffer init functions
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (36 preceding siblings ...)
2024-05-22 2:58 ` [PATCH 037/111] xfs: initialize btree blocks using btree_ops structure Darrick J. Wong
@ 2024-05-22 2:58 ` Darrick J. Wong
2024-05-22 2:58 ` [PATCH 039/111] xfs: btree convert xfs_btree_init_block to xfs_btree_init_buf calls Darrick J. Wong
` (73 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:58 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 3c68858b264fac292f74733eeaf558595978a5e5
Rename xfs_btree_init_block_int to xfs_btree_init_block, and
xfs_btree_init_block to xfs_btree_init_buf so that the name suggests the
type that caller are supposed to pass in.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_ag.c | 6 +++---
libxfs/xfs_bmap_btree.c | 4 ++--
libxfs/xfs_btree.c | 8 ++++----
libxfs/xfs_btree.h | 4 ++--
libxfs/xfs_btree_staging.c | 2 +-
5 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 932bdfb8d..cdca7f247 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -490,7 +490,7 @@ xfs_btroot_init(
struct xfs_buf *bp,
struct aghdr_init_data *id)
{
- xfs_btree_init_block(mp, bp, id->bc_ops, 0, 0, id->agno);
+ xfs_btree_init_buf(mp, bp, id->bc_ops, 0, 0, id->agno);
}
/* Finish initializing a free space btree. */
@@ -556,7 +556,7 @@ xfs_bnoroot_init(
struct xfs_buf *bp,
struct aghdr_init_data *id)
{
- xfs_btree_init_block(mp, bp, id->bc_ops, 0, 0, id->agno);
+ xfs_btree_init_buf(mp, bp, id->bc_ops, 0, 0, id->agno);
xfs_freesp_init_recs(mp, bp, id);
}
@@ -572,7 +572,7 @@ xfs_rmaproot_init(
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
struct xfs_rmap_rec *rrec;
- xfs_btree_init_block(mp, bp, id->bc_ops, 0, 4, id->agno);
+ xfs_btree_init_buf(mp, bp, id->bc_ops, 0, 4, id->agno);
/*
* mark the AG header regions as static metadata The BNO
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index a3732b4c4..65ba3ae8a 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -34,10 +34,10 @@ xfs_bmbt_init_block(
__u16 numrecs)
{
if (bp)
- xfs_btree_init_block(ip->i_mount, bp, &xfs_bmbt_ops, level,
+ xfs_btree_init_buf(ip->i_mount, bp, &xfs_bmbt_ops, level,
numrecs, ip->i_ino);
else
- xfs_btree_init_block_int(ip->i_mount, buf, &xfs_bmbt_ops,
+ xfs_btree_init_block(ip->i_mount, buf, &xfs_bmbt_ops,
XFS_BUF_DADDR_NULL, level, numrecs, ip->i_ino);
}
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 5675dd5ae..541f2336c 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1151,7 +1151,7 @@ xfs_btree_set_sibling(
}
void
-xfs_btree_init_block_int(
+xfs_btree_init_block(
struct xfs_mount *mp,
struct xfs_btree_block *buf,
const struct xfs_btree_ops *ops,
@@ -1193,7 +1193,7 @@ xfs_btree_init_block_int(
}
void
-xfs_btree_init_block(
+xfs_btree_init_buf(
struct xfs_mount *mp,
struct xfs_buf *bp,
const struct xfs_btree_ops *ops,
@@ -1201,7 +1201,7 @@ xfs_btree_init_block(
__u16 numrecs,
__u64 owner)
{
- xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), ops,
+ xfs_btree_init_block(mp, XFS_BUF_TO_BLOCK(bp), ops,
xfs_buf_daddr(bp), level, numrecs, owner);
}
@@ -1225,7 +1225,7 @@ xfs_btree_init_block_cur(
else
owner = cur->bc_ag.pag->pag_agno;
- xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), cur->bc_ops,
+ xfs_btree_init_block(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), cur->bc_ops,
xfs_buf_daddr(bp), level, numrecs, owner);
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 923f884fe..56901d259 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -435,10 +435,10 @@ xfs_btree_reada_bufs(
/*
* Initialise a new btree block header
*/
-void xfs_btree_init_block(struct xfs_mount *mp, struct xfs_buf *bp,
+void xfs_btree_init_buf(struct xfs_mount *mp, struct xfs_buf *bp,
const struct xfs_btree_ops *ops, __u16 level, __u16 numrecs,
__u64 owner);
-void xfs_btree_init_block_int(struct xfs_mount *mp,
+void xfs_btree_init_block(struct xfs_mount *mp,
struct xfs_btree_block *buf, const struct xfs_btree_ops *ops,
xfs_daddr_t blkno, __u16 level, __u16 numrecs, __u64 owner);
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index ba3383cad..47ef8e23a 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -410,7 +410,7 @@ xfs_btree_bload_prep_block(
ifp->if_broot_bytes = (int)new_size;
/* Initialize it and send it out. */
- xfs_btree_init_block_int(cur->bc_mp, ifp->if_broot,
+ xfs_btree_init_block(cur->bc_mp, ifp->if_broot,
cur->bc_ops, XFS_BUF_DADDR_NULL, level,
nr_this_block, cur->bc_ino.ip->i_ino);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 039/111] xfs: btree convert xfs_btree_init_block to xfs_btree_init_buf calls
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (37 preceding siblings ...)
2024-05-22 2:58 ` [PATCH 038/111] xfs: rename btree block/buffer init functions Darrick J. Wong
@ 2024-05-22 2:58 ` Darrick J. Wong
2024-05-22 2:59 ` [PATCH 040/111] xfs: remove the unnecessary daddr paramter to _init_block Darrick J. Wong
` (72 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:58 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 7771f7030007e3faa6906864d01b504b590e1ca2
Convert any place we call xfs_btree_init_block with a buffer to use the
_init_buf function.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_btree.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 541f2336c..372a521c1 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1225,8 +1225,7 @@ xfs_btree_init_block_cur(
else
owner = cur->bc_ag.pag->pag_agno;
- xfs_btree_init_block(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), cur->bc_ops,
- xfs_buf_daddr(bp), level, numrecs, owner);
+ xfs_btree_init_buf(cur->bc_mp, bp, cur->bc_ops, level, numrecs, owner);
}
/*
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 040/111] xfs: remove the unnecessary daddr paramter to _init_block
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (38 preceding siblings ...)
2024-05-22 2:58 ` [PATCH 039/111] xfs: btree convert xfs_btree_init_block to xfs_btree_init_buf calls Darrick J. Wong
@ 2024-05-22 2:59 ` Darrick J. Wong
2024-05-22 2:59 ` [PATCH 041/111] xfs: set btree block buffer ops in _init_buf Darrick J. Wong
` (71 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:59 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 11388f6581f40e7d5a69ce5f8b13264eca7c2c5c
Now that all of the callers pass XFS_BUF_DADDR_NULL as the daddr
parameter, we can elide that too.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap_btree.c | 4 ++--
libxfs/xfs_btree.c | 19 ++++++++++++++++---
libxfs/xfs_btree.h | 2 +-
libxfs/xfs_btree_staging.c | 5 ++---
4 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 65ba3ae8a..2d8411809 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -37,8 +37,8 @@ xfs_bmbt_init_block(
xfs_btree_init_buf(ip->i_mount, bp, &xfs_bmbt_ops, level,
numrecs, ip->i_ino);
else
- xfs_btree_init_block(ip->i_mount, buf, &xfs_bmbt_ops,
- XFS_BUF_DADDR_NULL, level, numrecs, ip->i_ino);
+ xfs_btree_init_block(ip->i_mount, buf, &xfs_bmbt_ops, level,
+ numrecs, ip->i_ino);
}
/*
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 372a521c1..2386084a5 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1150,8 +1150,8 @@ xfs_btree_set_sibling(
}
}
-void
-xfs_btree_init_block(
+static void
+__xfs_btree_init_block(
struct xfs_mount *mp,
struct xfs_btree_block *buf,
const struct xfs_btree_ops *ops,
@@ -1192,6 +1192,19 @@ xfs_btree_init_block(
}
}
+void
+xfs_btree_init_block(
+ struct xfs_mount *mp,
+ struct xfs_btree_block *block,
+ const struct xfs_btree_ops *ops,
+ __u16 level,
+ __u16 numrecs,
+ __u64 owner)
+{
+ __xfs_btree_init_block(mp, block, ops, XFS_BUF_DADDR_NULL, level,
+ numrecs, owner);
+}
+
void
xfs_btree_init_buf(
struct xfs_mount *mp,
@@ -1201,7 +1214,7 @@ xfs_btree_init_buf(
__u16 numrecs,
__u64 owner)
{
- xfs_btree_init_block(mp, XFS_BUF_TO_BLOCK(bp), ops,
+ __xfs_btree_init_block(mp, XFS_BUF_TO_BLOCK(bp), ops,
xfs_buf_daddr(bp), level, numrecs, owner);
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 56901d259..80be40ca8 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -440,7 +440,7 @@ void xfs_btree_init_buf(struct xfs_mount *mp, struct xfs_buf *bp,
__u64 owner);
void xfs_btree_init_block(struct xfs_mount *mp,
struct xfs_btree_block *buf, const struct xfs_btree_ops *ops,
- xfs_daddr_t blkno, __u16 level, __u16 numrecs, __u64 owner);
+ __u16 level, __u16 numrecs, __u64 owner);
/*
* Common btree core entry points.
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 47ef8e23a..39e95a771 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -410,9 +410,8 @@ xfs_btree_bload_prep_block(
ifp->if_broot_bytes = (int)new_size;
/* Initialize it and send it out. */
- xfs_btree_init_block(cur->bc_mp, ifp->if_broot,
- cur->bc_ops, XFS_BUF_DADDR_NULL, level,
- nr_this_block, cur->bc_ino.ip->i_ino);
+ xfs_btree_init_block(cur->bc_mp, ifp->if_broot, cur->bc_ops,
+ level, nr_this_block, cur->bc_ino.ip->i_ino);
*bpp = NULL;
*blockp = ifp->if_broot;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 041/111] xfs: set btree block buffer ops in _init_buf
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (39 preceding siblings ...)
2024-05-22 2:59 ` [PATCH 040/111] xfs: remove the unnecessary daddr paramter to _init_block Darrick J. Wong
@ 2024-05-22 2:59 ` Darrick J. Wong
2024-05-22 2:59 ` [PATCH 042/111] xfs: move lru refs to the btree ops structure Darrick J. Wong
` (70 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:59 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: ad065ef0d2fcd787225bd8887b6b75c6eb4da9a1
Set the btree block buffer ops in xfs_btree_init_buf since we already
have access to that information through the btree ops.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap.c | 1 -
libxfs/xfs_btree.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index a7b6c44f1..b81f3e3da 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -682,7 +682,6 @@ xfs_bmap_extents_to_btree(
/*
* Fill in the child block.
*/
- abp->b_ops = &xfs_bmbt_buf_ops;
ablock = XFS_BUF_TO_BLOCK(abp);
xfs_bmbt_init_block(ip, ablock, abp, 0, 0);
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 2386084a5..95041d626 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1216,6 +1216,7 @@ xfs_btree_init_buf(
{
__xfs_btree_init_block(mp, XFS_BUF_TO_BLOCK(bp), ops,
xfs_buf_daddr(bp), level, numrecs, owner);
+ bp->b_ops = ops->buf_ops;
}
void
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 042/111] xfs: move lru refs to the btree ops structure
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (40 preceding siblings ...)
2024-05-22 2:59 ` [PATCH 041/111] xfs: set btree block buffer ops in _init_buf Darrick J. Wong
@ 2024-05-22 2:59 ` Darrick J. Wong
2024-05-22 2:59 ` [PATCH 043/111] xfs: move the btree stats offset into struct btree_ops Darrick J. Wong
` (69 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:59 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 90cfae818dac5227e94e21d0f5250e098432723e
Move the btree buffer LRU refcount to the btree ops structure so that we
can eliminate the last bc_btnum switch in the generic btree code. We're
about to create repair-specific btree types, and we don't want that
stuff cluttering up libxfs.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_alloc_btree.c | 4 ++++
libxfs/xfs_bmap_btree.c | 2 ++
libxfs/xfs_btree.c | 24 ++----------------------
libxfs/xfs_btree.h | 3 +++
libxfs/xfs_ialloc_btree.c | 4 ++++
libxfs/xfs_refcount_btree.c | 2 ++
libxfs/xfs_rmap_btree.c | 2 ++
7 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 6c9781fcf..51c6703db 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -456,6 +456,8 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
+ .lru_refs = XFS_ALLOC_BTREE_REF,
+
.dup_cursor = xfs_allocbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
.alloc_block = xfs_allocbt_alloc_block,
@@ -481,6 +483,8 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
+ .lru_refs = XFS_ALLOC_BTREE_REF,
+
.dup_cursor = xfs_allocbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
.alloc_block = xfs_allocbt_alloc_block,
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 2d8411809..966e793b0 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -529,6 +529,8 @@ const struct xfs_btree_ops xfs_bmbt_ops = {
.rec_len = sizeof(xfs_bmbt_rec_t),
.key_len = sizeof(xfs_bmbt_key_t),
+ .lru_refs = XFS_BMAP_BTREE_REF,
+
.dup_cursor = xfs_bmbt_dup_cursor,
.update_cursor = xfs_bmbt_update_cursor,
.alloc_block = xfs_bmbt_alloc_block,
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 95041d626..150f8ac23 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1281,32 +1281,12 @@ xfs_btree_buf_to_ptr(
}
}
-STATIC void
+static inline void
xfs_btree_set_refs(
struct xfs_btree_cur *cur,
struct xfs_buf *bp)
{
- switch (cur->bc_btnum) {
- case XFS_BTNUM_BNO:
- case XFS_BTNUM_CNT:
- xfs_buf_set_ref(bp, XFS_ALLOC_BTREE_REF);
- break;
- case XFS_BTNUM_INO:
- case XFS_BTNUM_FINO:
- xfs_buf_set_ref(bp, XFS_INO_BTREE_REF);
- break;
- case XFS_BTNUM_BMAP:
- xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF);
- break;
- case XFS_BTNUM_RMAP:
- xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF);
- break;
- case XFS_BTNUM_REFC:
- xfs_buf_set_ref(bp, XFS_REFC_BTREE_REF);
- break;
- default:
- ASSERT(0);
- }
+ xfs_buf_set_ref(bp, cur->bc_ops->lru_refs);
}
int
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 80be40ca8..39df108a3 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -120,6 +120,9 @@ struct xfs_btree_ops {
size_t key_len;
size_t rec_len;
+ /* LRU refcount to set on each btree buffer created */
+ unsigned int lru_refs;
+
/* cursor operations */
struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
void (*update_cursor)(struct xfs_btree_cur *src,
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 52cc00e4f..332d497ea 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -401,6 +401,8 @@ const struct xfs_btree_ops xfs_inobt_ops = {
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
+ .lru_refs = XFS_INO_BTREE_REF,
+
.dup_cursor = xfs_inobt_dup_cursor,
.set_root = xfs_inobt_set_root,
.alloc_block = xfs_inobt_alloc_block,
@@ -423,6 +425,8 @@ const struct xfs_btree_ops xfs_finobt_ops = {
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
+ .lru_refs = XFS_INO_BTREE_REF,
+
.dup_cursor = xfs_inobt_dup_cursor,
.set_root = xfs_finobt_set_root,
.alloc_block = xfs_finobt_alloc_block,
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 2f91c7b62..1774b0477 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -320,6 +320,8 @@ const struct xfs_btree_ops xfs_refcountbt_ops = {
.rec_len = sizeof(struct xfs_refcount_rec),
.key_len = sizeof(struct xfs_refcount_key),
+ .lru_refs = XFS_REFC_BTREE_REF,
+
.dup_cursor = xfs_refcountbt_dup_cursor,
.set_root = xfs_refcountbt_set_root,
.alloc_block = xfs_refcountbt_alloc_block,
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index c3a113c88..6a7a9a176 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -476,6 +476,8 @@ const struct xfs_btree_ops xfs_rmapbt_ops = {
.rec_len = sizeof(struct xfs_rmap_rec),
.key_len = 2 * sizeof(struct xfs_rmap_key),
+ .lru_refs = XFS_RMAP_BTREE_REF,
+
.dup_cursor = xfs_rmapbt_dup_cursor,
.set_root = xfs_rmapbt_set_root,
.alloc_block = xfs_rmapbt_alloc_block,
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 043/111] xfs: move the btree stats offset into struct btree_ops
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (41 preceding siblings ...)
2024-05-22 2:59 ` [PATCH 042/111] xfs: move lru refs to the btree ops structure Darrick J. Wong
@ 2024-05-22 2:59 ` Darrick J. Wong
2024-05-22 3:00 ` [PATCH 044/111] xfs: factor out a xfs_btree_owner helper Darrick J. Wong
` (68 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 2:59 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 07b7f2e3172b97da2a7ac273ecbaf173cc09a9f4
The statistics offset is completely static, move it into the btree_ops
structure instead of the cursor.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc_btree.c | 17 +++++++----------
libxfs/xfs_bmap_btree.c | 2 +-
libxfs/xfs_btree.h | 10 +++++++---
libxfs/xfs_ialloc_btree.c | 20 +++++++++-----------
libxfs/xfs_refcount_btree.c | 3 +--
libxfs/xfs_rmap_btree.c | 3 +--
6 files changed, 26 insertions(+), 29 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 51c6703db..fab420a6c 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -457,6 +457,7 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
.key_len = sizeof(xfs_alloc_key_t),
.lru_refs = XFS_ALLOC_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_abtb_2),
.dup_cursor = xfs_allocbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
@@ -484,6 +485,7 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
.key_len = sizeof(xfs_alloc_key_t),
.lru_refs = XFS_ALLOC_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_abtc_2),
.dup_cursor = xfs_allocbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
@@ -512,22 +514,17 @@ xfs_allocbt_init_common(
struct xfs_perag *pag,
xfs_btnum_t btnum)
{
+ const struct xfs_btree_ops *ops = &xfs_bnobt_ops;
struct xfs_btree_cur *cur;
ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
- if (btnum == XFS_BTNUM_CNT) {
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_cntbt_ops,
- mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
- } else {
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_bnobt_ops,
- mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
- }
+ if (btnum == XFS_BTNUM_CNT)
+ ops = &xfs_cntbt_ops;
+ cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops, mp->m_alloc_maxlevels,
+ xfs_allocbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
-
return cur;
}
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 966e793b0..f149dddd9 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -530,6 +530,7 @@ const struct xfs_btree_ops xfs_bmbt_ops = {
.key_len = sizeof(xfs_bmbt_key_t),
.lru_refs = XFS_BMAP_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2),
.dup_cursor = xfs_bmbt_dup_cursor,
.update_cursor = xfs_bmbt_update_cursor,
@@ -563,7 +564,6 @@ xfs_bmbt_init_common(
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP, &xfs_bmbt_ops,
mp->m_bm_maxlevels[whichfork], xfs_bmbt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
cur->bc_ino.ip = ip;
cur->bc_ino.allocated = 0;
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 39df108a3..2a1f30a84 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -87,9 +87,11 @@ uint32_t xfs_btree_magic(struct xfs_mount *mp, const struct xfs_btree_ops *ops);
* Generic stats interface
*/
#define XFS_BTREE_STATS_INC(cur, stat) \
- XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat)
+ XFS_STATS_INC_OFF((cur)->bc_mp, \
+ (cur)->bc_ops->statoff + __XBTS_ ## stat)
#define XFS_BTREE_STATS_ADD(cur, stat, val) \
- XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val)
+ XFS_STATS_ADD_OFF((cur)->bc_mp, \
+ (cur)->bc_ops->statoff + __XBTS_ ## stat, val)
enum xbtree_key_contig {
XBTREE_KEY_GAP = 0,
@@ -123,6 +125,9 @@ struct xfs_btree_ops {
/* LRU refcount to set on each btree buffer created */
unsigned int lru_refs;
+ /* offset of btree stats array */
+ unsigned int statoff;
+
/* cursor operations */
struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
void (*update_cursor)(struct xfs_btree_cur *src,
@@ -280,7 +285,6 @@ struct xfs_btree_cur
union xfs_btree_irec bc_rec; /* current insert/search record value */
uint8_t bc_nlevels; /* number of levels in the tree */
uint8_t bc_maxlevels; /* maximum levels for this btree type */
- int bc_statoff; /* offset of btree stats array */
/*
* Short btree pointers need an agno to be able to turn the pointers
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 332d497ea..e23c5413f 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -402,6 +402,7 @@ const struct xfs_btree_ops xfs_inobt_ops = {
.key_len = sizeof(xfs_inobt_key_t),
.lru_refs = XFS_INO_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_ibt_2),
.dup_cursor = xfs_inobt_dup_cursor,
.set_root = xfs_inobt_set_root,
@@ -426,6 +427,7 @@ const struct xfs_btree_ops xfs_finobt_ops = {
.key_len = sizeof(xfs_inobt_key_t),
.lru_refs = XFS_INO_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_fibt_2),
.dup_cursor = xfs_inobt_dup_cursor,
.set_root = xfs_finobt_set_root,
@@ -455,20 +457,16 @@ xfs_inobt_init_common(
xfs_btnum_t btnum) /* ialloc or free ino btree */
{
struct xfs_mount *mp = pag->pag_mount;
+ const struct xfs_btree_ops *ops = &xfs_inobt_ops;
struct xfs_btree_cur *cur;
- if (btnum == XFS_BTNUM_INO) {
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_inobt_ops,
- M_IGEO(mp)->inobt_maxlevels,
- xfs_inobt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2);
- } else {
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, &xfs_finobt_ops,
- M_IGEO(mp)->inobt_maxlevels,
- xfs_inobt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
- }
+ ASSERT(btnum == XFS_BTNUM_INO || btnum == XFS_BTNUM_FINO);
+ if (btnum == XFS_BTNUM_FINO)
+ ops = &xfs_finobt_ops;
+
+ cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops,
+ M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
return cur;
}
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 1774b0477..4ee259278 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -321,6 +321,7 @@ const struct xfs_btree_ops xfs_refcountbt_ops = {
.key_len = sizeof(struct xfs_refcount_key),
.lru_refs = XFS_REFC_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2),
.dup_cursor = xfs_refcountbt_dup_cursor,
.set_root = xfs_refcountbt_set_root,
@@ -356,8 +357,6 @@ xfs_refcountbt_init_common(
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC,
&xfs_refcountbt_ops, mp->m_refc_maxlevels,
xfs_refcountbt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
-
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.refc.nr_ops = 0;
cur->bc_ag.refc.shape_changes = 0;
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 6a7a9a176..6f9bc43c2 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -477,6 +477,7 @@ const struct xfs_btree_ops xfs_rmapbt_ops = {
.key_len = 2 * sizeof(struct xfs_rmap_key),
.lru_refs = XFS_RMAP_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_rmap_2),
.dup_cursor = xfs_rmapbt_dup_cursor,
.set_root = xfs_rmapbt_set_root,
@@ -507,8 +508,6 @@ xfs_rmapbt_init_common(
/* Overlapping btree; 2 keys per pointer. */
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
-
cur->bc_ag.pag = xfs_perag_hold(pag);
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 044/111] xfs: factor out a xfs_btree_owner helper
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (42 preceding siblings ...)
2024-05-22 2:59 ` [PATCH 043/111] xfs: move the btree stats offset into struct btree_ops Darrick J. Wong
@ 2024-05-22 3:00 ` Darrick J. Wong
2024-05-22 3:00 ` [PATCH 045/111] xfs: factor out a btree block owner check Darrick J. Wong
` (67 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:00 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 2054cf051698d30cc9479678c2b807a364248f38
Split out a helper to calculate the owner for a given btree instead of
duplicating the logic in two places. While we're at it, make the
bc_ag/bc_ino switch logic depend on the correct geometry flag.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: break this up into two patches for the owner check]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 150f8ac23..dab571222 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1219,6 +1219,15 @@ xfs_btree_init_buf(
bp->b_ops = ops->buf_ops;
}
+static inline __u64
+xfs_btree_owner(
+ struct xfs_btree_cur *cur)
+{
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
+ return cur->bc_ino.ip->i_ino;
+ return cur->bc_ag.pag->pag_agno;
+}
+
void
xfs_btree_init_block_cur(
struct xfs_btree_cur *cur,
@@ -1226,20 +1235,8 @@ xfs_btree_init_block_cur(
int level,
int numrecs)
{
- __u64 owner;
-
- /*
- * we can pull the owner from the cursor right now as the different
- * owners align directly with the pointer size of the btree. This may
- * change in future, but is safe for current users of the generic btree
- * code.
- */
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
- owner = cur->bc_ino.ip->i_ino;
- else
- owner = cur->bc_ag.pag->pag_agno;
-
- xfs_btree_init_buf(cur->bc_mp, bp, cur->bc_ops, level, numrecs, owner);
+ xfs_btree_init_buf(cur->bc_mp, bp, cur->bc_ops, level, numrecs,
+ xfs_btree_owner(cur));
}
/*
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 045/111] xfs: factor out a btree block owner check
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (43 preceding siblings ...)
2024-05-22 3:00 ` [PATCH 044/111] xfs: factor out a xfs_btree_owner helper Darrick J. Wong
@ 2024-05-22 3:00 ` Darrick J. Wong
2024-05-22 3:00 ` [PATCH 046/111] xfs: store the btree pointer length in struct xfs_btree_ops Darrick J. Wong
` (66 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:00 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 186f20c003199824eb3eb3b78e4eb7c2535a8ffc
Hoist the btree block owner check into a separate helper so that we
don't have an ugly multiline if statement.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_btree.c | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index dab571222..5f132e336 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1774,6 +1774,33 @@ xfs_btree_decrement(
return error;
}
+/*
+ * Check the btree block owner now that we have the context to know who the
+ * real owner is.
+ */
+static inline xfs_failaddr_t
+xfs_btree_check_block_owner(
+ struct xfs_btree_cur *cur,
+ struct xfs_btree_block *block)
+{
+ __u64 owner;
+
+ if (!xfs_has_crc(cur->bc_mp) ||
+ (cur->bc_flags & XFS_BTREE_BMBT_INVALID_OWNER))
+ return NULL;
+
+ owner = xfs_btree_owner(cur);
+ if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (be64_to_cpu(block->bb_u.l.bb_owner) != owner)
+ return __this_address;
+ } else {
+ if (be32_to_cpu(block->bb_u.s.bb_owner) != owner)
+ return __this_address;
+ }
+
+ return NULL;
+}
+
int
xfs_btree_lookup_get_block(
struct xfs_btree_cur *cur, /* btree cursor */
@@ -1812,11 +1839,7 @@ xfs_btree_lookup_get_block(
return error;
/* Check the inode owner since the verifiers don't. */
- if (xfs_has_crc(cur->bc_mp) &&
- !(cur->bc_flags & XFS_BTREE_BMBT_INVALID_OWNER) &&
- (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) &&
- be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
- cur->bc_ino.ip->i_ino)
+ if (xfs_btree_check_block_owner(cur, *blkp) != NULL)
goto out_bad;
/* Did we get the level we were looking for? */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 046/111] xfs: store the btree pointer length in struct xfs_btree_ops
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (44 preceding siblings ...)
2024-05-22 3:00 ` [PATCH 045/111] xfs: factor out a btree block owner check Darrick J. Wong
@ 2024-05-22 3:00 ` Darrick J. Wong
2024-05-22 3:01 ` [PATCH 047/111] xfs: split out a btree type from the btree ops geometry flags Darrick J. Wong
` (65 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:00 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 1a9d26291c68fbb8f8d24f9f694b32223a072745
Make the pointer length an explicit field in the btree operations
structure so that the next patch (which introduces an explicit btree
type enum) doesn't have to play a bunch of awkward games with inferring
the pointer length from the enumeration.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_alloc_btree.c | 2 ++
libxfs/xfs_bmap_btree.c | 3 ++
libxfs/xfs_btree.c | 57 ++++++++++++++++++-------------------------
libxfs/xfs_btree.h | 26 ++++++++++++--------
libxfs/xfs_ialloc_btree.c | 2 ++
libxfs/xfs_refcount_btree.c | 1 +
libxfs/xfs_rmap_btree.c | 1 +
repair/bulkload.c | 2 +-
8 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index fab420a6c..e1637580c 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -455,6 +455,7 @@ xfs_allocbt_keys_contiguous(
const struct xfs_btree_ops xfs_bnobt_ops = {
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
+ .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
.lru_refs = XFS_ALLOC_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_abtb_2),
@@ -483,6 +484,7 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
+ .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
.lru_refs = XFS_ALLOC_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_abtc_2),
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index f149dddd9..d2399ea42 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -524,10 +524,11 @@ xfs_bmbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_bmbt_ops = {
- .geom_flags = XFS_BTGEO_LONG_PTRS | XFS_BTGEO_ROOT_IN_INODE,
+ .geom_flags = XFS_BTGEO_ROOT_IN_INODE,
.rec_len = sizeof(xfs_bmbt_rec_t),
.key_len = sizeof(xfs_bmbt_key_t),
+ .ptr_len = XFS_BTREE_LONG_PTR_LEN,
.lru_refs = XFS_BMAP_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2),
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 5f132e336..2bce8ebbd 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -249,7 +249,7 @@ xfs_btree_check_block(
int level, /* level of the btree block */
struct xfs_buf *bp) /* buffer containing block, if any */
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return xfs_btree_check_lblock(cur, block, level, bp);
else
return xfs_btree_check_sblock(cur, block, level, bp);
@@ -290,7 +290,7 @@ xfs_btree_check_ptr(
int index,
int level)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]),
level))
return 0;
@@ -446,7 +446,7 @@ xfs_btree_del_cursor(
xfs_is_shutdown(cur->bc_mp) || error != 0);
if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
kfree(cur->bc_ops);
- if (!(cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) && cur->bc_ag.pag)
+ if (!(cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) && cur->bc_ag.pag)
xfs_perag_put(cur->bc_ag.pag);
kmem_cache_free(cur->bc_cache, cur);
}
@@ -585,7 +585,7 @@ xfs_btree_dup_cursor(
*/
static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (xfs_has_crc(cur->bc_mp))
return XFS_BTREE_LBLOCK_CRC_LEN;
return XFS_BTREE_LBLOCK_LEN;
@@ -595,15 +595,6 @@ static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
return XFS_BTREE_SBLOCK_LEN;
}
-/*
- * Return size of btree block pointers for this btree instance.
- */
-static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur)
-{
- return (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) ?
- sizeof(__be64) : sizeof(__be32);
-}
-
/*
* Calculate offset of the n-th record in a btree block.
*/
@@ -651,7 +642,7 @@ xfs_btree_ptr_offset(
{
return xfs_btree_block_len(cur) +
cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len +
- (n - 1) * xfs_btree_ptr_len(cur);
+ (n - 1) * cur->bc_ops->ptr_len;
}
/*
@@ -999,7 +990,7 @@ xfs_btree_readahead(
cur->bc_levels[lev].ra |= lr;
block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return xfs_btree_readahead_lblock(cur, lr, block);
return xfs_btree_readahead_sblock(cur, lr, block);
}
@@ -1018,7 +1009,7 @@ xfs_btree_ptr_to_daddr(
if (error)
return error;
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
fsbno = be64_to_cpu(ptr->l);
*daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno);
} else {
@@ -1068,7 +1059,7 @@ xfs_btree_setbuf(
cur->bc_levels[lev].ra = 0;
b = XFS_BUF_TO_BLOCK(bp);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK))
cur->bc_levels[lev].ra |= XFS_BTCUR_LEFTRA;
if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK))
@@ -1086,7 +1077,7 @@ xfs_btree_ptr_is_null(
struct xfs_btree_cur *cur,
const union xfs_btree_ptr *ptr)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return ptr->l == cpu_to_be64(NULLFSBLOCK);
else
return ptr->s == cpu_to_be32(NULLAGBLOCK);
@@ -1097,7 +1088,7 @@ xfs_btree_set_ptr_null(
struct xfs_btree_cur *cur,
union xfs_btree_ptr *ptr)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
ptr->l = cpu_to_be64(NULLFSBLOCK);
else
ptr->s = cpu_to_be32(NULLAGBLOCK);
@@ -1115,7 +1106,7 @@ xfs_btree_get_sibling(
{
ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (lr == XFS_BB_RIGHTSIB)
ptr->l = block->bb_u.l.bb_rightsib;
else
@@ -1137,7 +1128,7 @@ xfs_btree_set_sibling(
{
ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (lr == XFS_BB_RIGHTSIB)
block->bb_u.l.bb_rightsib = ptr->l;
else
@@ -1167,7 +1158,7 @@ __xfs_btree_init_block(
buf->bb_level = cpu_to_be16(level);
buf->bb_numrecs = cpu_to_be16(numrecs);
- if (ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK);
buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK);
if (crc) {
@@ -1269,7 +1260,7 @@ xfs_btree_buf_to_ptr(
struct xfs_buf *bp,
union xfs_btree_ptr *ptr)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp,
xfs_buf_daddr(bp)));
else {
@@ -1384,7 +1375,7 @@ xfs_btree_copy_ptrs(
int numptrs)
{
ASSERT(numptrs >= 0);
- memcpy(dst_ptr, src_ptr, numptrs * xfs_btree_ptr_len(cur));
+ memcpy(dst_ptr, src_ptr, numptrs * cur->bc_ops->ptr_len);
}
/*
@@ -1440,8 +1431,8 @@ xfs_btree_shift_ptrs(
ASSERT(numptrs >= 0);
ASSERT(dir == 1 || dir == -1);
- dst_ptr = (char *)ptr + (dir * xfs_btree_ptr_len(cur));
- memmove(dst_ptr, ptr, numptrs * xfs_btree_ptr_len(cur));
+ dst_ptr = (char *)ptr + (dir * cur->bc_ops->ptr_len);
+ memmove(dst_ptr, ptr, numptrs * cur->bc_ops->ptr_len);
}
/*
@@ -1567,7 +1558,7 @@ xfs_btree_log_block(
nbits = XFS_BB_NUM_BITS;
}
xfs_btree_offsets(fields,
- (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) ?
+ (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) ?
loffsets : soffsets,
nbits, &first, &last);
xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
@@ -1790,7 +1781,7 @@ xfs_btree_check_block_owner(
return NULL;
owner = xfs_btree_owner(cur);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (be64_to_cpu(block->bb_u.l.bb_owner) != owner)
return __this_address;
} else {
@@ -3049,7 +3040,7 @@ xfs_btree_new_iroot(
memcpy(cblock, block, xfs_btree_block_len(cur));
if (xfs_has_crc(cur->bc_mp)) {
__be64 bno = cpu_to_be64(xfs_buf_daddr(cbp));
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
cblock->bb_u.l.bb_blkno = bno;
else
cblock->bb_u.s.bb_blkno = bno;
@@ -4408,7 +4399,7 @@ xfs_btree_visit_block(
* return the same block without checking if the right sibling points
* back to us and creates a cyclic reference in the btree.
*/
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (be64_to_cpu(rptr.l) == XFS_DADDR_TO_FSB(cur->bc_mp,
xfs_buf_daddr(bp))) {
xfs_btree_mark_sick(cur);
@@ -4516,7 +4507,7 @@ xfs_btree_block_change_owner(
/* modify the owner */
block = xfs_btree_get_block(cur, level, &bp);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (block->bb_u.l.bb_owner == cpu_to_be64(bbcoi->new_owner))
return 0;
block->bb_u.l.bb_owner = cpu_to_be64(bbcoi->new_owner);
@@ -5065,7 +5056,7 @@ xfs_btree_diff_two_ptrs(
const union xfs_btree_ptr *a,
const union xfs_btree_ptr *b)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return (int64_t)be64_to_cpu(a->l) - be64_to_cpu(b->l);
return (int64_t)be32_to_cpu(a->s) - be32_to_cpu(b->s);
}
@@ -5213,7 +5204,7 @@ xfs_btree_has_more_records(
return true;
/* There are more record blocks. */
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK);
else
return block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK);
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 2a1f30a84..559066e3a 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -114,13 +114,17 @@ static inline enum xbtree_key_contig xbtree_key_contig(uint64_t x, uint64_t y)
return XBTREE_KEY_OVERLAP;
}
+#define XFS_BTREE_LONG_PTR_LEN (sizeof(__be64))
+#define XFS_BTREE_SHORT_PTR_LEN (sizeof(__be32))
+
struct xfs_btree_ops {
/* XFS_BTGEO_* flags that determine the geometry of the btree */
unsigned int geom_flags;
- /* size of the key and record structures */
- size_t key_len;
- size_t rec_len;
+ /* size of the key, pointer, and record structures */
+ size_t key_len;
+ size_t ptr_len;
+ size_t rec_len;
/* LRU refcount to set on each btree buffer created */
unsigned int lru_refs;
@@ -212,10 +216,9 @@ struct xfs_btree_ops {
};
/* btree geometry flags */
-#define XFS_BTGEO_LONG_PTRS (1U << 0) /* pointers are 64bits long */
-#define XFS_BTGEO_ROOT_IN_INODE (1U << 1) /* root may be variable size */
-#define XFS_BTGEO_LASTREC_UPDATE (1U << 2) /* track last rec externally */
-#define XFS_BTGEO_OVERLAPPING (1U << 3) /* overlapping intervals */
+#define XFS_BTGEO_ROOT_IN_INODE (1U << 0) /* root may be variable size */
+#define XFS_BTGEO_LASTREC_UPDATE (1U << 1) /* track last rec externally */
+#define XFS_BTGEO_OVERLAPPING (1U << 2) /* overlapping intervals */
/*
* Reasons for the update_lastrec method to be called.
@@ -289,8 +292,8 @@ struct xfs_btree_cur
/*
* Short btree pointers need an agno to be able to turn the pointers
* into physical addresses for IO, so the btree cursor switches between
- * bc_ino and bc_ag based on whether XFS_BTGEO_LONG_PTRS is set for the
- * cursor.
+ * bc_ino and bc_ag based on whether XFS_BTGEO_ROOT_IN_INODE is set for
+ * the cursor.
*/
union {
struct xfs_btree_cur_ag bc_ag;
@@ -689,7 +692,7 @@ xfs_btree_islastblock(
block = xfs_btree_get_block(cur, level, &bp);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK);
return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK);
}
@@ -725,6 +728,9 @@ xfs_btree_alloc_cursor(
{
struct xfs_btree_cur *cur;
+ ASSERT(ops->ptr_len == XFS_BTREE_LONG_PTR_LEN ||
+ ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN);
+
/* BMBT allocations can come through from non-transactional context. */
cur = kmem_cache_zalloc(cache,
GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index e23c5413f..a9b2a48a3 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -400,6 +400,7 @@ xfs_inobt_keys_contiguous(
const struct xfs_btree_ops xfs_inobt_ops = {
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
+ .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
.lru_refs = XFS_INO_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_ibt_2),
@@ -425,6 +426,7 @@ const struct xfs_btree_ops xfs_inobt_ops = {
const struct xfs_btree_ops xfs_finobt_ops = {
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
+ .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
.lru_refs = XFS_INO_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_fibt_2),
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 4ee259278..4918c8bae 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -319,6 +319,7 @@ xfs_refcountbt_keys_contiguous(
const struct xfs_btree_ops xfs_refcountbt_ops = {
.rec_len = sizeof(struct xfs_refcount_rec),
.key_len = sizeof(struct xfs_refcount_key),
+ .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
.lru_refs = XFS_REFC_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2),
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 6f9bc43c2..b1d25d99d 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -475,6 +475,7 @@ const struct xfs_btree_ops xfs_rmapbt_ops = {
.rec_len = sizeof(struct xfs_rmap_rec),
.key_len = 2 * sizeof(struct xfs_rmap_key),
+ .ptr_len = XFS_BTREE_SHORT_PTR_LEN,
.lru_refs = XFS_RMAP_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_rmap_2),
diff --git a/repair/bulkload.c b/repair/bulkload.c
index 31d136bb8..d36e32d99 100644
--- a/repair/bulkload.c
+++ b/repair/bulkload.c
@@ -314,7 +314,7 @@ bulkload_claim_block(
if (resv->used == resv->len)
list_move_tail(&resv->list, &bkl->resv_list);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_LONG_PTRS)
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
ptr->l = cpu_to_be64(XFS_AGB_TO_FSB(mp, resv->pag->pag_agno,
agbno));
else
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 047/111] xfs: split out a btree type from the btree ops geometry flags
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (45 preceding siblings ...)
2024-05-22 3:00 ` [PATCH 046/111] xfs: store the btree pointer length in struct xfs_btree_ops Darrick J. Wong
@ 2024-05-22 3:01 ` Darrick J. Wong
2024-05-22 3:01 ` [PATCH 048/111] xfs: split the per-btree union in struct xfs_btree_cur Darrick J. Wong
` (64 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:01 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 4f0cd5a555072e21fb589975607b70798e073f8f
Two of the btree cursor flags are always used together and encode
the fundamental btree type. There currently are two such types:
1) an on-disk AG-rooted btree with 32-bit pointers
2) an on-disk inode-rooted btree with 64-bit pointers
and we're about to add:
3) an in-memory btree with 64-bit pointers
Introduce a new enum and a new type field in struct xfs_btree_geom
to encode this type directly instead of using flags and change most
code to switch on this enum.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: make the pointer lengths explicit]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc_btree.c | 3 ++
libxfs/xfs_bmap_btree.c | 2 +
libxfs/xfs_btree.c | 66 +++++++++++++++++++++++--------------------
libxfs/xfs_btree.h | 15 +++++++---
libxfs/xfs_btree_staging.c | 12 ++++----
libxfs/xfs_btree_staging.h | 3 +-
libxfs/xfs_ialloc_btree.c | 4 +++
libxfs/xfs_refcount_btree.c | 2 +
libxfs/xfs_rmap_btree.c | 1 +
9 files changed, 65 insertions(+), 43 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index e1637580c..b18ac7045 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -453,6 +453,8 @@ xfs_allocbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_bnobt_ops = {
+ .type = XFS_BTREE_TYPE_AG,
+
.rec_len = sizeof(xfs_alloc_rec_t),
.key_len = sizeof(xfs_alloc_key_t),
.ptr_len = XFS_BTREE_SHORT_PTR_LEN,
@@ -480,6 +482,7 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
};
const struct xfs_btree_ops xfs_cntbt_ops = {
+ .type = XFS_BTREE_TYPE_AG,
.geom_flags = XFS_BTGEO_LASTREC_UPDATE,
.rec_len = sizeof(xfs_alloc_rec_t),
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index d2399ea42..54020dea2 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -524,7 +524,7 @@ xfs_bmbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_bmbt_ops = {
- .geom_flags = XFS_BTGEO_ROOT_IN_INODE,
+ .type = XFS_BTREE_TYPE_INODE,
.rec_len = sizeof(xfs_bmbt_rec_t),
.key_len = sizeof(xfs_bmbt_key_t),
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 2bce8ebbd..f8c348e49 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -444,10 +444,19 @@ xfs_btree_del_cursor(
*/
ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_ino.allocated == 0 ||
xfs_is_shutdown(cur->bc_mp) || error != 0);
+
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_AG:
+ if (cur->bc_ag.pag)
+ xfs_perag_put(cur->bc_ag.pag);
+ break;
+ case XFS_BTREE_TYPE_INODE:
+ /* nothing to do */
+ break;
+ }
+
if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
kfree(cur->bc_ops);
- if (!(cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) && cur->bc_ag.pag)
- xfs_perag_put(cur->bc_ag.pag);
kmem_cache_free(cur->bc_cache, cur);
}
@@ -705,7 +714,7 @@ struct xfs_ifork *
xfs_btree_ifork_ptr(
struct xfs_btree_cur *cur)
{
- ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
if (cur->bc_flags & XFS_BTREE_STAGING)
return cur->bc_ino.ifake->if_fork;
@@ -737,8 +746,8 @@ xfs_btree_get_block(
int level, /* level in btree */
struct xfs_buf **bpp) /* buffer containing the block */
{
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
- (level == cur->bc_nlevels - 1)) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
+ level == cur->bc_nlevels - 1) {
*bpp = NULL;
return xfs_btree_get_iroot(cur);
}
@@ -980,8 +989,8 @@ xfs_btree_readahead(
* No readahead needed if we are at the root level and the
* btree root is stored in the inode.
*/
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
- (lev == cur->bc_nlevels - 1))
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
+ lev == cur->bc_nlevels - 1)
return 0;
if ((cur->bc_levels[lev].ra | lr) == cur->bc_levels[lev].ra)
@@ -1169,14 +1178,12 @@ __xfs_btree_init_block(
buf->bb_u.l.bb_lsn = 0;
}
} else {
- /* owner is a 32 bit value on short blocks */
- __u32 __owner = (__u32)owner;
-
buf->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
buf->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
if (crc) {
buf->bb_u.s.bb_blkno = cpu_to_be64(blkno);
- buf->bb_u.s.bb_owner = cpu_to_be32(__owner);
+ /* owner is a 32 bit value on short blocks */
+ buf->bb_u.s.bb_owner = cpu_to_be32((__u32)owner);
uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid);
buf->bb_u.s.bb_lsn = 0;
}
@@ -1214,7 +1221,7 @@ static inline __u64
xfs_btree_owner(
struct xfs_btree_cur *cur)
{
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
return cur->bc_ino.ip->i_ino;
return cur->bc_ag.pag->pag_agno;
}
@@ -1635,7 +1642,7 @@ xfs_btree_increment(
* confused or have the tree root in an inode.
*/
if (lev == cur->bc_nlevels) {
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
goto out0;
ASSERT(0);
xfs_btree_mark_sick(cur);
@@ -1729,7 +1736,7 @@ xfs_btree_decrement(
* or the root of the tree is in an inode.
*/
if (lev == cur->bc_nlevels) {
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
goto out0;
ASSERT(0);
xfs_btree_mark_sick(cur);
@@ -1804,8 +1811,8 @@ xfs_btree_lookup_get_block(
int error = 0;
/* special case the root block if in an inode */
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
- (level == cur->bc_nlevels - 1)) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
+ level == cur->bc_nlevels - 1) {
*blkp = xfs_btree_get_iroot(cur);
return 0;
}
@@ -2340,7 +2347,7 @@ xfs_btree_lshift(
int error; /* error return value */
int i;
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
+ if ((cur->bc_ops->type == XFS_BTREE_TYPE_INODE) &&
level == cur->bc_nlevels - 1)
goto out0;
@@ -2536,8 +2543,8 @@ xfs_btree_rshift(
int error; /* error return value */
int i; /* loop counter */
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
- (level == cur->bc_nlevels - 1))
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
+ level == cur->bc_nlevels - 1)
goto out0;
/* Set up variables for this block as "left". */
@@ -2987,7 +2994,6 @@ xfs_btree_split(
#define xfs_btree_split __xfs_btree_split
#endif /* __KERNEL__ */
-
/*
* Copy the old inode root contents into a real block and make the
* broot point to it.
@@ -3012,7 +3018,7 @@ xfs_btree_new_iroot(
XFS_BTREE_STATS_INC(cur, newroot);
- ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
level = cur->bc_nlevels - 1;
@@ -3237,7 +3243,7 @@ xfs_btree_make_block_unfull(
{
int error = 0;
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
level == cur->bc_nlevels - 1) {
struct xfs_inode *ip = cur->bc_ino.ip;
@@ -3323,8 +3329,8 @@ xfs_btree_insrec(
* If we have an external root pointer, and we've made it to the
* root level, allocate a new root block and we're done.
*/
- if (!(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
- (level >= cur->bc_nlevels)) {
+ if (cur->bc_ops->type != XFS_BTREE_TYPE_INODE &&
+ level >= cur->bc_nlevels) {
error = xfs_btree_new_root(cur, stat);
xfs_btree_set_ptr_null(cur, ptrp);
@@ -3611,7 +3617,7 @@ xfs_btree_kill_iroot(
#endif
int i;
- ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
ASSERT(cur->bc_nlevels > 1);
/*
@@ -3848,7 +3854,7 @@ xfs_btree_delrec(
* nothing left to do.
*/
if (level == cur->bc_nlevels - 1) {
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
xfs_iroot_realloc(cur->bc_ino.ip, -1,
cur->bc_ino.whichfork);
@@ -3916,7 +3922,7 @@ xfs_btree_delrec(
xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
xfs_btree_get_sibling(cur, block, &lptr, XFS_BB_LEFTSIB);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
/*
* One child of root, need to get a chance to copy its contents
* into the root and delete it. Can't go up to next level,
@@ -4233,8 +4239,8 @@ xfs_btree_delrec(
* If we joined with the right neighbor and there's a level above
* us, increment the cursor at that level.
*/
- else if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) ||
- (level + 1 < cur->bc_nlevels)) {
+ else if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE ||
+ level + 1 < cur->bc_nlevels) {
error = xfs_btree_increment(cur, level + 1, &i);
if (error)
goto error0;
@@ -4525,7 +4531,7 @@ xfs_btree_block_change_owner(
* though, so everything is consistent in memory.
*/
if (!bp) {
- ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
ASSERT(level == cur->bc_nlevels - 1);
return 0;
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 559066e3a..5f2b5ef85 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -117,7 +117,15 @@ static inline enum xbtree_key_contig xbtree_key_contig(uint64_t x, uint64_t y)
#define XFS_BTREE_LONG_PTR_LEN (sizeof(__be64))
#define XFS_BTREE_SHORT_PTR_LEN (sizeof(__be32))
+enum xfs_btree_type {
+ XFS_BTREE_TYPE_AG,
+ XFS_BTREE_TYPE_INODE,
+};
+
struct xfs_btree_ops {
+ /* Type of btree - AG-rooted or inode-rooted */
+ enum xfs_btree_type type;
+
/* XFS_BTGEO_* flags that determine the geometry of the btree */
unsigned int geom_flags;
@@ -216,9 +224,8 @@ struct xfs_btree_ops {
};
/* btree geometry flags */
-#define XFS_BTGEO_ROOT_IN_INODE (1U << 0) /* root may be variable size */
-#define XFS_BTGEO_LASTREC_UPDATE (1U << 1) /* track last rec externally */
-#define XFS_BTGEO_OVERLAPPING (1U << 2) /* overlapping intervals */
+#define XFS_BTGEO_LASTREC_UPDATE (1U << 0) /* track last rec externally */
+#define XFS_BTGEO_OVERLAPPING (1U << 1) /* overlapping intervals */
/*
* Reasons for the update_lastrec method to be called.
@@ -292,7 +299,7 @@ struct xfs_btree_cur
/*
* Short btree pointers need an agno to be able to turn the pointers
* into physical addresses for IO, so the btree cursor switches between
- * bc_ino and bc_ag based on whether XFS_BTGEO_ROOT_IN_INODE is set for
+ * bc_ino and bc_ag based on bc_ops->type.
* the cursor.
*/
union {
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 39e95a771..e1fd57dee 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -136,7 +136,7 @@ xfs_btree_stage_afakeroot(
struct xfs_btree_ops *nops;
ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
- ASSERT(!(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE));
+ ASSERT(cur->bc_ops->type != XFS_BTREE_TYPE_INODE);
ASSERT(cur->bc_tp == NULL);
nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
@@ -217,7 +217,7 @@ xfs_btree_stage_ifakeroot(
struct xfs_btree_ops *nops;
ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
- ASSERT(cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE);
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
ASSERT(cur->bc_tp == NULL);
nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
@@ -397,7 +397,7 @@ xfs_btree_bload_prep_block(
struct xfs_btree_block *new_block;
int ret;
- if ((cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) &&
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
level == cur->bc_nlevels - 1) {
struct xfs_ifork *ifp = xfs_btree_ifork_ptr(cur);
size_t new_size;
@@ -702,7 +702,7 @@ xfs_btree_bload_compute_geometry(
xfs_btree_bload_level_geometry(cur, bbl, level, nr_this_level,
&avg_per_block, &level_blocks, &dontcare64);
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
/*
* If all the items we want to store at this level
* would fit in the inode root block, then we have our
@@ -761,7 +761,7 @@ xfs_btree_bload_compute_geometry(
return -EOVERFLOW;
bbl->btree_height = cur->bc_nlevels;
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE)
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
bbl->nr_blocks = nr_blocks - 1;
else
bbl->nr_blocks = nr_blocks;
@@ -888,7 +888,7 @@ xfs_btree_bload(
}
/* Initialize the new root. */
- if (cur->bc_ops->geom_flags & XFS_BTGEO_ROOT_IN_INODE) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
cur->bc_ino.ifake->if_levels = cur->bc_nlevels;
cur->bc_ino.ifake->if_blocks = total_blocks - 1;
diff --git a/libxfs/xfs_btree_staging.h b/libxfs/xfs_btree_staging.h
index 9624ae06c..8e29cd3cc 100644
--- a/libxfs/xfs_btree_staging.h
+++ b/libxfs/xfs_btree_staging.h
@@ -76,8 +76,7 @@ struct xfs_btree_bload {
/*
* This function should return the size of the in-core btree root
- * block. It is only necessary for XFS_BTGEO_ROOT_IN_INODE btree
- * types.
+ * block. It is only necessary for XFS_BTREE_TYPE_INODE btrees.
*/
xfs_btree_bload_iroot_size_fn iroot_size;
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index a9b2a48a3..79ab04684 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -398,6 +398,8 @@ xfs_inobt_keys_contiguous(
}
const struct xfs_btree_ops xfs_inobt_ops = {
+ .type = XFS_BTREE_TYPE_AG,
+
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
.ptr_len = XFS_BTREE_SHORT_PTR_LEN,
@@ -424,6 +426,8 @@ const struct xfs_btree_ops xfs_inobt_ops = {
};
const struct xfs_btree_ops xfs_finobt_ops = {
+ .type = XFS_BTREE_TYPE_AG,
+
.rec_len = sizeof(xfs_inobt_rec_t),
.key_len = sizeof(xfs_inobt_key_t),
.ptr_len = XFS_BTREE_SHORT_PTR_LEN,
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 4918c8bae..3d61eeaca 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -317,6 +317,8 @@ xfs_refcountbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_refcountbt_ops = {
+ .type = XFS_BTREE_TYPE_AG,
+
.rec_len = sizeof(struct xfs_refcount_rec),
.key_len = sizeof(struct xfs_refcount_key),
.ptr_len = XFS_BTREE_SHORT_PTR_LEN,
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index b1d25d99d..f87e34a1d 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -471,6 +471,7 @@ xfs_rmapbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_rmapbt_ops = {
+ .type = XFS_BTREE_TYPE_AG,
.geom_flags = XFS_BTGEO_OVERLAPPING,
.rec_len = sizeof(struct xfs_rmap_rec),
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 048/111] xfs: split the per-btree union in struct xfs_btree_cur
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (46 preceding siblings ...)
2024-05-22 3:01 ` [PATCH 047/111] xfs: split out a btree type from the btree ops geometry flags Darrick J. Wong
@ 2024-05-22 3:01 ` Darrick J. Wong
2024-05-22 3:01 ` [PATCH 049/111] xfs: create predicate to determine if cursor is at inode root level Darrick J. Wong
` (63 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:01 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 88ee2f4849119b82b95d6e8e2d9daa81214eb080
Split up the union that encodes btree-specific fields in struct
xfs_btree_cur. Most fields in there are specific to the btree type
encoded in xfs_btree_ops.type, and we can use the obviously named union
for that. But one field is specific to the bmapbt and two are shared by
the refcount and rtrefcountbt. Move those to a separate union to make
the usage clear and not need a separate struct for the refcount-related
fields.
This will also make unnecessary some very awkward btree cursor
refc/rtrefc switching logic in the rtrefcount patchset.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap.c | 22 +++++++++--------
libxfs/xfs_bmap_btree.c | 9 +++----
libxfs/xfs_btree.c | 2 +-
libxfs/xfs_btree.h | 55 ++++++++++++++++++-------------------------
libxfs/xfs_btree_staging.c | 1 +
libxfs/xfs_refcount.c | 24 +++++++++----------
libxfs/xfs_refcount_btree.c | 4 ++-
7 files changed, 54 insertions(+), 63 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index b81f3e3da..2d332989b 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -670,7 +670,7 @@ xfs_bmap_extents_to_btree(
goto out_root_realloc;
}
- cur->bc_ino.allocated++;
+ cur->bc_bmap.allocated++;
ip->i_nblocks++;
xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
@@ -888,7 +888,7 @@ xfs_bmap_add_attrfork_btree(
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
return -ENOSPC;
}
- cur->bc_ino.allocated = 0;
+ cur->bc_bmap.allocated = 0;
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
}
return 0;
@@ -916,7 +916,7 @@ xfs_bmap_add_attrfork_extents(
error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags,
XFS_DATA_FORK);
if (cur) {
- cur->bc_ino.allocated = 0;
+ cur->bc_bmap.allocated = 0;
xfs_btree_del_cursor(cur, error);
}
return error;
@@ -1740,7 +1740,7 @@ xfs_bmap_add_extent_delay_real(
temp = PREV.br_blockcount - new->br_blockcount;
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
startblockval(PREV.br_startblock) -
- (bma->cur ? bma->cur->bc_ino.allocated : 0));
+ (bma->cur ? bma->cur->bc_bmap.allocated : 0));
PREV.br_startoff = new_endoff;
PREV.br_blockcount = temp;
@@ -1830,7 +1830,7 @@ xfs_bmap_add_extent_delay_real(
temp = PREV.br_blockcount - new->br_blockcount;
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
startblockval(PREV.br_startblock) -
- (bma->cur ? bma->cur->bc_ino.allocated : 0));
+ (bma->cur ? bma->cur->bc_bmap.allocated : 0));
PREV.br_startblock = nullstartblock(da_new);
PREV.br_blockcount = temp;
@@ -1953,8 +1953,8 @@ xfs_bmap_add_extent_delay_real(
xfs_mod_delalloc(mp, (int64_t)da_new - da_old);
if (bma->cur) {
- da_new += bma->cur->bc_ino.allocated;
- bma->cur->bc_ino.allocated = 0;
+ da_new += bma->cur->bc_bmap.allocated;
+ bma->cur->bc_bmap.allocated = 0;
}
/* adjust for changes in reserved delayed indirect blocks */
@@ -2519,7 +2519,7 @@ xfs_bmap_add_extent_unwritten_real(
/* clear out the allocated field, done with it now in any case. */
if (cur) {
- cur->bc_ino.allocated = 0;
+ cur->bc_bmap.allocated = 0;
*curp = cur;
}
@@ -2907,7 +2907,7 @@ xfs_bmap_add_extent_hole_real(
/* clear out the allocated field, done with it now in any case. */
if (cur)
- cur->bc_ino.allocated = 0;
+ cur->bc_bmap.allocated = 0;
xfs_bmap_check_leaf_extents(cur, ip, whichfork);
done:
@@ -5623,7 +5623,7 @@ __xfs_bunmapi(
xfs_trans_log_inode(tp, ip, logflags);
if (cur) {
if (!error)
- cur->bc_ino.allocated = 0;
+ cur->bc_bmap.allocated = 0;
xfs_btree_del_cursor(cur, error);
}
return error;
@@ -6139,7 +6139,7 @@ xfs_bmap_split_extent(
del_cursor:
if (cur) {
- cur->bc_ino.allocated = 0;
+ cur->bc_bmap.allocated = 0;
xfs_btree_del_cursor(cur, error);
}
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 54020dea2..9f66eee9a 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -197,10 +197,10 @@ xfs_bmbt_update_cursor(
ASSERT((dst->bc_tp->t_highest_agno != NULLAGNUMBER) ||
(dst->bc_ino.ip->i_diflags & XFS_DIFLAG_REALTIME));
- dst->bc_ino.allocated += src->bc_ino.allocated;
+ dst->bc_bmap.allocated += src->bc_bmap.allocated;
dst->bc_tp->t_highest_agno = src->bc_tp->t_highest_agno;
- src->bc_ino.allocated = 0;
+ src->bc_bmap.allocated = 0;
}
STATIC int
@@ -255,7 +255,7 @@ xfs_bmbt_alloc_block(
}
ASSERT(args.len == 1);
- cur->bc_ino.allocated++;
+ cur->bc_bmap.allocated++;
cur->bc_ino.ip->i_nblocks++;
xfs_trans_log_inode(args.tp, cur->bc_ino.ip, XFS_ILOG_CORE);
xfs_trans_mod_dquot_byino(args.tp, cur->bc_ino.ip,
@@ -567,8 +567,7 @@ xfs_bmbt_init_common(
mp->m_bm_maxlevels[whichfork], xfs_bmbt_cur_cache);
cur->bc_ino.ip = ip;
- cur->bc_ino.allocated = 0;
-
+ cur->bc_bmap.allocated = 0;
return cur;
}
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index f8c348e49..6d90e10b3 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -442,7 +442,7 @@ xfs_btree_del_cursor(
* zero, then we should be shut down or on our way to shutdown due to
* cancelling a dirty transaction on error.
*/
- ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_ino.allocated == 0 ||
+ ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_bmap.allocated == 0 ||
xfs_is_shutdown(cur->bc_mp) || error != 0);
switch (cur->bc_ops->type) {
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 5f2b5ef85..153d86725 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -243,30 +243,6 @@ union xfs_btree_irec {
struct xfs_refcount_irec rc;
};
-/* Per-AG btree information. */
-struct xfs_btree_cur_ag {
- struct xfs_perag *pag;
- union {
- struct xfs_buf *agbp;
- struct xbtree_afakeroot *afake; /* for staging cursor */
- };
- union {
- struct {
- unsigned int nr_ops; /* # record updates */
- unsigned int shape_changes; /* # of extent splits */
- } refc;
- };
-};
-
-/* Btree-in-inode cursor information */
-struct xfs_btree_cur_ino {
- struct xfs_inode *ip;
- struct xbtree_ifakeroot *ifake; /* for staging cursor */
- int allocated;
- short forksize;
- char whichfork;
-};
-
struct xfs_btree_level {
/* buffer pointer */
struct xfs_buf *bp;
@@ -296,15 +272,30 @@ struct xfs_btree_cur
uint8_t bc_nlevels; /* number of levels in the tree */
uint8_t bc_maxlevels; /* maximum levels for this btree type */
- /*
- * Short btree pointers need an agno to be able to turn the pointers
- * into physical addresses for IO, so the btree cursor switches between
- * bc_ino and bc_ag based on bc_ops->type.
- * the cursor.
- */
+ /* per-type information */
union {
- struct xfs_btree_cur_ag bc_ag;
- struct xfs_btree_cur_ino bc_ino;
+ struct {
+ struct xfs_inode *ip;
+ short forksize;
+ char whichfork;
+ struct xbtree_ifakeroot *ifake; /* for staging cursor */
+ } bc_ino;
+ struct {
+ struct xfs_perag *pag;
+ struct xfs_buf *agbp;
+ struct xbtree_afakeroot *afake; /* for staging cursor */
+ } bc_ag;
+ };
+
+ /* per-format private data */
+ union {
+ struct {
+ int allocated;
+ } bc_bmap; /* bmapbt */
+ struct {
+ unsigned int nr_ops; /* # record updates */
+ unsigned int shape_changes; /* # of extent splits */
+ } bc_refc; /* refcountbt */
};
/* Must be at the end of the struct! */
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index e1fd57dee..80bcb7ba2 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -172,6 +172,7 @@ xfs_btree_commit_afakeroot(
trace_xfs_btree_commit_afakeroot(cur);
kfree((void *)cur->bc_ops);
+ cur->bc_ag.afake = NULL;
cur->bc_ag.agbp = agbp;
cur->bc_ops = ops;
cur->bc_flags &= ~XFS_BTREE_STAGING;
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index d0d0d8617..47049488b 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -1076,7 +1076,7 @@ xfs_refcount_still_have_space(
* to handle each of the shape changes to the refcount btree.
*/
overhead = xfs_allocfree_block_count(cur->bc_mp,
- cur->bc_ag.refc.shape_changes);
+ cur->bc_refc.shape_changes);
overhead += cur->bc_mp->m_refc_maxlevels;
overhead *= cur->bc_mp->m_sb.sb_blocksize;
@@ -1084,17 +1084,17 @@ xfs_refcount_still_have_space(
* Only allow 2 refcount extent updates per transaction if the
* refcount continue update "error" has been injected.
*/
- if (cur->bc_ag.refc.nr_ops > 2 &&
+ if (cur->bc_refc.nr_ops > 2 &&
XFS_TEST_ERROR(false, cur->bc_mp,
XFS_ERRTAG_REFCOUNT_CONTINUE_UPDATE))
return false;
- if (cur->bc_ag.refc.nr_ops == 0)
+ if (cur->bc_refc.nr_ops == 0)
return true;
else if (overhead > cur->bc_tp->t_log_res)
return false;
- return cur->bc_tp->t_log_res - overhead >
- cur->bc_ag.refc.nr_ops * XFS_REFCOUNT_ITEM_OVERHEAD;
+ return cur->bc_tp->t_log_res - overhead >
+ cur->bc_refc.nr_ops * XFS_REFCOUNT_ITEM_OVERHEAD;
}
/*
@@ -1154,7 +1154,7 @@ xfs_refcount_adjust_extents(
* Either cover the hole (increment) or
* delete the range (decrement).
*/
- cur->bc_ag.refc.nr_ops++;
+ cur->bc_refc.nr_ops++;
if (tmp.rc_refcount) {
error = xfs_refcount_insert(cur, &tmp,
&found_tmp);
@@ -1215,7 +1215,7 @@ xfs_refcount_adjust_extents(
ext.rc_refcount += adj;
trace_xfs_refcount_modify_extent(cur->bc_mp,
cur->bc_ag.pag->pag_agno, &ext);
- cur->bc_ag.refc.nr_ops++;
+ cur->bc_refc.nr_ops++;
if (ext.rc_refcount > 1) {
error = xfs_refcount_update(cur, &ext);
if (error)
@@ -1304,7 +1304,7 @@ xfs_refcount_adjust(
if (shape_changed)
shape_changes++;
if (shape_changes)
- cur->bc_ag.refc.shape_changes++;
+ cur->bc_refc.shape_changes++;
/* Now that we've taken care of the ends, adjust the middle extents */
error = xfs_refcount_adjust_extents(cur, agbno, aglen, adj);
@@ -1399,8 +1399,8 @@ xfs_refcount_finish_one(
*/
rcur = *pcur;
if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
- nr_ops = rcur->bc_ag.refc.nr_ops;
- shape_changes = rcur->bc_ag.refc.shape_changes;
+ nr_ops = rcur->bc_refc.nr_ops;
+ shape_changes = rcur->bc_refc.shape_changes;
xfs_refcount_finish_one_cleanup(tp, rcur, 0);
rcur = NULL;
*pcur = NULL;
@@ -1412,8 +1412,8 @@ xfs_refcount_finish_one(
return error;
rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, ri->ri_pag);
- rcur->bc_ag.refc.nr_ops = nr_ops;
- rcur->bc_ag.refc.shape_changes = shape_changes;
+ rcur->bc_refc.nr_ops = nr_ops;
+ rcur->bc_refc.shape_changes = shape_changes;
}
*pcur = rcur;
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 3d61eeaca..529091a6b 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -361,8 +361,8 @@ xfs_refcountbt_init_common(
&xfs_refcountbt_ops, mp->m_refc_maxlevels,
xfs_refcountbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
- cur->bc_ag.refc.nr_ops = 0;
- cur->bc_ag.refc.shape_changes = 0;
+ cur->bc_refc.nr_ops = 0;
+ cur->bc_refc.shape_changes = 0;
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 049/111] xfs: create predicate to determine if cursor is at inode root level
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (47 preceding siblings ...)
2024-05-22 3:01 ` [PATCH 048/111] xfs: split the per-btree union in struct xfs_btree_cur Darrick J. Wong
@ 2024-05-22 3:01 ` Darrick J. Wong
2024-05-22 3:01 ` [PATCH 050/111] xfs: move comment about two 2 keys per pointer in the rmap btree Darrick J. Wong
` (62 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:01 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: f73def90a7cd24a32a42f689efba6a7a35edeb7b
Create a predicate to decide if the given cursor and level point to the
root block in the inode immediate area instead of a disk block, and get
rid of the open-coded logic everywhere.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_btree.c | 56 +++++++++++++++++++-------------------------
libxfs/xfs_btree.h | 10 ++++++++
libxfs/xfs_btree_staging.c | 3 +-
3 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 6d90e10b3..2511462e3 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -746,8 +746,7 @@ xfs_btree_get_block(
int level, /* level in btree */
struct xfs_buf **bpp) /* buffer containing the block */
{
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
- level == cur->bc_nlevels - 1) {
+ if (xfs_btree_at_iroot(cur, level)) {
*bpp = NULL;
return xfs_btree_get_iroot(cur);
}
@@ -989,8 +988,7 @@ xfs_btree_readahead(
* No readahead needed if we are at the root level and the
* btree root is stored in the inode.
*/
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
- lev == cur->bc_nlevels - 1)
+ if (xfs_btree_at_iroot(cur, lev))
return 0;
if ((cur->bc_levels[lev].ra | lr) == cur->bc_levels[lev].ra)
@@ -1811,8 +1809,7 @@ xfs_btree_lookup_get_block(
int error = 0;
/* special case the root block if in an inode */
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
- level == cur->bc_nlevels - 1) {
+ if (xfs_btree_at_iroot(cur, level)) {
*blkp = xfs_btree_get_iroot(cur);
return 0;
}
@@ -2347,8 +2344,7 @@ xfs_btree_lshift(
int error; /* error return value */
int i;
- if ((cur->bc_ops->type == XFS_BTREE_TYPE_INODE) &&
- level == cur->bc_nlevels - 1)
+ if (xfs_btree_at_iroot(cur, level))
goto out0;
/* Set up variables for this block as "right". */
@@ -2543,8 +2539,7 @@ xfs_btree_rshift(
int error; /* error return value */
int i; /* loop counter */
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
- level == cur->bc_nlevels - 1)
+ if (xfs_btree_at_iroot(cur, level))
goto out0;
/* Set up variables for this block as "left". */
@@ -3243,8 +3238,7 @@ xfs_btree_make_block_unfull(
{
int error = 0;
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
- level == cur->bc_nlevels - 1) {
+ if (xfs_btree_at_iroot(cur, level)) {
struct xfs_inode *ip = cur->bc_ino.ip;
if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) {
@@ -3853,27 +3847,25 @@ xfs_btree_delrec(
* Try to get rid of the next level down. If we can't then there's
* nothing left to do.
*/
+ if (xfs_btree_at_iroot(cur, level)) {
+ xfs_iroot_realloc(cur->bc_ino.ip, -1, cur->bc_ino.whichfork);
+
+ error = xfs_btree_kill_iroot(cur);
+ if (error)
+ goto error0;
+
+ error = xfs_btree_dec_cursor(cur, level, stat);
+ if (error)
+ goto error0;
+ *stat = 1;
+ return 0;
+ }
+
+ /*
+ * If this is the root level, and there's only one entry left, and it's
+ * NOT the leaf level, then we can get rid of this level.
+ */
if (level == cur->bc_nlevels - 1) {
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
- xfs_iroot_realloc(cur->bc_ino.ip, -1,
- cur->bc_ino.whichfork);
-
- error = xfs_btree_kill_iroot(cur);
- if (error)
- goto error0;
-
- error = xfs_btree_dec_cursor(cur, level, stat);
- if (error)
- goto error0;
- *stat = 1;
- return 0;
- }
-
- /*
- * If this is the root level, and there's only one entry left,
- * and it's NOT the leaf level, then we can get rid of this
- * level.
- */
if (numrecs == 1 && level > 0) {
union xfs_btree_ptr *pp;
/*
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 153d86725..07abc56e0 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -747,4 +747,14 @@ void xfs_btree_destroy_cur_caches(void);
int xfs_btree_goto_left_edge(struct xfs_btree_cur *cur);
+/* Does this level of the cursor point to the inode root (and not a block)? */
+static inline bool
+xfs_btree_at_iroot(
+ const struct xfs_btree_cur *cur,
+ int level)
+{
+ return cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
+ level == cur->bc_nlevels - 1;
+}
+
#endif /* __XFS_BTREE_H__ */
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 80bcb7ba2..07b43da78 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -398,8 +398,7 @@ xfs_btree_bload_prep_block(
struct xfs_btree_block *new_block;
int ret;
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
- level == cur->bc_nlevels - 1) {
+ if (xfs_btree_at_iroot(cur, level)) {
struct xfs_ifork *ifp = xfs_btree_ifork_ptr(cur);
size_t new_size;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 050/111] xfs: move comment about two 2 keys per pointer in the rmap btree
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (48 preceding siblings ...)
2024-05-22 3:01 ` [PATCH 049/111] xfs: create predicate to determine if cursor is at inode root level Darrick J. Wong
@ 2024-05-22 3:01 ` Darrick J. Wong
2024-05-22 3:02 ` [PATCH 051/111] xfs: add a xfs_btree_init_ptr_from_cur Darrick J. Wong
` (61 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:01 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 72c2070f3f52196a2e8b4efced94390b62eb8ac4
Move it to the relevant initialization of the ops structure instead
of a place that has nothing to do with the key size.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_rmap_btree.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index f87e34a1d..311261df3 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -475,6 +475,7 @@ const struct xfs_btree_ops xfs_rmapbt_ops = {
.geom_flags = XFS_BTGEO_OVERLAPPING,
.rec_len = sizeof(struct xfs_rmap_rec),
+ /* Overlapping btree; 2 keys per pointer. */
.key_len = 2 * sizeof(struct xfs_rmap_key),
.ptr_len = XFS_BTREE_SHORT_PTR_LEN,
@@ -507,7 +508,6 @@ xfs_rmapbt_init_common(
{
struct xfs_btree_cur *cur;
- /* Overlapping btree; 2 keys per pointer. */
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 051/111] xfs: add a xfs_btree_init_ptr_from_cur
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (49 preceding siblings ...)
2024-05-22 3:01 ` [PATCH 050/111] xfs: move comment about two 2 keys per pointer in the rmap btree Darrick J. Wong
@ 2024-05-22 3:02 ` Darrick J. Wong
2024-05-22 3:02 ` [PATCH 052/111] xfs: don't override bc_ops for staging btrees Darrick J. Wong
` (60 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:02 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: f9c18129e57df7b33f4257340840525816481da6
Inode-rooted btrees don't need to initialize the root pointer in the
->init_ptr_from_cur method as the root is found by the
xfs_btree_get_iroot method later. Make ->init_ptr_from_cur option
for inode rooted btrees by providing a helper that does the right
thing for the given btree type and also documents the semantics.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap_btree.c | 9 ---------
libxfs/xfs_btree.c | 27 +++++++++++++++++++++++----
libxfs/xfs_btree.h | 2 ++
libxfs/xfs_btree_staging.c | 1 -
4 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 9f66eee9a..7fc325fd3 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -368,14 +368,6 @@ xfs_bmbt_init_rec_from_cur(
xfs_bmbt_disk_set_all(&rec->bmbt, &cur->bc_rec.b);
}
-STATIC void
-xfs_bmbt_init_ptr_from_cur(
- struct xfs_btree_cur *cur,
- union xfs_btree_ptr *ptr)
-{
- ptr->l = 0;
-}
-
STATIC int64_t
xfs_bmbt_key_diff(
struct xfs_btree_cur *cur,
@@ -543,7 +535,6 @@ const struct xfs_btree_ops xfs_bmbt_ops = {
.init_key_from_rec = xfs_bmbt_init_key_from_rec,
.init_high_key_from_rec = xfs_bmbt_init_high_key_from_rec,
.init_rec_from_cur = xfs_bmbt_init_rec_from_cur,
- .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
.key_diff = xfs_bmbt_key_diff,
.diff_two_keys = xfs_bmbt_diff_two_keys,
.buf_ops = &xfs_bmbt_buf_ops,
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 2511462e3..f59fa54e3 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1878,6 +1878,25 @@ xfs_lookup_get_search_key(
return xfs_btree_key_addr(cur, keyno, block);
}
+/*
+ * Initialize a pointer to the root block.
+ */
+void
+xfs_btree_init_ptr_from_cur(
+ struct xfs_btree_cur *cur,
+ union xfs_btree_ptr *ptr)
+{
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
+ /*
+ * Inode-rooted btrees call xfs_btree_get_iroot to find the root
+ * in xfs_btree_lookup_get_block and don't need a pointer here.
+ */
+ ptr->l = 0;
+ } else {
+ cur->bc_ops->init_ptr_from_cur(cur, ptr);
+ }
+}
+
/*
* Lookup the record. The cursor is made to point to it, based on dir.
* stat is set to 0 if can't find any such record, 1 for success.
@@ -1908,7 +1927,7 @@ xfs_btree_lookup(
keyno = 0;
/* initialise start pointer from cursor */
- cur->bc_ops->init_ptr_from_cur(cur, &ptr);
+ xfs_btree_init_ptr_from_cur(cur, &ptr);
pp = &ptr;
/*
@@ -3118,7 +3137,7 @@ xfs_btree_new_root(
XFS_BTREE_STATS_INC(cur, newroot);
/* initialise our start point from the cursor */
- cur->bc_ops->init_ptr_from_cur(cur, &rptr);
+ xfs_btree_init_ptr_from_cur(cur, &rptr);
/* Allocate the new block. If we can't do it, we're toast. Give up. */
error = xfs_btree_alloc_block(cur, &rptr, &lptr, stat);
@@ -4427,7 +4446,7 @@ xfs_btree_visit_blocks(
struct xfs_btree_block *block = NULL;
int error = 0;
- cur->bc_ops->init_ptr_from_cur(cur, &lptr);
+ xfs_btree_init_ptr_from_cur(cur, &lptr);
/* for each level */
for (level = cur->bc_nlevels - 1; level >= 0; level--) {
@@ -4849,7 +4868,7 @@ xfs_btree_overlapped_query_range(
/* Load the root of the btree. */
level = cur->bc_nlevels - 1;
- cur->bc_ops->init_ptr_from_cur(cur, &ptr);
+ xfs_btree_init_ptr_from_cur(cur, &ptr);
error = xfs_btree_lookup_get_block(cur, level, &ptr, &block);
if (error)
return error;
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 07abc56e0..99194ae94 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -714,6 +714,8 @@ void xfs_btree_copy_ptrs(struct xfs_btree_cur *cur,
void xfs_btree_copy_keys(struct xfs_btree_cur *cur,
union xfs_btree_key *dst_key,
const union xfs_btree_key *src_key, int numkeys);
+void xfs_btree_init_ptr_from_cur(struct xfs_btree_cur *cur,
+ union xfs_btree_ptr *ptr);
static inline struct xfs_btree_cur *
xfs_btree_alloc_cursor(
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 07b43da78..656bad6cd 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -225,7 +225,6 @@ xfs_btree_stage_ifakeroot(
memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
nops->alloc_block = xfs_btree_fakeroot_alloc_block;
nops->free_block = xfs_btree_fakeroot_free_block;
- nops->init_ptr_from_cur = xfs_btree_fakeroot_init_ptr_from_cur;
nops->dup_cursor = xfs_btree_fakeroot_dup_cursor;
cur->bc_ino.ifake = ifake;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 052/111] xfs: don't override bc_ops for staging btrees
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (50 preceding siblings ...)
2024-05-22 3:02 ` [PATCH 051/111] xfs: add a xfs_btree_init_ptr_from_cur Darrick J. Wong
@ 2024-05-22 3:02 ` Darrick J. Wong
2024-05-22 3:02 ` [PATCH 053/111] xfs: fold xfs_allocbt_init_common into xfs_allocbt_init_cursor Darrick J. Wong
` (59 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:02 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 2b9e7f2668c540f18afd66a053ea78f3a629f8e2
Add a few conditionals for staging btrees to the core btree code instead
of overloading the bc_ops vector.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc_btree.c | 6 --
libxfs/xfs_bmap_btree.c | 6 +-
libxfs/xfs_btree.c | 75 +++++++++++++++++++++++-------
libxfs/xfs_btree_staging.c | 109 +------------------------------------------
libxfs/xfs_btree_staging.h | 7 +--
libxfs/xfs_ialloc_btree.c | 4 +-
libxfs/xfs_refcount_btree.c | 2 -
libxfs/xfs_rmap_btree.c | 2 -
8 files changed, 72 insertions(+), 139 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index b18ac7045..6b17037f8 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -592,11 +592,7 @@ xfs_allocbt_commit_staged_btree(
agf->agf_levels[cur->bc_btnum] = cpu_to_be32(afake->af_levels);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
- if (cur->bc_btnum == XFS_BTNUM_BNO) {
- xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_bnobt_ops);
- } else {
- xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_cntbt_ops);
- }
+ xfs_btree_commit_afakeroot(cur, tp, agbp);
}
/* Calculate number of records in an alloc btree block. */
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 7fc325fd3..611f5ed96 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -608,7 +608,6 @@ xfs_bmbt_stage_cursor(
struct xbtree_ifakeroot *ifake)
{
struct xfs_btree_cur *cur;
- struct xfs_btree_ops *ops;
/* data fork always has larger maxheight */
cur = xfs_bmbt_init_common(mp, NULL, ip, XFS_DATA_FORK);
@@ -617,8 +616,7 @@ xfs_bmbt_stage_cursor(
/* Don't let anyone think we're attached to the real fork yet. */
cur->bc_ino.whichfork = -1;
- xfs_btree_stage_ifakeroot(cur, ifake, &ops);
- ops->update_cursor = NULL;
+ xfs_btree_stage_ifakeroot(cur, ifake);
return cur;
}
@@ -662,7 +660,7 @@ xfs_bmbt_commit_staged_btree(
break;
}
xfs_trans_log_inode(tp, cur->bc_ino.ip, flags);
- xfs_btree_commit_ifakeroot(cur, tp, whichfork, &xfs_bmbt_ops);
+ xfs_btree_commit_ifakeroot(cur, tp, whichfork);
}
/*
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index f59fa54e3..42a1ed786 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -404,6 +404,15 @@ xfs_btree_free_block(
trace_xfs_btree_free_block(cur, bp);
+ /*
+ * Don't allow block freeing for a staging cursor, because staging
+ * cursors do not support regular btree modifications.
+ */
+ if (unlikely(cur->bc_flags & XFS_BTREE_STAGING)) {
+ ASSERT(0);
+ return -EFSCORRUPTED;
+ }
+
error = cur->bc_ops->free_block(cur, bp);
if (!error) {
xfs_trans_binval(cur->bc_tp, bp);
@@ -455,8 +464,6 @@ xfs_btree_del_cursor(
break;
}
- if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
- kfree(cur->bc_ops);
kmem_cache_free(cur->bc_cache, cur);
}
@@ -464,20 +471,26 @@ xfs_btree_del_cursor(
* Duplicate the btree cursor.
* Allocate a new one, copy the record, re-get the buffers.
*/
-int /* error */
+int /* error */
xfs_btree_dup_cursor(
- struct xfs_btree_cur *cur, /* input cursor */
- struct xfs_btree_cur **ncur) /* output cursor */
+ struct xfs_btree_cur *cur, /* input cursor */
+ struct xfs_btree_cur **ncur) /* output cursor */
{
- struct xfs_buf *bp; /* btree block's buffer pointer */
- int error; /* error return value */
- int i; /* level number of btree block */
- xfs_mount_t *mp; /* mount structure for filesystem */
- struct xfs_btree_cur *new; /* new cursor value */
- xfs_trans_t *tp; /* transaction pointer, can be NULL */
+ struct xfs_mount *mp = cur->bc_mp;
+ struct xfs_trans *tp = cur->bc_tp;
+ struct xfs_buf *bp;
+ struct xfs_btree_cur *new;
+ int error;
+ int i;
- tp = cur->bc_tp;
- mp = cur->bc_mp;
+ /*
+ * Don't allow staging cursors to be duplicated because they're supposed
+ * to be kept private to a single thread.
+ */
+ if (unlikely(cur->bc_flags & XFS_BTREE_STAGING)) {
+ ASSERT(0);
+ return -EFSCORRUPTED;
+ }
/*
* Allocate a new cursor like the old one.
@@ -1892,6 +1905,8 @@ xfs_btree_init_ptr_from_cur(
* in xfs_btree_lookup_get_block and don't need a pointer here.
*/
ptr->l = 0;
+ } else if (cur->bc_flags & XFS_BTREE_STAGING) {
+ ptr->s = cpu_to_be32(cur->bc_ag.afake->af_root);
} else {
cur->bc_ops->init_ptr_from_cur(cur, ptr);
}
@@ -2713,6 +2728,18 @@ xfs_btree_alloc_block(
{
int error;
+ /*
+ * Don't allow block allocation for a staging cursor, because staging
+ * cursors do not support regular btree modifications.
+ *
+ * Bulk loading uses a separate callback to obtain new blocks from a
+ * preallocated list, which prevents ENOSPC failures during loading.
+ */
+ if (unlikely(cur->bc_flags & XFS_BTREE_STAGING)) {
+ ASSERT(0);
+ return -EFSCORRUPTED;
+ }
+
error = cur->bc_ops->alloc_block(cur, hint_block, new_block, stat);
trace_xfs_btree_alloc_block(cur, new_block, *stat, error);
return error;
@@ -3113,6 +3140,21 @@ xfs_btree_new_iroot(
return error;
}
+static void
+xfs_btree_set_root(
+ struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *ptr,
+ int inc)
+{
+ if (cur->bc_flags & XFS_BTREE_STAGING) {
+ /* Update the btree root information for a per-AG fake root. */
+ cur->bc_ag.afake->af_root = be32_to_cpu(ptr->s);
+ cur->bc_ag.afake->af_levels += inc;
+ } else {
+ cur->bc_ops->set_root(cur, ptr, inc);
+ }
+}
+
/*
* Allocate a new root block, fill it in.
*/
@@ -3153,7 +3195,7 @@ xfs_btree_new_root(
goto error0;
/* Set the root in the holding structure increasing the level by 1. */
- cur->bc_ops->set_root(cur, &lptr, 1);
+ xfs_btree_set_root(cur, &lptr, 1);
/*
* At the previous root level there are now two blocks: the old root,
@@ -3581,7 +3623,8 @@ xfs_btree_insert(
if (pcur != cur &&
(ncur || xfs_btree_ptr_is_null(cur, &nptr))) {
/* Save the state from the cursor before we trash it */
- if (cur->bc_ops->update_cursor)
+ if (cur->bc_ops->update_cursor &&
+ !(cur->bc_flags & XFS_BTREE_STAGING))
cur->bc_ops->update_cursor(pcur, cur);
cur->bc_nlevels = pcur->bc_nlevels;
xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
@@ -3724,7 +3767,7 @@ xfs_btree_kill_root(
* Update the root pointer, decreasing the level by 1 and then
* free the old root.
*/
- cur->bc_ops->set_root(cur, newroot, -1);
+ xfs_btree_set_root(cur, newroot, -1);
error = xfs_btree_free_block(cur, bp);
if (error)
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 656bad6cd..5a988a8bf 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -38,63 +38,6 @@
* specific btree type to commit the new btree into the filesystem.
*/
-/*
- * Don't allow staging cursors to be duplicated because they're supposed to be
- * kept private to a single thread.
- */
-STATIC struct xfs_btree_cur *
-xfs_btree_fakeroot_dup_cursor(
- struct xfs_btree_cur *cur)
-{
- ASSERT(0);
- return NULL;
-}
-
-/*
- * Don't allow block allocation for a staging cursor, because staging cursors
- * do not support regular btree modifications.
- *
- * Bulk loading uses a separate callback to obtain new blocks from a
- * preallocated list, which prevents ENOSPC failures during loading.
- */
-STATIC int
-xfs_btree_fakeroot_alloc_block(
- struct xfs_btree_cur *cur,
- const union xfs_btree_ptr *start_bno,
- union xfs_btree_ptr *new_bno,
- int *stat)
-{
- ASSERT(0);
- return -EFSCORRUPTED;
-}
-
-/*
- * Don't allow block freeing for a staging cursor, because staging cursors
- * do not support regular btree modifications.
- */
-STATIC int
-xfs_btree_fakeroot_free_block(
- struct xfs_btree_cur *cur,
- struct xfs_buf *bp)
-{
- ASSERT(0);
- return -EFSCORRUPTED;
-}
-
-/* Initialize a pointer to the root block from the fakeroot. */
-STATIC void
-xfs_btree_fakeroot_init_ptr_from_cur(
- struct xfs_btree_cur *cur,
- union xfs_btree_ptr *ptr)
-{
- struct xbtree_afakeroot *afake;
-
- ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
-
- afake = cur->bc_ag.afake;
- ptr->s = cpu_to_be32(afake->af_root);
-}
-
/*
* Bulk Loading for AG Btrees
* ==========================
@@ -109,47 +52,20 @@ xfs_btree_fakeroot_init_ptr_from_cur(
* cursor into a regular btree cursor.
*/
-/* Update the btree root information for a per-AG fake root. */
-STATIC void
-xfs_btree_afakeroot_set_root(
- struct xfs_btree_cur *cur,
- const union xfs_btree_ptr *ptr,
- int inc)
-{
- struct xbtree_afakeroot *afake = cur->bc_ag.afake;
-
- ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
- afake->af_root = be32_to_cpu(ptr->s);
- afake->af_levels += inc;
-}
-
/*
* Initialize a AG-rooted btree cursor with the given AG btree fake root.
- * The btree cursor's bc_ops will be overridden as needed to make the staging
- * functionality work.
*/
void
xfs_btree_stage_afakeroot(
struct xfs_btree_cur *cur,
struct xbtree_afakeroot *afake)
{
- struct xfs_btree_ops *nops;
-
ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
ASSERT(cur->bc_ops->type != XFS_BTREE_TYPE_INODE);
ASSERT(cur->bc_tp == NULL);
- nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
- memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
- nops->alloc_block = xfs_btree_fakeroot_alloc_block;
- nops->free_block = xfs_btree_fakeroot_free_block;
- nops->init_ptr_from_cur = xfs_btree_fakeroot_init_ptr_from_cur;
- nops->set_root = xfs_btree_afakeroot_set_root;
- nops->dup_cursor = xfs_btree_fakeroot_dup_cursor;
-
cur->bc_ag.afake = afake;
cur->bc_nlevels = afake->af_levels;
- cur->bc_ops = nops;
cur->bc_flags |= XFS_BTREE_STAGING;
}
@@ -163,18 +79,15 @@ void
xfs_btree_commit_afakeroot(
struct xfs_btree_cur *cur,
struct xfs_trans *tp,
- struct xfs_buf *agbp,
- const struct xfs_btree_ops *ops)
+ struct xfs_buf *agbp)
{
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
ASSERT(cur->bc_tp == NULL);
trace_xfs_btree_commit_afakeroot(cur);
- kfree((void *)cur->bc_ops);
cur->bc_ag.afake = NULL;
cur->bc_ag.agbp = agbp;
- cur->bc_ops = ops;
cur->bc_flags &= ~XFS_BTREE_STAGING;
cur->bc_tp = tp;
}
@@ -212,28 +125,15 @@ xfs_btree_commit_afakeroot(
void
xfs_btree_stage_ifakeroot(
struct xfs_btree_cur *cur,
- struct xbtree_ifakeroot *ifake,
- struct xfs_btree_ops **new_ops)
+ struct xbtree_ifakeroot *ifake)
{
- struct xfs_btree_ops *nops;
-
ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
ASSERT(cur->bc_tp == NULL);
- nops = kmalloc(sizeof(struct xfs_btree_ops), GFP_KERNEL | __GFP_NOFAIL);
- memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
- nops->alloc_block = xfs_btree_fakeroot_alloc_block;
- nops->free_block = xfs_btree_fakeroot_free_block;
- nops->dup_cursor = xfs_btree_fakeroot_dup_cursor;
-
cur->bc_ino.ifake = ifake;
cur->bc_nlevels = ifake->if_levels;
- cur->bc_ops = nops;
cur->bc_flags |= XFS_BTREE_STAGING;
-
- if (new_ops)
- *new_ops = nops;
}
/*
@@ -246,18 +146,15 @@ void
xfs_btree_commit_ifakeroot(
struct xfs_btree_cur *cur,
struct xfs_trans *tp,
- int whichfork,
- const struct xfs_btree_ops *ops)
+ int whichfork)
{
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
ASSERT(cur->bc_tp == NULL);
trace_xfs_btree_commit_ifakeroot(cur);
- kfree((void *)cur->bc_ops);
cur->bc_ino.ifake = NULL;
cur->bc_ino.whichfork = whichfork;
- cur->bc_ops = ops;
cur->bc_flags &= ~XFS_BTREE_STAGING;
cur->bc_tp = tp;
}
diff --git a/libxfs/xfs_btree_staging.h b/libxfs/xfs_btree_staging.h
index 8e29cd3cc..0c9c2ffb1 100644
--- a/libxfs/xfs_btree_staging.h
+++ b/libxfs/xfs_btree_staging.h
@@ -22,7 +22,7 @@ struct xbtree_afakeroot {
void xfs_btree_stage_afakeroot(struct xfs_btree_cur *cur,
struct xbtree_afakeroot *afake);
void xfs_btree_commit_afakeroot(struct xfs_btree_cur *cur, struct xfs_trans *tp,
- struct xfs_buf *agbp, const struct xfs_btree_ops *ops);
+ struct xfs_buf *agbp);
/* Fake root for an inode-rooted btree. */
struct xbtree_ifakeroot {
@@ -41,10 +41,9 @@ struct xbtree_ifakeroot {
/* Cursor interactions with fake roots for inode-rooted btrees. */
void xfs_btree_stage_ifakeroot(struct xfs_btree_cur *cur,
- struct xbtree_ifakeroot *ifake,
- struct xfs_btree_ops **new_ops);
+ struct xbtree_ifakeroot *ifake);
void xfs_btree_commit_ifakeroot(struct xfs_btree_cur *cur, struct xfs_trans *tp,
- int whichfork, const struct xfs_btree_ops *ops);
+ int whichfork);
/* Bulk loading of staged btrees. */
typedef int (*xfs_btree_bload_get_records_fn)(struct xfs_btree_cur *cur,
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 79ab04684..87471ba14 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -536,7 +536,7 @@ xfs_inobt_commit_staged_btree(
fields |= XFS_AGI_IBLOCKS;
}
xfs_ialloc_log_agi(tp, agbp, fields);
- xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_inobt_ops);
+ xfs_btree_commit_afakeroot(cur, tp, agbp);
} else {
fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL;
agi->agi_free_root = cpu_to_be32(afake->af_root);
@@ -546,7 +546,7 @@ xfs_inobt_commit_staged_btree(
fields |= XFS_AGI_IBLOCKS;
}
xfs_ialloc_log_agi(tp, agbp, fields);
- xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_finobt_ops);
+ xfs_btree_commit_afakeroot(cur, tp, agbp);
}
}
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 529091a6b..45bfb39e0 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -418,7 +418,7 @@ xfs_refcountbt_commit_staged_btree(
xfs_alloc_log_agf(tp, agbp, XFS_AGF_REFCOUNT_BLOCKS |
XFS_AGF_REFCOUNT_ROOT |
XFS_AGF_REFCOUNT_LEVEL);
- xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_refcountbt_ops);
+ xfs_btree_commit_afakeroot(cur, tp, agbp);
}
/* Calculate number of records in a refcount btree block. */
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 311261df3..52c820108 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -565,7 +565,7 @@ xfs_rmapbt_commit_staged_btree(
agf->agf_rmap_blocks = cpu_to_be32(afake->af_blocks);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS |
XFS_AGF_RMAP_BLOCKS);
- xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_rmapbt_ops);
+ xfs_btree_commit_afakeroot(cur, tp, agbp);
}
/* Calculate number of records in a reverse mapping btree block. */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 053/111] xfs: fold xfs_allocbt_init_common into xfs_allocbt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (51 preceding siblings ...)
2024-05-22 3:02 ` [PATCH 052/111] xfs: don't override bc_ops for staging btrees Darrick J. Wong
@ 2024-05-22 3:02 ` Darrick J. Wong
2024-05-22 3:02 ` [PATCH 054/111] xfs: remove xfs_allocbt_stage_cursor Darrick J. Wong
` (58 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:02 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: fb518f8eeb90197624b21a3429e57b6a65bff7bb
Make the levels initialization in xfs_allocbt_init_cursor conditional
and merge the two helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc_btree.c | 42 +++++++++++++++---------------------------
1 file changed, 15 insertions(+), 27 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 6b17037f8..13d2310cf 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -511,11 +511,16 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
.keys_contiguous = NULL, /* not needed right now */
};
-/* Allocate most of a new allocation btree cursor. */
-STATIC struct xfs_btree_cur *
-xfs_allocbt_init_common(
+/*
+ * Allocate a new allocation btree cursor.
+ *
+ * For staging cursors tp and agbp are NULL.
+ */
+struct xfs_btree_cur *
+xfs_allocbt_init_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
+ struct xfs_buf *agbp,
struct xfs_perag *pag,
xfs_btnum_t btnum)
{
@@ -530,31 +535,14 @@ xfs_allocbt_init_common(
cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops, mp->m_alloc_maxlevels,
xfs_allocbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
- return cur;
-}
-
-/*
- * Allocate a new allocation btree cursor.
- */
-struct xfs_btree_cur * /* new alloc btree cursor */
-xfs_allocbt_init_cursor(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- struct xfs_buf *agbp, /* buffer for agf structure */
- struct xfs_perag *pag,
- xfs_btnum_t btnum) /* btree identifier */
-{
- struct xfs_agf *agf = agbp->b_addr;
- struct xfs_btree_cur *cur;
-
- cur = xfs_allocbt_init_common(mp, tp, pag, btnum);
- if (btnum == XFS_BTNUM_CNT)
- cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
- else
- cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
-
cur->bc_ag.agbp = agbp;
+ if (agbp) {
+ struct xfs_agf *agf = agbp->b_addr;
+ cur->bc_nlevels = (btnum == XFS_BTNUM_BNO) ?
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) :
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
+ }
return cur;
}
@@ -568,7 +556,7 @@ xfs_allocbt_stage_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_allocbt_init_common(mp, NULL, pag, btnum);
+ cur = xfs_allocbt_init_cursor(mp, NULL, NULL, pag, btnum);
xfs_btree_stage_afakeroot(cur, afake);
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 054/111] xfs: remove xfs_allocbt_stage_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (52 preceding siblings ...)
2024-05-22 3:02 ` [PATCH 053/111] xfs: fold xfs_allocbt_init_common into xfs_allocbt_init_cursor Darrick J. Wong
@ 2024-05-22 3:02 ` Darrick J. Wong
2024-05-22 3:03 ` [PATCH 055/111] xfs: fold xfs_inobt_init_common into xfs_inobt_init_cursor Darrick J. Wong
` (57 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:02 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 91796b2eef8bd725873bec326a7be830a68a11ff
Just open code the two calls in the callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/libxfs_api_defs.h | 2 ++
libxfs/xfs_alloc_btree.c | 15 ---------------
libxfs/xfs_alloc_btree.h | 3 ---
repair/agbtree.c | 11 +++++++----
4 files changed, 9 insertions(+), 22 deletions(-)
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 769733ec2..9a2968906 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -26,6 +26,7 @@
#define xfs_alloc_ag_max_usable libxfs_alloc_ag_max_usable
#define xfs_allocbt_calc_size libxfs_allocbt_calc_size
+#define xfs_allocbt_init_cursor libxfs_allocbt_init_cursor
#define xfs_allocbt_maxlevels_ondisk libxfs_allocbt_maxlevels_ondisk
#define xfs_allocbt_maxrecs libxfs_allocbt_maxrecs
#define xfs_allocbt_stage_cursor libxfs_allocbt_stage_cursor
@@ -63,6 +64,7 @@
#define xfs_btree_del_cursor libxfs_btree_del_cursor
#define xfs_btree_init_block libxfs_btree_init_block
#define xfs_btree_rec_addr libxfs_btree_rec_addr
+#define xfs_btree_stage_afakeroot libxfs_btree_stage_afakeroot
#define xfs_buf_delwri_submit libxfs_buf_delwri_submit
#define xfs_buf_get libxfs_buf_get
#define xfs_buf_get_uncached libxfs_buf_get_uncached
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 13d2310cf..bd7878b68 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -546,21 +546,6 @@ xfs_allocbt_init_cursor(
return cur;
}
-/* Create a free space btree cursor with a fake root for staging. */
-struct xfs_btree_cur *
-xfs_allocbt_stage_cursor(
- struct xfs_mount *mp,
- struct xbtree_afakeroot *afake,
- struct xfs_perag *pag,
- xfs_btnum_t btnum)
-{
- struct xfs_btree_cur *cur;
-
- cur = xfs_allocbt_init_cursor(mp, NULL, NULL, pag, btnum);
- xfs_btree_stage_afakeroot(cur, afake);
- return cur;
-}
-
/*
* Install a new free space btree root. Caller is responsible for invalidating
* and freeing the old btree blocks.
diff --git a/libxfs/xfs_alloc_btree.h b/libxfs/xfs_alloc_btree.h
index 45df893ef..1c9108625 100644
--- a/libxfs/xfs_alloc_btree.h
+++ b/libxfs/xfs_alloc_btree.h
@@ -50,9 +50,6 @@ struct xbtree_afakeroot;
extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_buf *bp,
struct xfs_perag *pag, xfs_btnum_t btnum);
-struct xfs_btree_cur *xfs_allocbt_stage_cursor(struct xfs_mount *mp,
- struct xbtree_afakeroot *afake, struct xfs_perag *pag,
- xfs_btnum_t btnum);
extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int);
extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp,
unsigned long long len);
diff --git a/repair/agbtree.c b/repair/agbtree.c
index 38f3f7b8f..d5fa4eafb 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -262,10 +262,13 @@ init_freespace_cursors(
init_rebuild(sc, &XFS_RMAP_OINFO_AG, est_agfreeblocks, btr_bno);
init_rebuild(sc, &XFS_RMAP_OINFO_AG, est_agfreeblocks, btr_cnt);
- btr_bno->cur = libxfs_allocbt_stage_cursor(sc->mp,
- &btr_bno->newbt.afake, pag, XFS_BTNUM_BNO);
- btr_cnt->cur = libxfs_allocbt_stage_cursor(sc->mp,
- &btr_cnt->newbt.afake, pag, XFS_BTNUM_CNT);
+ btr_bno->cur = libxfs_allocbt_init_cursor(sc->mp, NULL, NULL, pag,
+ XFS_BTNUM_BNO);
+ libxfs_btree_stage_afakeroot(btr_bno->cur, &btr_bno->newbt.afake);
+
+ btr_cnt->cur = libxfs_allocbt_init_cursor(sc->mp, NULL, NULL, pag,
+ XFS_BTNUM_CNT);
+ libxfs_btree_stage_afakeroot(btr_cnt->cur, &btr_cnt->newbt.afake);
btr_bno->bload.get_records = get_bnobt_records;
btr_bno->bload.claim_block = rebuild_claim_block;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 055/111] xfs: fold xfs_inobt_init_common into xfs_inobt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (53 preceding siblings ...)
2024-05-22 3:02 ` [PATCH 054/111] xfs: remove xfs_allocbt_stage_cursor Darrick J. Wong
@ 2024-05-22 3:03 ` Darrick J. Wong
2024-05-22 3:03 ` [PATCH 056/111] xfs: remove xfs_inobt_stage_cursor Darrick J. Wong
` (56 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:03 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: f6c98d921a9e5b753ac1a35d540a6487ee111a33
Make the levels initialization in xfs_inobt_init_cursor conditional
and merge the two helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_ialloc_btree.c | 39 +++++++++++++++------------------------
1 file changed, 15 insertions(+), 24 deletions(-)
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 87471ba14..aa3f586da 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -454,12 +454,15 @@ const struct xfs_btree_ops xfs_finobt_ops = {
};
/*
- * Initialize a new inode btree cursor.
+ * Create an inode btree cursor.
+ *
+ * For staging cursors tp and agbp are NULL.
*/
-static struct xfs_btree_cur *
-xfs_inobt_init_common(
+struct xfs_btree_cur *
+xfs_inobt_init_cursor(
struct xfs_perag *pag,
- struct xfs_trans *tp, /* transaction pointer */
+ struct xfs_trans *tp,
+ struct xfs_buf *agbp,
xfs_btnum_t btnum) /* ialloc or free ino btree */
{
struct xfs_mount *mp = pag->pag_mount;
@@ -474,26 +477,14 @@ xfs_inobt_init_common(
cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops,
M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
- return cur;
-}
-
-/* Create an inode btree cursor. */
-struct xfs_btree_cur *
-xfs_inobt_init_cursor(
- struct xfs_perag *pag,
- struct xfs_trans *tp,
- struct xfs_buf *agbp,
- xfs_btnum_t btnum)
-{
- struct xfs_btree_cur *cur;
- struct xfs_agi *agi = agbp->b_addr;
-
- cur = xfs_inobt_init_common(pag, tp, btnum);
- if (btnum == XFS_BTNUM_INO)
- cur->bc_nlevels = be32_to_cpu(agi->agi_level);
- else
- cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
cur->bc_ag.agbp = agbp;
+ if (agbp) {
+ struct xfs_agi *agi = agbp->b_addr;
+
+ cur->bc_nlevels = (btnum == XFS_BTNUM_INO) ?
+ be32_to_cpu(agi->agi_level) :
+ be32_to_cpu(agi->agi_free_level);
+ }
return cur;
}
@@ -506,7 +497,7 @@ xfs_inobt_stage_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_inobt_init_common(pag, NULL, btnum);
+ cur = xfs_inobt_init_cursor(pag, NULL, NULL, btnum);
xfs_btree_stage_afakeroot(cur, afake);
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 056/111] xfs: remove xfs_inobt_stage_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (54 preceding siblings ...)
2024-05-22 3:03 ` [PATCH 055/111] xfs: fold xfs_inobt_init_common into xfs_inobt_init_cursor Darrick J. Wong
@ 2024-05-22 3:03 ` Darrick J. Wong
2024-05-22 3:03 ` [PATCH 057/111] xfs: fold xfs_refcountbt_init_common into xfs_refcountbt_init_cursor Darrick J. Wong
` (55 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:03 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 6234dee7e6f58676379f3a2d8b0629a6e9a427fd
Just open code the two calls in the callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/libxfs_api_defs.h | 1 +
libxfs/xfs_ialloc_btree.c | 14 --------------
libxfs/xfs_ialloc_btree.h | 2 --
repair/agbtree.c | 8 +++++---
4 files changed, 6 insertions(+), 19 deletions(-)
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 9a2968906..2adf20ce8 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -147,6 +147,7 @@
#define xfs_initialize_perag_data libxfs_initialize_perag_data
#define xfs_init_local_fork libxfs_init_local_fork
+#define xfs_inobt_init_cursor libxfs_inobt_init_cursor
#define xfs_inobt_maxrecs libxfs_inobt_maxrecs
#define xfs_inobt_stage_cursor libxfs_inobt_stage_cursor
#define xfs_inode_from_disk libxfs_inode_from_disk
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index aa3f586da..6a34de282 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -488,20 +488,6 @@ xfs_inobt_init_cursor(
return cur;
}
-/* Create an inode btree cursor with a fake root for staging. */
-struct xfs_btree_cur *
-xfs_inobt_stage_cursor(
- struct xfs_perag *pag,
- struct xbtree_afakeroot *afake,
- xfs_btnum_t btnum)
-{
- struct xfs_btree_cur *cur;
-
- cur = xfs_inobt_init_cursor(pag, NULL, NULL, btnum);
- xfs_btree_stage_afakeroot(cur, afake);
- return cur;
-}
-
/*
* Install a new inobt btree root. Caller is responsible for invalidating
* and freeing the old btree blocks.
diff --git a/libxfs/xfs_ialloc_btree.h b/libxfs/xfs_ialloc_btree.h
index 3262c3fe5..40f0fc0e8 100644
--- a/libxfs/xfs_ialloc_btree.h
+++ b/libxfs/xfs_ialloc_btree.h
@@ -48,8 +48,6 @@ struct xfs_perag;
extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_perag *pag,
struct xfs_trans *tp, struct xfs_buf *agbp, xfs_btnum_t btnum);
-struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_perag *pag,
- struct xbtree_afakeroot *afake, xfs_btnum_t btnum);
extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int);
/* ir_holemask to inode allocation bitmap conversion */
diff --git a/repair/agbtree.c b/repair/agbtree.c
index d5fa4eafb..22e31c47a 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -524,8 +524,9 @@ init_ino_cursors(
fino_recs++;
}
- btr_ino->cur = libxfs_inobt_stage_cursor(pag, &btr_ino->newbt.afake,
+ btr_ino->cur = libxfs_inobt_init_cursor(pag, NULL, NULL,
XFS_BTNUM_INO);
+ libxfs_btree_stage_afakeroot(btr_ino->cur, &btr_ino->newbt.afake);
btr_ino->bload.get_records = get_inobt_records;
btr_ino->bload.claim_block = rebuild_claim_block;
@@ -544,8 +545,9 @@ _("Unable to compute inode btree geometry, error %d.\n"), error);
return;
init_rebuild(sc, &XFS_RMAP_OINFO_INOBT, est_agfreeblocks, btr_fino);
- btr_fino->cur = libxfs_inobt_stage_cursor(pag,
- &btr_fino->newbt.afake, XFS_BTNUM_FINO);
+ btr_fino->cur = libxfs_inobt_init_cursor(pag, NULL, NULL,
+ XFS_BTNUM_FINO);
+ libxfs_btree_stage_afakeroot(btr_fino->cur, &btr_fino->newbt.afake);
btr_fino->bload.get_records = get_inobt_records;
btr_fino->bload.claim_block = rebuild_claim_block;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 057/111] xfs: fold xfs_refcountbt_init_common into xfs_refcountbt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (55 preceding siblings ...)
2024-05-22 3:03 ` [PATCH 056/111] xfs: remove xfs_inobt_stage_cursor Darrick J. Wong
@ 2024-05-22 3:03 ` Darrick J. Wong
2024-05-22 3:03 ` [PATCH 058/111] xfs: remove xfs_refcountbt_stage_cursor Darrick J. Wong
` (54 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:03 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 4f2dc69e4bcb4b3bfaea0a96ac6424b0ed998172
Make the levels initialization in xfs_refcountbt_init_cursor conditional
and merge the two helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_refcount_btree.c | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 45bfb39e0..c1ae76949 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -345,12 +345,15 @@ const struct xfs_btree_ops xfs_refcountbt_ops = {
};
/*
- * Initialize a new refcount btree cursor.
+ * Create a new refcount btree cursor.
+ *
+ * For staging cursors tp and agbp are NULL.
*/
-static struct xfs_btree_cur *
-xfs_refcountbt_init_common(
+struct xfs_btree_cur *
+xfs_refcountbt_init_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
+ struct xfs_buf *agbp,
struct xfs_perag *pag)
{
struct xfs_btree_cur *cur;
@@ -363,23 +366,12 @@ xfs_refcountbt_init_common(
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_refc.nr_ops = 0;
cur->bc_refc.shape_changes = 0;
- return cur;
-}
-
-/* Create a btree cursor. */
-struct xfs_btree_cur *
-xfs_refcountbt_init_cursor(
- struct xfs_mount *mp,
- struct xfs_trans *tp,
- struct xfs_buf *agbp,
- struct xfs_perag *pag)
-{
- struct xfs_agf *agf = agbp->b_addr;
- struct xfs_btree_cur *cur;
-
- cur = xfs_refcountbt_init_common(mp, tp, pag);
- cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
cur->bc_ag.agbp = agbp;
+ if (agbp) {
+ struct xfs_agf *agf = agbp->b_addr;
+
+ cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
+ }
return cur;
}
@@ -392,7 +384,7 @@ xfs_refcountbt_stage_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_refcountbt_init_common(mp, NULL, pag);
+ cur = xfs_refcountbt_init_cursor(mp, NULL, NULL, pag);
xfs_btree_stage_afakeroot(cur, afake);
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 058/111] xfs: remove xfs_refcountbt_stage_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (56 preceding siblings ...)
2024-05-22 3:03 ` [PATCH 057/111] xfs: fold xfs_refcountbt_init_common into xfs_refcountbt_init_cursor Darrick J. Wong
@ 2024-05-22 3:03 ` Darrick J. Wong
2024-05-22 3:04 ` [PATCH 059/111] xfs: fold xfs_rmapbt_init_common into xfs_rmapbt_init_cursor Darrick J. Wong
` (53 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:03 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: a5c2194406f322e91b90fb813128541a9b4fed6a
Just open code the two calls in the callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_refcount_btree.c | 14 --------------
libxfs/xfs_refcount_btree.h | 2 --
repair/agbtree.c | 4 ++--
3 files changed, 2 insertions(+), 18 deletions(-)
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index c1ae76949..760163ca4 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -375,20 +375,6 @@ xfs_refcountbt_init_cursor(
return cur;
}
-/* Create a btree cursor with a fake root for staging. */
-struct xfs_btree_cur *
-xfs_refcountbt_stage_cursor(
- struct xfs_mount *mp,
- struct xbtree_afakeroot *afake,
- struct xfs_perag *pag)
-{
- struct xfs_btree_cur *cur;
-
- cur = xfs_refcountbt_init_cursor(mp, NULL, NULL, pag);
- xfs_btree_stage_afakeroot(cur, afake);
- return cur;
-}
-
/*
* Swap in the new btree root. Once we pass this point the newly rebuilt btree
* is in place and we have to kill off all the old btree blocks.
diff --git a/libxfs/xfs_refcount_btree.h b/libxfs/xfs_refcount_btree.h
index d66b37259..1e0ab25f6 100644
--- a/libxfs/xfs_refcount_btree.h
+++ b/libxfs/xfs_refcount_btree.h
@@ -48,8 +48,6 @@ struct xbtree_afakeroot;
extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_buf *agbp,
struct xfs_perag *pag);
-struct xfs_btree_cur *xfs_refcountbt_stage_cursor(struct xfs_mount *mp,
- struct xbtree_afakeroot *afake, struct xfs_perag *pag);
extern int xfs_refcountbt_maxrecs(int blocklen, bool leaf);
extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp);
diff --git a/repair/agbtree.c b/repair/agbtree.c
index 22e31c47a..395ced6cf 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -719,8 +719,8 @@ init_refc_cursor(
return;
init_rebuild(sc, &XFS_RMAP_OINFO_REFC, est_agfreeblocks, btr);
- btr->cur = libxfs_refcountbt_stage_cursor(sc->mp, &btr->newbt.afake,
- pag);
+ btr->cur = libxfs_refcountbt_init_cursor(sc->mp, NULL, NULL, pag);
+ libxfs_btree_stage_afakeroot(btr->cur, &btr->newbt.afake);
btr->bload.get_records = get_refcountbt_records;
btr->bload.claim_block = rebuild_claim_block;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 059/111] xfs: fold xfs_rmapbt_init_common into xfs_rmapbt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (57 preceding siblings ...)
2024-05-22 3:03 ` [PATCH 058/111] xfs: remove xfs_refcountbt_stage_cursor Darrick J. Wong
@ 2024-05-22 3:04 ` Darrick J. Wong
2024-05-22 3:04 ` [PATCH 060/111] xfs: remove xfs_rmapbt_stage_cursor Darrick J. Wong
` (52 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:04 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: c49a4b2f0ef0ac5daee5c2a3cfd2b537345c34eb
Make the levels initialization in xfs_rmapbt_init_cursor conditional
and merge the two helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_rmap_btree.c | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 52c820108..fabab29e2 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -500,10 +500,16 @@ const struct xfs_btree_ops xfs_rmapbt_ops = {
.keys_contiguous = xfs_rmapbt_keys_contiguous,
};
-static struct xfs_btree_cur *
-xfs_rmapbt_init_common(
+/*
+ * Create a new reverse mapping btree cursor.
+ *
+ * For staging cursors tp and agbp are NULL.
+ */
+struct xfs_btree_cur *
+xfs_rmapbt_init_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
+ struct xfs_buf *agbp,
struct xfs_perag *pag)
{
struct xfs_btree_cur *cur;
@@ -511,23 +517,12 @@ xfs_rmapbt_init_common(
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
- return cur;
-}
-
-/* Create a new reverse mapping btree cursor. */
-struct xfs_btree_cur *
-xfs_rmapbt_init_cursor(
- struct xfs_mount *mp,
- struct xfs_trans *tp,
- struct xfs_buf *agbp,
- struct xfs_perag *pag)
-{
- struct xfs_agf *agf = agbp->b_addr;
- struct xfs_btree_cur *cur;
-
- cur = xfs_rmapbt_init_common(mp, tp, pag);
- cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
cur->bc_ag.agbp = agbp;
+ if (agbp) {
+ struct xfs_agf *agf = agbp->b_addr;
+
+ cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
+ }
return cur;
}
@@ -540,7 +535,7 @@ xfs_rmapbt_stage_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_rmapbt_init_common(mp, NULL, pag);
+ cur = xfs_rmapbt_init_cursor(mp, NULL, NULL, pag);
xfs_btree_stage_afakeroot(cur, afake);
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 060/111] xfs: remove xfs_rmapbt_stage_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (58 preceding siblings ...)
2024-05-22 3:04 ` [PATCH 059/111] xfs: fold xfs_rmapbt_init_common into xfs_rmapbt_init_cursor Darrick J. Wong
@ 2024-05-22 3:04 ` Darrick J. Wong
2024-05-22 3:04 ` [PATCH 061/111] xfs: make full use of xfs_btree_stage_ifakeroot in xfs_bmbt_stage_cursor Darrick J. Wong
` (51 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:04 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 1317813290be04bc37196c4adf457712238c7faa
xfs_rmapbt_stage_cursor is currently unused, but future callers can
trivially open code the two calls.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_rmap_btree.c | 14 --------------
libxfs/xfs_rmap_btree.h | 2 --
repair/agbtree.c | 3 ++-
3 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index fabab29e2..5fad7f20b 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -526,20 +526,6 @@ xfs_rmapbt_init_cursor(
return cur;
}
-/* Create a new reverse mapping btree cursor with a fake root for staging. */
-struct xfs_btree_cur *
-xfs_rmapbt_stage_cursor(
- struct xfs_mount *mp,
- struct xbtree_afakeroot *afake,
- struct xfs_perag *pag)
-{
- struct xfs_btree_cur *cur;
-
- cur = xfs_rmapbt_init_cursor(mp, NULL, NULL, pag);
- xfs_btree_stage_afakeroot(cur, afake);
- return cur;
-}
-
/*
* Install a new reverse mapping btree root. Caller is responsible for
* invalidating and freeing the old btree blocks.
diff --git a/libxfs/xfs_rmap_btree.h b/libxfs/xfs_rmap_btree.h
index 3244715dd..27536d7e1 100644
--- a/libxfs/xfs_rmap_btree.h
+++ b/libxfs/xfs_rmap_btree.h
@@ -44,8 +44,6 @@ struct xbtree_afakeroot;
struct xfs_btree_cur *xfs_rmapbt_init_cursor(struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_buf *bp,
struct xfs_perag *pag);
-struct xfs_btree_cur *xfs_rmapbt_stage_cursor(struct xfs_mount *mp,
- struct xbtree_afakeroot *afake, struct xfs_perag *pag);
void xfs_rmapbt_commit_staged_btree(struct xfs_btree_cur *cur,
struct xfs_trans *tp, struct xfs_buf *agbp);
int xfs_rmapbt_maxrecs(int blocklen, int leaf);
diff --git a/repair/agbtree.c b/repair/agbtree.c
index 395ced6cf..ab97c1d79 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -637,7 +637,8 @@ init_rmapbt_cursor(
return;
init_rebuild(sc, &XFS_RMAP_OINFO_AG, est_agfreeblocks, btr);
- btr->cur = libxfs_rmapbt_stage_cursor(sc->mp, &btr->newbt.afake, pag);
+ btr->cur = libxfs_rmapbt_init_cursor(sc->mp, NULL, NULL, pag);
+ libxfs_btree_stage_afakeroot(btr->cur, &btr->newbt.afake);
btr->bload.get_records = get_rmapbt_records;
btr->bload.claim_block = rebuild_claim_block;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 061/111] xfs: make full use of xfs_btree_stage_ifakeroot in xfs_bmbt_stage_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (59 preceding siblings ...)
2024-05-22 3:04 ` [PATCH 060/111] xfs: remove xfs_rmapbt_stage_cursor Darrick J. Wong
@ 2024-05-22 3:04 ` Darrick J. Wong
2024-05-22 3:04 ` [PATCH 062/111] xfs: make staging file forks explicit Darrick J. Wong
` (50 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:04 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 579d7022d1afea8f4475d1750224ec0b652febee
Remove the duplicate cur->bc_nlevels assignment in xfs_bmbt_stage_cursor,
and move the cur->bc_ino.forksize assignment into
xfs_btree_stage_ifakeroot as it is part of setting up the fake btree
root.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap_btree.c | 2 --
libxfs/xfs_btree_staging.c | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 611f5ed96..dedc33dc5 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -611,8 +611,6 @@ xfs_bmbt_stage_cursor(
/* data fork always has larger maxheight */
cur = xfs_bmbt_init_common(mp, NULL, ip, XFS_DATA_FORK);
- cur->bc_nlevels = ifake->if_levels;
- cur->bc_ino.forksize = ifake->if_fork_size;
/* Don't let anyone think we're attached to the real fork yet. */
cur->bc_ino.whichfork = -1;
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 5a988a8bf..52410fe4f 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -133,6 +133,7 @@ xfs_btree_stage_ifakeroot(
cur->bc_ino.ifake = ifake;
cur->bc_nlevels = ifake->if_levels;
+ cur->bc_ino.forksize = ifake->if_fork_size;
cur->bc_flags |= XFS_BTREE_STAGING;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 062/111] xfs: make staging file forks explicit
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (60 preceding siblings ...)
2024-05-22 3:04 ` [PATCH 061/111] xfs: make full use of xfs_btree_stage_ifakeroot in xfs_bmbt_stage_cursor Darrick J. Wong
@ 2024-05-22 3:04 ` Darrick J. Wong
2024-05-22 3:05 ` [PATCH 063/111] xfs: fold xfs_bmbt_init_common into xfs_bmbt_init_cursor Darrick J. Wong
` (49 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:04 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 42e357c806c8c0ffb9c5c2faa4ad034bfe950d77
Don't open-code "-1" for whichfork when we're creating a staging btree
for a repair; let's define an actual symbol to make grepping and
understanding easier.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap_btree.c | 2 +-
libxfs/xfs_types.h | 8 +++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index dedc33dc5..6b377d129 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -613,7 +613,7 @@ xfs_bmbt_stage_cursor(
cur = xfs_bmbt_init_common(mp, NULL, ip, XFS_DATA_FORK);
/* Don't let anyone think we're attached to the real fork yet. */
- cur->bc_ino.whichfork = -1;
+ cur->bc_ino.whichfork = XFS_STAGING_FORK;
xfs_btree_stage_ifakeroot(cur, ifake);
return cur;
}
diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h
index 62e02d538..a1004fb3c 100644
--- a/libxfs/xfs_types.h
+++ b/libxfs/xfs_types.h
@@ -80,11 +80,13 @@ typedef void * xfs_failaddr_t;
/*
* Inode fork identifiers.
*/
-#define XFS_DATA_FORK 0
-#define XFS_ATTR_FORK 1
-#define XFS_COW_FORK 2
+#define XFS_STAGING_FORK (-1) /* fake fork for staging a btree */
+#define XFS_DATA_FORK (0)
+#define XFS_ATTR_FORK (1)
+#define XFS_COW_FORK (2)
#define XFS_WHICHFORK_STRINGS \
+ { XFS_STAGING_FORK, "staging" }, \
{ XFS_DATA_FORK, "data" }, \
{ XFS_ATTR_FORK, "attr" }, \
{ XFS_COW_FORK, "cow" }
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 063/111] xfs: fold xfs_bmbt_init_common into xfs_bmbt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (61 preceding siblings ...)
2024-05-22 3:04 ` [PATCH 062/111] xfs: make staging file forks explicit Darrick J. Wong
@ 2024-05-22 3:05 ` Darrick J. Wong
2024-05-22 3:05 ` [PATCH 064/111] xfs: remove xfs_bmbt_stage_cursor Darrick J. Wong
` (48 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:05 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 802f91f7b1d535ac975e2d696bf5b5dea82816e7
Make the levels initialization in xfs_bmbt_init_cursor conditional
and merge the two helpers.
This requires the fakeroot case to now pass a -1 whichfork directly
into xfs_bmbt_init_cursor, and some special casing for that, but
at least this scheme to deal with the fake btree root is handled and
documented in once place now.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: tidy up a multline ternary]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap_btree.c | 58 +++++++++++++++++++++++------------------------
1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 6b377d129..0afe541c5 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -543,44 +543,46 @@ const struct xfs_btree_ops xfs_bmbt_ops = {
.keys_contiguous = xfs_bmbt_keys_contiguous,
};
-static struct xfs_btree_cur *
-xfs_bmbt_init_common(
+/*
+ * Create a new bmap btree cursor.
+ *
+ * For staging cursors -1 in passed in whichfork.
+ */
+struct xfs_btree_cur *
+xfs_bmbt_init_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
struct xfs_inode *ip,
int whichfork)
{
struct xfs_btree_cur *cur;
+ unsigned int maxlevels;
ASSERT(whichfork != XFS_COW_FORK);
+ /*
+ * The Data fork always has larger maxlevel, so use that for staging
+ * cursors.
+ */
+ switch (whichfork) {
+ case XFS_STAGING_FORK:
+ maxlevels = mp->m_bm_maxlevels[XFS_DATA_FORK];
+ break;
+ default:
+ maxlevels = mp->m_bm_maxlevels[whichfork];
+ break;
+ }
cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP, &xfs_bmbt_ops,
- mp->m_bm_maxlevels[whichfork], xfs_bmbt_cur_cache);
-
+ maxlevels, xfs_bmbt_cur_cache);
cur->bc_ino.ip = ip;
- cur->bc_bmap.allocated = 0;
- return cur;
-}
-
-/*
- * Allocate a new bmap btree cursor.
- */
-struct xfs_btree_cur *
-xfs_bmbt_init_cursor(
- struct xfs_mount *mp,
- struct xfs_trans *tp,
- struct xfs_inode *ip,
- int whichfork)
-{
- struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
- struct xfs_btree_cur *cur;
-
- cur = xfs_bmbt_init_common(mp, tp, ip, whichfork);
-
- cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
- cur->bc_ino.forksize = xfs_inode_fork_size(ip, whichfork);
cur->bc_ino.whichfork = whichfork;
+ cur->bc_bmap.allocated = 0;
+ if (whichfork != XFS_STAGING_FORK) {
+ struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
+ cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
+ cur->bc_ino.forksize = xfs_inode_fork_size(ip, whichfork);
+ }
return cur;
}
@@ -609,11 +611,7 @@ xfs_bmbt_stage_cursor(
{
struct xfs_btree_cur *cur;
- /* data fork always has larger maxheight */
- cur = xfs_bmbt_init_common(mp, NULL, ip, XFS_DATA_FORK);
-
- /* Don't let anyone think we're attached to the real fork yet. */
- cur->bc_ino.whichfork = XFS_STAGING_FORK;
+ cur = xfs_bmbt_init_cursor(mp, NULL, ip, XFS_STAGING_FORK);
xfs_btree_stage_ifakeroot(cur, ifake);
return cur;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 064/111] xfs: remove xfs_bmbt_stage_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (62 preceding siblings ...)
2024-05-22 3:05 ` [PATCH 063/111] xfs: fold xfs_bmbt_init_common into xfs_bmbt_init_cursor Darrick J. Wong
@ 2024-05-22 3:05 ` Darrick J. Wong
2024-05-22 3:05 ` [PATCH 065/111] xfs: split the agf_roots and agf_levels arrays Darrick J. Wong
` (47 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:05 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 02f7ebf5f99c3776bbf048786885eeafeb2f21ca
Just open code the two calls in the callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
db/bmap_inflate.c | 8 ++++++--
libxfs/libxfs_api_defs.h | 2 ++
libxfs/xfs_bmap_btree.c | 19 -------------------
libxfs/xfs_bmap_btree.h | 2 --
repair/bmap_repair.c | 4 +++-
5 files changed, 11 insertions(+), 24 deletions(-)
diff --git a/db/bmap_inflate.c b/db/bmap_inflate.c
index 33b0c954d..c85d5dc0d 100644
--- a/db/bmap_inflate.c
+++ b/db/bmap_inflate.c
@@ -351,7 +351,9 @@ build_new_datafork(
/* Set up staging for the new bmbt */
ifake.if_fork = kmem_cache_zalloc(xfs_ifork_cache, 0);
ifake.if_fork_size = xfs_inode_fork_size(ip, XFS_DATA_FORK);
- bmap_cur = libxfs_bmbt_stage_cursor(ip->i_mount, ip, &ifake);
+ bmap_cur = libxfs_bmbt_init_cursor(ip->i_mount, NULL, ip,
+ XFS_STAGING_FORK);
+ libxfs_btree_stage_ifakeroot(bmap_cur, &ifake);
/*
* Figure out the size and format of the new fork, then fill it with
@@ -405,7 +407,9 @@ estimate_size(
ifake.if_fork = kmem_cache_zalloc(xfs_ifork_cache, 0);
ifake.if_fork_size = xfs_inode_fork_size(ip, XFS_DATA_FORK);
- bmap_cur = libxfs_bmbt_stage_cursor(ip->i_mount, ip, &ifake);
+ bmap_cur = libxfs_bmbt_init_cursor(ip->i_mount, NULL, ip,
+ XFS_STAGING_FORK);
+ libxfs_btree_stage_ifakeroot(bmap_cur, &ifake);
error = -libxfs_btree_bload_compute_geometry(bmap_cur, &bmap_bload,
nextents);
libxfs_btree_del_cursor(bmap_cur, error);
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 2adf20ce8..b0f9d9edb 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -54,6 +54,7 @@
#define xfs_bmbt_commit_staged_btree libxfs_bmbt_commit_staged_btree
#define xfs_bmbt_disk_get_startoff libxfs_bmbt_disk_get_startoff
#define xfs_bmbt_disk_set_all libxfs_bmbt_disk_set_all
+#define xfs_bmbt_init_cursor libxfs_bmbt_init_cursor
#define xfs_bmbt_maxlevels_ondisk libxfs_bmbt_maxlevels_ondisk
#define xfs_bmbt_maxrecs libxfs_bmbt_maxrecs
#define xfs_bmbt_stage_cursor libxfs_bmbt_stage_cursor
@@ -65,6 +66,7 @@
#define xfs_btree_init_block libxfs_btree_init_block
#define xfs_btree_rec_addr libxfs_btree_rec_addr
#define xfs_btree_stage_afakeroot libxfs_btree_stage_afakeroot
+#define xfs_btree_stage_ifakeroot libxfs_btree_stage_ifakeroot
#define xfs_buf_delwri_submit libxfs_buf_delwri_submit
#define xfs_buf_get libxfs_buf_get
#define xfs_buf_get_uncached libxfs_buf_get_uncached
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 0afe541c5..828dfb7d4 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -597,25 +597,6 @@ xfs_bmbt_block_maxrecs(
return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t));
}
-/*
- * Allocate a new bmap btree cursor for reloading an inode block mapping data
- * structure. Note that callers can use the staged cursor to reload extents
- * format inode forks if they rebuild the iext tree and commit the staged
- * cursor immediately.
- */
-struct xfs_btree_cur *
-xfs_bmbt_stage_cursor(
- struct xfs_mount *mp,
- struct xfs_inode *ip,
- struct xbtree_ifakeroot *ifake)
-{
- struct xfs_btree_cur *cur;
-
- cur = xfs_bmbt_init_cursor(mp, NULL, ip, XFS_STAGING_FORK);
- xfs_btree_stage_ifakeroot(cur, ifake);
- return cur;
-}
-
/*
* Swap in the new inode fork root. Once we pass this point the newly rebuilt
* mappings are in place and we have to kill off any old btree blocks.
diff --git a/libxfs/xfs_bmap_btree.h b/libxfs/xfs_bmap_btree.h
index e93aa42e2..de1b73f12 100644
--- a/libxfs/xfs_bmap_btree.h
+++ b/libxfs/xfs_bmap_btree.h
@@ -107,8 +107,6 @@ extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip,
extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *,
struct xfs_trans *, struct xfs_inode *, int);
-struct xfs_btree_cur *xfs_bmbt_stage_cursor(struct xfs_mount *mp,
- struct xfs_inode *ip, struct xbtree_ifakeroot *ifake);
void xfs_bmbt_commit_staged_btree(struct xfs_btree_cur *cur,
struct xfs_trans *tp, int whichfork);
diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
index 1dbcafb22..845584f18 100644
--- a/repair/bmap_repair.c
+++ b/repair/bmap_repair.c
@@ -475,7 +475,9 @@ xrep_bmap_build_new_fork(
*/
libxfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork);
bulkload_init_inode(&rb->new_fork_info, sc, rb->whichfork, &oinfo);
- bmap_cur = libxfs_bmbt_stage_cursor(sc->mp, sc->ip, ifake);
+ bmap_cur = libxfs_bmbt_init_cursor(sc->mp, NULL, sc->ip,
+ XFS_STAGING_FORK);
+ libxfs_btree_stage_ifakeroot(bmap_cur, ifake);
/*
* Figure out the size and format of the new fork, then fill it with
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 065/111] xfs: split the agf_roots and agf_levels arrays
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (63 preceding siblings ...)
2024-05-22 3:05 ` [PATCH 064/111] xfs: remove xfs_bmbt_stage_cursor Darrick J. Wong
@ 2024-05-22 3:05 ` Darrick J. Wong
2024-05-22 3:05 ` [PATCH 066/111] xfs: add a name field to struct xfs_btree_ops Darrick J. Wong
` (46 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:05 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: e45ea3645178c6db91aef4314945b05e4c6ee1fc
Using arrays of largely unrelated fields that use the btree number
as index is not very robust. Split the arrays into three separate
fields instead.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
copy/xfs_copy.c | 4 ++--
db/agf.c | 28 +++++--------------------
db/check.c | 14 ++++++------
db/freesp.c | 8 ++++---
db/metadump.c | 12 +++++------
libxfs/xfs_ag.c | 13 +++++-------
libxfs/xfs_ag.h | 8 ++++---
libxfs/xfs_alloc.c | 49 +++++++++++++++++--------------------------
libxfs/xfs_alloc_btree.c | 52 +++++++++++++++++++++++++++++++---------------
libxfs/xfs_format.h | 21 +++++++++----------
libxfs/xfs_rmap_btree.c | 17 +++++++--------
logprint/log_misc.c | 8 ++++---
logprint/log_print_all.c | 8 ++++---
repair/phase5.c | 24 +++++++++++----------
repair/scan.c | 16 +++++++-------
15 files changed, 136 insertions(+), 146 deletions(-)
diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
index 98a578a01..07957e007 100644
--- a/copy/xfs_copy.c
+++ b/copy/xfs_copy.c
@@ -1016,10 +1016,10 @@ main(int argc, char **argv)
/* traverse btree until we get to the leftmost leaf node */
- bno = be32_to_cpu(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi]);
+ bno = be32_to_cpu(ag_hdr.xfs_agf->agf_bno_root);
current_level = 0;
btree_levels = be32_to_cpu(ag_hdr.xfs_agf->
- agf_levels[XFS_BTNUM_BNOi]);
+ agf_bno_level);
ag_end = XFS_AGB_TO_DADDR(mp, agno,
be32_to_cpu(ag_hdr.xfs_agf->agf_length) - 1)
diff --git a/db/agf.c b/db/agf.c
index 8a6e2824d..5d465f5d2 100644
--- a/db/agf.c
+++ b/db/agf.c
@@ -35,31 +35,15 @@ const field_t agf_flds[] = {
{ "versionnum", FLDT_UINT32D, OI(OFF(versionnum)), C1, 0, TYP_NONE },
{ "seqno", FLDT_AGNUMBER, OI(OFF(seqno)), C1, 0, TYP_NONE },
{ "length", FLDT_AGBLOCK, OI(OFF(length)), C1, 0, TYP_NONE },
- { "roots", FLDT_AGBLOCK, OI(OFF(roots)), CI(XFS_BTNUM_AGF),
- FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
- { "bnoroot", FLDT_AGBLOCK,
- OI(OFF(roots) + XFS_BTNUM_BNO * SZ(roots[XFS_BTNUM_BNO])), C1, 0,
- TYP_BNOBT },
- { "cntroot", FLDT_AGBLOCK,
- OI(OFF(roots) + XFS_BTNUM_CNT * SZ(roots[XFS_BTNUM_CNT])), C1, 0,
- TYP_CNTBT },
- { "rmaproot", FLDT_AGBLOCKNZ,
- OI(OFF(roots) + XFS_BTNUM_RMAP * SZ(roots[XFS_BTNUM_RMAP])), C1, 0,
- TYP_RMAPBT },
+ { "bnoroot", FLDT_AGBLOCK, OI(OFF(bno_root)), C1, 0, TYP_BNOBT },
+ { "cntroot", FLDT_AGBLOCK, OI(OFF(cnt_root)), C1, 0, TYP_CNTBT },
+ { "rmaproot", FLDT_AGBLOCKNZ, OI(OFF(rmap_root)), C1, 0, TYP_RMAPBT },
{ "refcntroot", FLDT_AGBLOCKNZ,
OI(OFF(refcount_root)), C1, 0,
TYP_REFCBT },
- { "levels", FLDT_UINT32D, OI(OFF(levels)), CI(XFS_BTNUM_AGF),
- FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
- { "bnolevel", FLDT_UINT32D,
- OI(OFF(levels) + XFS_BTNUM_BNO * SZ(levels[XFS_BTNUM_BNO])), C1, 0,
- TYP_NONE },
- { "cntlevel", FLDT_UINT32D,
- OI(OFF(levels) + XFS_BTNUM_CNT * SZ(levels[XFS_BTNUM_CNT])), C1, 0,
- TYP_NONE },
- { "rmaplevel", FLDT_UINT32D,
- OI(OFF(levels) + XFS_BTNUM_RMAP * SZ(levels[XFS_BTNUM_RMAP])), C1, 0,
- TYP_NONE },
+ { "bnolevel", FLDT_UINT32D, OI(OFF(bno_level)), C1, 0, TYP_NONE },
+ { "cntlevel", FLDT_UINT32D, OI(OFF(cnt_level)), C1, 0, TYP_NONE },
+ { "rmaplevel", FLDT_UINT32D, OI(OFF(rmap_level)), C1, 0, TYP_NONE },
{ "refcntlevel", FLDT_UINT32D,
OI(OFF(refcount_level)), C1, 0,
TYP_NONE },
diff --git a/db/check.c b/db/check.c
index 0a53ab7df..bceaf318d 100644
--- a/db/check.c
+++ b/db/check.c
@@ -4095,18 +4095,18 @@ scan_ag(
scan_freelist(agf);
fdblocks--;
scan_sbtree(agf,
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
+ be32_to_cpu(agf->agf_bno_root),
+ be32_to_cpu(agf->agf_bno_level),
1, scanfunc_bno, TYP_BNOBT);
fdblocks--;
scan_sbtree(agf,
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
+ be32_to_cpu(agf->agf_cnt_root),
+ be32_to_cpu(agf->agf_cnt_level),
1, scanfunc_cnt, TYP_CNTBT);
- if (agf->agf_roots[XFS_BTNUM_RMAP]) {
+ if (agf->agf_rmap_root) {
scan_sbtree(agf,
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]),
+ be32_to_cpu(agf->agf_rmap_root),
+ be32_to_cpu(agf->agf_rmap_level),
1, scanfunc_rmap, TYP_RMAPBT);
}
if (agf->agf_refcount_root) {
diff --git a/db/freesp.c b/db/freesp.c
index 6f2346665..883741e66 100644
--- a/db/freesp.c
+++ b/db/freesp.c
@@ -209,12 +209,12 @@ scan_ag(
agf = iocur_top->data;
scan_freelist(agf);
if (countflag)
- scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]),
- TYP_CNTBT, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
+ scan_sbtree(agf, be32_to_cpu(agf->agf_cnt_root),
+ TYP_CNTBT, be32_to_cpu(agf->agf_cnt_level),
scanfunc_cnt);
else
- scan_sbtree(agf, be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]),
- TYP_BNOBT, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
+ scan_sbtree(agf, be32_to_cpu(agf->agf_bno_root),
+ TYP_BNOBT, be32_to_cpu(agf->agf_bno_level),
scanfunc_bno);
pop_cur();
}
diff --git a/db/metadump.c b/db/metadump.c
index 536d089fb..a656ef574 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -460,8 +460,8 @@ copy_free_bno_btree(
xfs_agblock_t root;
int levels;
- root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
- levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
+ root = be32_to_cpu(agf->agf_bno_root);
+ levels = be32_to_cpu(agf->agf_bno_level);
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
@@ -488,8 +488,8 @@ copy_free_cnt_btree(
xfs_agblock_t root;
int levels;
- root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
- levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
+ root = be32_to_cpu(agf->agf_cnt_root);
+ levels = be32_to_cpu(agf->agf_cnt_level);
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
@@ -560,8 +560,8 @@ copy_rmap_btree(
if (!xfs_has_rmapbt(mp))
return 1;
- root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
- levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
+ root = be32_to_cpu(agf->agf_rmap_root);
+ levels = be32_to_cpu(agf->agf_rmap_level);
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index cdca7f247..389a8288e 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -667,14 +667,13 @@ xfs_agfblock_init(
agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
agf->agf_seqno = cpu_to_be32(id->agno);
agf->agf_length = cpu_to_be32(id->agsize);
- agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
- agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
- agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
- agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
+ agf->agf_bno_root = cpu_to_be32(XFS_BNO_BLOCK(mp));
+ agf->agf_cnt_root = cpu_to_be32(XFS_CNT_BLOCK(mp));
+ agf->agf_bno_level = cpu_to_be32(1);
+ agf->agf_cnt_level = cpu_to_be32(1);
if (xfs_has_rmapbt(mp)) {
- agf->agf_roots[XFS_BTNUM_RMAPi] =
- cpu_to_be32(XFS_RMAP_BLOCK(mp));
- agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
+ agf->agf_rmap_root = cpu_to_be32(XFS_RMAP_BLOCK(mp));
+ agf->agf_rmap_level = cpu_to_be32(1);
agf->agf_rmap_blocks = cpu_to_be32(1);
}
diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h
index 77c0fa2bb..19eddba09 100644
--- a/libxfs/xfs_ag.h
+++ b/libxfs/xfs_ag.h
@@ -36,8 +36,9 @@ struct xfs_perag {
atomic_t pag_active_ref; /* active reference count */
wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */
unsigned long pag_opstate;
- uint8_t pagf_levels[XFS_BTNUM_AGF];
- /* # of levels in bno & cnt btree */
+ uint8_t pagf_bno_level; /* # of levels in bno btree */
+ uint8_t pagf_cnt_level; /* # of levels in cnt btree */
+ uint8_t pagf_rmap_level;/* # of levels in rmap btree */
uint32_t pagf_flcount; /* count of blocks in freelist */
xfs_extlen_t pagf_freeblks; /* total free blocks */
xfs_extlen_t pagf_longest; /* longest free space */
@@ -86,7 +87,8 @@ struct xfs_perag {
* Alternate btree heights so that online repair won't trip the write
* verifiers while rebuilding the AG btrees.
*/
- uint8_t pagf_repair_levels[XFS_BTNUM_AGF];
+ uint8_t pagf_repair_bno_level;
+ uint8_t pagf_repair_cnt_level;
uint8_t pagf_repair_refcount_level;
#endif
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index e5ae53948..1fdd7d44c 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -2331,8 +2331,9 @@ xfs_alloc_min_freelist(
struct xfs_perag *pag)
{
/* AG btrees have at least 1 level. */
- static const uint8_t fake_levels[XFS_BTNUM_AGF] = {1, 1, 1};
- const uint8_t *levels = pag ? pag->pagf_levels : fake_levels;
+ const unsigned int bno_level = pag ? pag->pagf_bno_level : 1;
+ const unsigned int cnt_level = pag ? pag->pagf_cnt_level : 1;
+ const unsigned int rmap_level = pag ? pag->pagf_rmap_level : 1;
unsigned int min_free;
ASSERT(mp->m_alloc_maxlevels > 0);
@@ -2359,16 +2360,12 @@ xfs_alloc_min_freelist(
*/
/* space needed by-bno freespace btree */
- min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
- mp->m_alloc_maxlevels) * 2 - 2;
+ min_free = min(bno_level + 1, mp->m_alloc_maxlevels) * 2 - 2;
/* space needed by-size freespace btree */
- min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
- mp->m_alloc_maxlevels) * 2 - 2;
+ min_free += min(cnt_level + 1, mp->m_alloc_maxlevels) * 2 - 2;
/* space needed reverse mapping used space btree */
if (xfs_has_rmapbt(mp))
- min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
- mp->m_rmap_maxlevels) * 2 - 2;
-
+ min_free += min(rmap_level + 1, mp->m_rmap_maxlevels) * 2 - 2;
return min_free;
}
@@ -3052,8 +3049,8 @@ xfs_alloc_log_agf(
offsetof(xfs_agf_t, agf_versionnum),
offsetof(xfs_agf_t, agf_seqno),
offsetof(xfs_agf_t, agf_length),
- offsetof(xfs_agf_t, agf_roots[0]),
- offsetof(xfs_agf_t, agf_levels[0]),
+ offsetof(xfs_agf_t, agf_bno_root), /* also cnt/rmap root */
+ offsetof(xfs_agf_t, agf_bno_level), /* also cnt/rmap levels */
offsetof(xfs_agf_t, agf_flfirst),
offsetof(xfs_agf_t, agf_fllast),
offsetof(xfs_agf_t, agf_flcount),
@@ -3232,12 +3229,10 @@ xfs_agf_verify(
be32_to_cpu(agf->agf_freeblks) > agf_length)
return __this_address;
- if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) >
- mp->m_alloc_maxlevels ||
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) >
- mp->m_alloc_maxlevels)
+ if (be32_to_cpu(agf->agf_bno_level) < 1 ||
+ be32_to_cpu(agf->agf_cnt_level) < 1 ||
+ be32_to_cpu(agf->agf_bno_level) > mp->m_alloc_maxlevels ||
+ be32_to_cpu(agf->agf_cnt_level) > mp->m_alloc_maxlevels)
return __this_address;
if (xfs_has_lazysbcount(mp) &&
@@ -3248,9 +3243,8 @@ xfs_agf_verify(
if (be32_to_cpu(agf->agf_rmap_blocks) > agf_length)
return __this_address;
- if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) >
- mp->m_rmap_maxlevels)
+ if (be32_to_cpu(agf->agf_rmap_level) < 1 ||
+ be32_to_cpu(agf->agf_rmap_level) > mp->m_rmap_maxlevels)
return __this_address;
}
@@ -3376,12 +3370,9 @@ xfs_alloc_read_agf(
pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
pag->pagf_longest = be32_to_cpu(agf->agf_longest);
- pag->pagf_levels[XFS_BTNUM_BNOi] =
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
- pag->pagf_levels[XFS_BTNUM_CNTi] =
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
- pag->pagf_levels[XFS_BTNUM_RMAPi] =
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
+ pag->pagf_bno_level = be32_to_cpu(agf->agf_bno_level);
+ pag->pagf_cnt_level = be32_to_cpu(agf->agf_cnt_level);
+ pag->pagf_rmap_level = be32_to_cpu(agf->agf_rmap_level);
pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
if (xfs_agfl_needs_reset(pag->pag_mount, agf))
set_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate);
@@ -3410,10 +3401,8 @@ xfs_alloc_read_agf(
ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
- ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
- ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
+ ASSERT(pag->pagf_bno_level == be32_to_cpu(agf->agf_bno_level));
+ ASSERT(pag->pagf_cnt_level == be32_to_cpu(agf->agf_cnt_level));
}
#endif
if (agfbpp)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index bd7878b68..dd9584269 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -36,13 +36,18 @@ xfs_allocbt_set_root(
{
struct xfs_buf *agbp = cur->bc_ag.agbp;
struct xfs_agf *agf = agbp->b_addr;
- int btnum = cur->bc_btnum;
ASSERT(ptr->s != 0);
- agf->agf_roots[btnum] = ptr->s;
- be32_add_cpu(&agf->agf_levels[btnum], inc);
- cur->bc_ag.pag->pagf_levels[btnum] += inc;
+ if (cur->bc_btnum == XFS_BTNUM_BNO) {
+ agf->agf_bno_root = ptr->s;
+ be32_add_cpu(&agf->agf_bno_level, inc);
+ cur->bc_ag.pag->pagf_bno_level += inc;
+ } else {
+ agf->agf_cnt_root = ptr->s;
+ be32_add_cpu(&agf->agf_cnt_level, inc);
+ cur->bc_ag.pag->pagf_cnt_level += inc;
+ }
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
}
@@ -224,7 +229,10 @@ xfs_allocbt_init_ptr_from_cur(
ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));
- ptr->s = agf->agf_roots[cur->bc_btnum];
+ if (cur->bc_btnum == XFS_BTNUM_BNO)
+ ptr->s = agf->agf_bno_root;
+ else
+ ptr->s = agf->agf_cnt_root;
}
STATIC int64_t
@@ -297,7 +305,6 @@ xfs_allocbt_verify(
struct xfs_perag *pag = bp->b_pag;
xfs_failaddr_t fa;
unsigned int level;
- xfs_btnum_t btnum = XFS_BTNUM_BNOi;
if (!xfs_verify_magic(bp, block->bb_magic))
return __this_address;
@@ -318,21 +325,27 @@ xfs_allocbt_verify(
* against.
*/
level = be16_to_cpu(block->bb_level);
- if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC))
- btnum = XFS_BTNUM_CNTi;
if (pag && xfs_perag_initialised_agf(pag)) {
- unsigned int maxlevel = pag->pagf_levels[btnum];
+ unsigned int maxlevel, repair_maxlevel = 0;
-#ifdef CONFIG_XFS_ONLINE_REPAIR
/*
* Online repair could be rewriting the free space btrees, so
* we'll validate against the larger of either tree while this
* is going on.
*/
- maxlevel = max_t(unsigned int, maxlevel,
- pag->pagf_repair_levels[btnum]);
+ if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) {
+ maxlevel = pag->pagf_cnt_level;
+#ifdef CONFIG_XFS_ONLINE_REPAIR
+ repair_maxlevel = pag->pagf_repair_cnt_level;
#endif
- if (level >= maxlevel)
+ } else {
+ maxlevel = pag->pagf_bno_level;
+#ifdef CONFIG_XFS_ONLINE_REPAIR
+ repair_maxlevel = pag->pagf_repair_bno_level;
+#endif
+ }
+
+ if (level >= max(maxlevel, repair_maxlevel))
return __this_address;
} else if (level >= mp->m_alloc_maxlevels)
return __this_address;
@@ -540,8 +553,8 @@ xfs_allocbt_init_cursor(
struct xfs_agf *agf = agbp->b_addr;
cur->bc_nlevels = (btnum == XFS_BTNUM_BNO) ?
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) :
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
+ be32_to_cpu(agf->agf_bno_level) :
+ be32_to_cpu(agf->agf_cnt_level);
}
return cur;
}
@@ -561,8 +574,13 @@ xfs_allocbt_commit_staged_btree(
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
- agf->agf_roots[cur->bc_btnum] = cpu_to_be32(afake->af_root);
- agf->agf_levels[cur->bc_btnum] = cpu_to_be32(afake->af_levels);
+ if (cur->bc_btnum == XFS_BTNUM_BNO) {
+ agf->agf_bno_root = cpu_to_be32(afake->af_root);
+ agf->agf_bno_level = cpu_to_be32(afake->af_levels);
+ } else {
+ agf->agf_cnt_root = cpu_to_be32(afake->af_root);
+ agf->agf_cnt_level = cpu_to_be32(afake->af_levels);
+ }
xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
xfs_btree_commit_afakeroot(cur, tp, agbp);
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 382ab1e71..2b2f9050f 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -477,15 +477,9 @@ xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
#define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION)
/*
- * Btree number 0 is bno, 1 is cnt, 2 is rmap. This value gives the size of the
- * arrays below.
- */
-#define XFS_BTNUM_AGF ((int)XFS_BTNUM_RMAPi + 1)
-
-/*
- * The second word of agf_levels in the first a.g. overlaps the EFS
- * superblock's magic number. Since the magic numbers valid for EFS
- * are > 64k, our value cannot be confused for an EFS superblock's.
+ * agf_cnt_level in the first AGF overlaps the EFS superblock's magic number.
+ * Since the magic numbers valid for EFS are > 64k, our value cannot be confused
+ * for an EFS superblock.
*/
typedef struct xfs_agf {
@@ -499,8 +493,13 @@ typedef struct xfs_agf {
/*
* Freespace and rmap information
*/
- __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */
- __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */
+ __be32 agf_bno_root; /* bnobt root block */
+ __be32 agf_cnt_root; /* cntbt root block */
+ __be32 agf_rmap_root; /* rmapbt root block */
+
+ __be32 agf_bno_level; /* bnobt btree levels */
+ __be32 agf_cnt_level; /* cntbt btree levels */
+ __be32 agf_rmap_level; /* rmapbt btree levels */
__be32 agf_flfirst; /* first freelist block's index */
__be32 agf_fllast; /* last freelist block's index */
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 5fad7f20b..82052ce78 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -63,13 +63,12 @@ xfs_rmapbt_set_root(
{
struct xfs_buf *agbp = cur->bc_ag.agbp;
struct xfs_agf *agf = agbp->b_addr;
- int btnum = cur->bc_btnum;
ASSERT(ptr->s != 0);
- agf->agf_roots[btnum] = ptr->s;
- be32_add_cpu(&agf->agf_levels[btnum], inc);
- cur->bc_ag.pag->pagf_levels[btnum] += inc;
+ agf->agf_rmap_root = ptr->s;
+ be32_add_cpu(&agf->agf_rmap_level, inc);
+ cur->bc_ag.pag->pagf_rmap_level += inc;
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
}
@@ -220,7 +219,7 @@ xfs_rmapbt_init_ptr_from_cur(
ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));
- ptr->s = agf->agf_roots[cur->bc_btnum];
+ ptr->s = agf->agf_rmap_root;
}
/*
@@ -340,7 +339,7 @@ xfs_rmapbt_verify(
level = be16_to_cpu(block->bb_level);
if (pag && xfs_perag_initialised_agf(pag)) {
- if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi])
+ if (level >= pag->pagf_rmap_level)
return __this_address;
} else if (level >= mp->m_rmap_maxlevels)
return __this_address;
@@ -521,7 +520,7 @@ xfs_rmapbt_init_cursor(
if (agbp) {
struct xfs_agf *agf = agbp->b_addr;
- cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
+ cur->bc_nlevels = be32_to_cpu(agf->agf_rmap_level);
}
return cur;
}
@@ -541,8 +540,8 @@ xfs_rmapbt_commit_staged_btree(
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
- agf->agf_roots[cur->bc_btnum] = cpu_to_be32(afake->af_root);
- agf->agf_levels[cur->bc_btnum] = cpu_to_be32(afake->af_levels);
+ agf->agf_rmap_root = cpu_to_be32(afake->af_root);
+ agf->agf_rmap_level = cpu_to_be32(afake->af_levels);
agf->agf_rmap_blocks = cpu_to_be32(afake->af_blocks);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS |
XFS_AGF_RMAP_BLOCKS);
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index 836156e0d..9d3811340 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -378,11 +378,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops)
be32_to_cpu(agf->agf_seqno),
be32_to_cpu(agf->agf_length));
printf(_("root BNO: %d CNT: %d\n"),
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]),
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
+ be32_to_cpu(agf->agf_bno_root),
+ be32_to_cpu(agf->agf_cnt_root));
printf(_("level BNO: %d CNT: %d\n"),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
+ be32_to_cpu(agf->agf_bno_level),
+ be32_to_cpu(agf->agf_cnt_level));
printf(_("1st: %d last: %d cnt: %d "
"freeblks: %d longest: %d\n"),
be32_to_cpu(agf->agf_flfirst),
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index 8d3ede190..f436e1091 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -152,11 +152,11 @@ xlog_recover_print_buffer(
be32_to_cpu(agf->agf_seqno),
be32_to_cpu(agf->agf_length));
printf(_(" root BNO:%d CNT:%d\n"),
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]),
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
+ be32_to_cpu(agf->agf_bno_root),
+ be32_to_cpu(agf->agf_cnt_root));
printf(_(" level BNO:%d CNT:%d\n"),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]),
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
+ be32_to_cpu(agf->agf_bno_level),
+ be32_to_cpu(agf->agf_cnt_level));
printf(_(" 1st:%d last:%d cnt:%d "
"freeblks:%d longest:%d\n"),
be32_to_cpu(agf->agf_flfirst),
diff --git a/repair/phase5.c b/repair/phase5.c
index b0e208f95..6ae2ea575 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -255,20 +255,20 @@ build_agf_agfl(
agf->agf_length = cpu_to_be32(mp->m_sb.sb_dblocks -
(xfs_rfsblock_t) mp->m_sb.sb_agblocks * agno);
- agf->agf_roots[XFS_BTNUM_BNO] =
+ agf->agf_bno_root =
cpu_to_be32(btr_bno->newbt.afake.af_root);
- agf->agf_levels[XFS_BTNUM_BNO] =
+ agf->agf_bno_level =
cpu_to_be32(btr_bno->newbt.afake.af_levels);
- agf->agf_roots[XFS_BTNUM_CNT] =
+ agf->agf_cnt_root =
cpu_to_be32(btr_cnt->newbt.afake.af_root);
- agf->agf_levels[XFS_BTNUM_CNT] =
+ agf->agf_cnt_level =
cpu_to_be32(btr_cnt->newbt.afake.af_levels);
agf->agf_freeblks = cpu_to_be32(btr_bno->freeblks);
if (xfs_has_rmapbt(mp)) {
- agf->agf_roots[XFS_BTNUM_RMAP] =
+ agf->agf_rmap_root =
cpu_to_be32(btr_rmap->newbt.afake.af_root);
- agf->agf_levels[XFS_BTNUM_RMAP] =
+ agf->agf_rmap_level =
cpu_to_be32(btr_rmap->newbt.afake.af_levels);
agf->agf_rmap_blocks =
cpu_to_be32(btr_rmap->newbt.afake.af_blocks);
@@ -305,8 +305,8 @@ build_agf_agfl(
#ifdef XR_BLD_FREE_TRACE
fprintf(stderr, "bno root = %u, bcnt root = %u, indices = %u %u\n",
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]),
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]),
+ be32_to_cpu(agf->agf_bno_root),
+ be32_to_cpu(agf->agf_cnt_root),
XFS_BTNUM_BNO,
XFS_BTNUM_CNT);
#endif
@@ -367,12 +367,12 @@ build_agf_agfl(
agf->agf_longest = cpu_to_be32((ext_ptr != NULL) ?
ext_ptr->ex_blockcount : 0);
- ASSERT(be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]) !=
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
+ ASSERT(be32_to_cpu(agf->agf_bno_root) !=
+ be32_to_cpu(agf->agf_cnt_root));
ASSERT(be32_to_cpu(agf->agf_refcount_root) !=
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]));
+ be32_to_cpu(agf->agf_bno_root));
ASSERT(be32_to_cpu(agf->agf_refcount_root) !=
- be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
+ be32_to_cpu(agf->agf_cnt_root));
libxfs_buf_mark_dirty(agf_buf);
libxfs_buf_relse(agf_buf);
diff --git a/repair/scan.c b/repair/scan.c
index 0a77dd679..7e6d94cfa 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -2364,17 +2364,17 @@ validate_agf(
unsigned int levels;
struct xfs_perag *pag = libxfs_perag_get(mp, agno);
- levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
+ levels = be32_to_cpu(agf->agf_bno_level);
if (levels == 0 || levels > mp->m_alloc_maxlevels) {
do_warn(_("bad levels %u for btbno root, agno %d\n"),
levels, agno);
}
- bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
+ bno = be32_to_cpu(agf->agf_bno_root);
if (libxfs_verify_agbno(pag, bno)) {
magic = xfs_has_crc(mp) ? XFS_ABTB_CRC_MAGIC
: XFS_ABTB_MAGIC;
- scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
+ scan_sbtree(bno, be32_to_cpu(agf->agf_bno_level),
agno, 0, scan_allocbt, 1, magic, agcnts,
&xfs_bnobt_buf_ops);
} else {
@@ -2382,17 +2382,17 @@ validate_agf(
bno, agno);
}
- levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
+ levels = be32_to_cpu(agf->agf_cnt_level);
if (levels == 0 || levels > mp->m_alloc_maxlevels) {
do_warn(_("bad levels %u for btbcnt root, agno %d\n"),
levels, agno);
}
- bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
+ bno = be32_to_cpu(agf->agf_cnt_root);
if (libxfs_verify_agbno(pag, bno)) {
magic = xfs_has_crc(mp) ? XFS_ABTC_CRC_MAGIC
: XFS_ABTC_MAGIC;
- scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
+ scan_sbtree(bno, be32_to_cpu(agf->agf_cnt_level),
agno, 0, scan_allocbt, 1, magic, agcnts,
&xfs_cntbt_buf_ops);
} else {
@@ -2409,14 +2409,14 @@ validate_agf(
priv.last_rec.rm_owner = XFS_RMAP_OWN_UNKNOWN;
priv.nr_blocks = 0;
- levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
+ levels = be32_to_cpu(agf->agf_rmap_level);
if (levels == 0 || levels > mp->m_rmap_maxlevels) {
do_warn(_("bad levels %u for rmapbt root, agno %d\n"),
levels, agno);
rmap_avoid_check();
}
- bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
+ bno = be32_to_cpu(agf->agf_rmap_root);
if (libxfs_verify_agbno(pag, bno)) {
scan_sbtree(bno, levels, agno, 0, scan_rmapbt, 1,
XFS_RMAP_CRC_MAGIC, &priv,
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 066/111] xfs: add a name field to struct xfs_btree_ops
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (64 preceding siblings ...)
2024-05-22 3:05 ` [PATCH 065/111] xfs: split the agf_roots and agf_levels arrays Darrick J. Wong
@ 2024-05-22 3:05 ` Darrick J. Wong
2024-05-22 3:06 ` [PATCH 067/111] xfs: add a sick_mask " Darrick J. Wong
` (45 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:05 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 77953b97bb19dc031673d055c811a5ba7df92307
The btnum in struct xfs_btree_ops is often used for printing a symbolic
name for the btree. Add a name field to the ops structure and use that
directly.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
include/xfs_trace.h | 2 +-
libxfs/xfs_alloc.c | 8 +++-----
libxfs/xfs_alloc_btree.c | 2 ++
libxfs/xfs_bmap_btree.c | 1 +
libxfs/xfs_btree.c | 8 ++++----
libxfs/xfs_btree.h | 2 ++
libxfs/xfs_ialloc.c | 5 ++---
libxfs/xfs_ialloc_btree.c | 2 ++
libxfs/xfs_refcount_btree.c | 1 +
libxfs/xfs_rmap_btree.c | 1 +
libxfs/xfs_types.h | 9 ---------
11 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index e7cbd0d9d..df25dc2a9 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -8,7 +8,7 @@
#define trace_xfs_agfl_reset(a,b,c,d) ((void) 0)
#define trace_xfs_agfl_free_defer(a,b,c,d,e) ((void) 0)
-#define trace_xfs_alloc_cur_check(a,b,c,d,e,f) ((void) 0)
+#define trace_xfs_alloc_cur_check(...) ((void) 0)
#define trace_xfs_alloc_cur(a) ((void) 0)
#define trace_xfs_alloc_cur_left(a) ((void) 0)
#define trace_xfs_alloc_cur_lookup(a) ((void) 0)
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 1fdd7d44c..b7690dfde 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -269,9 +269,8 @@ xfs_alloc_complain_bad_rec(
struct xfs_mount *mp = cur->bc_mp;
xfs_warn(mp,
- "%s Freespace BTree record corruption in AG %d detected at %pS!",
- cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size",
- cur->bc_ag.pag->pag_agno, fa);
+ "%sbt record corruption in AG %d detected at %pS!",
+ cur->bc_ops->name, cur->bc_ag.pag->pag_agno, fa);
xfs_warn(mp,
"start block 0x%x block count 0x%x", irec->ar_startblock,
irec->ar_blockcount);
@@ -992,8 +991,7 @@ xfs_alloc_cur_check(
out:
if (deactivate)
cur->bc_flags &= ~XFS_BTREE_ALLOCBT_ACTIVE;
- trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff,
- *new);
+ trace_xfs_alloc_cur_check(cur, bno, len, diff, *new);
return 0;
}
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index dd9584269..d9e9ba53a 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -466,6 +466,7 @@ xfs_allocbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_bnobt_ops = {
+ .name = "bno",
.type = XFS_BTREE_TYPE_AG,
.rec_len = sizeof(xfs_alloc_rec_t),
@@ -495,6 +496,7 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
};
const struct xfs_btree_ops xfs_cntbt_ops = {
+ .name = "cnt",
.type = XFS_BTREE_TYPE_AG,
.geom_flags = XFS_BTGEO_LASTREC_UPDATE,
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 828dfb7d4..12b94c74e 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -516,6 +516,7 @@ xfs_bmbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_bmbt_ops = {
+ .name = "bmap",
.type = XFS_BTREE_TYPE_INODE,
.rec_len = sizeof(xfs_bmbt_rec_t),
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 42a1ed786..95f77fbe7 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -295,17 +295,17 @@ xfs_btree_check_ptr(
level))
return 0;
xfs_err(cur->bc_mp,
-"Inode %llu fork %d: Corrupt btree %d pointer at level %d index %d.",
+"Inode %llu fork %d: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ino.ip->i_ino,
- cur->bc_ino.whichfork, cur->bc_btnum,
+ cur->bc_ino.whichfork, cur->bc_ops->name,
level, index);
} else {
if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]),
level))
return 0;
xfs_err(cur->bc_mp,
-"AG %u: Corrupt btree %d pointer at level %d index %d.",
- cur->bc_ag.pag->pag_agno, cur->bc_btnum,
+"AG %u: Corrupt %sbt pointer at level %d index %d.",
+ cur->bc_ag.pag->pag_agno, cur->bc_ops->name,
level, index);
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 99194ae94..6bc609620 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -123,6 +123,8 @@ enum xfs_btree_type {
};
struct xfs_btree_ops {
+ const char *name;
+
/* Type of btree - AG-rooted or inode-rooted */
enum xfs_btree_type type;
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 21577a50f..94f4f8690 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -136,9 +136,8 @@ xfs_inobt_complain_bad_rec(
struct xfs_mount *mp = cur->bc_mp;
xfs_warn(mp,
- "%s Inode BTree record corruption in AG %d detected at %pS!",
- cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free",
- cur->bc_ag.pag->pag_agno, fa);
+ "%sbt record corruption in AG %d detected at %pS!",
+ cur->bc_ops->name, cur->bc_ag.pag->pag_agno, fa);
xfs_warn(mp,
"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x",
irec->ir_startino, irec->ir_count, irec->ir_freecount,
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 6a34de282..5e8a47563 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -398,6 +398,7 @@ xfs_inobt_keys_contiguous(
}
const struct xfs_btree_ops xfs_inobt_ops = {
+ .name = "ino",
.type = XFS_BTREE_TYPE_AG,
.rec_len = sizeof(xfs_inobt_rec_t),
@@ -426,6 +427,7 @@ const struct xfs_btree_ops xfs_inobt_ops = {
};
const struct xfs_btree_ops xfs_finobt_ops = {
+ .name = "fino",
.type = XFS_BTREE_TYPE_AG,
.rec_len = sizeof(xfs_inobt_rec_t),
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 760163ca4..397ce2131 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -317,6 +317,7 @@ xfs_refcountbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_refcountbt_ops = {
+ .name = "refcount",
.type = XFS_BTREE_TYPE_AG,
.rec_len = sizeof(struct xfs_refcount_rec),
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 82052ce78..5bf5340c8 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -470,6 +470,7 @@ xfs_rmapbt_keys_contiguous(
}
const struct xfs_btree_ops xfs_rmapbt_ops = {
+ .name = "rmap",
.type = XFS_BTREE_TYPE_AG,
.geom_flags = XFS_BTGEO_OVERLAPPING,
diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h
index a1004fb3c..f577247b7 100644
--- a/libxfs/xfs_types.h
+++ b/libxfs/xfs_types.h
@@ -125,15 +125,6 @@ typedef enum {
XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_REFCi, XFS_BTNUM_MAX
} xfs_btnum_t;
-#define XFS_BTNUM_STRINGS \
- { XFS_BTNUM_BNOi, "bnobt" }, \
- { XFS_BTNUM_CNTi, "cntbt" }, \
- { XFS_BTNUM_RMAPi, "rmapbt" }, \
- { XFS_BTNUM_BMAPi, "bmbt" }, \
- { XFS_BTNUM_INOi, "inobt" }, \
- { XFS_BTNUM_FINOi, "finobt" }, \
- { XFS_BTNUM_REFCi, "refcbt" }
-
struct xfs_name {
const unsigned char *name;
int len;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 067/111] xfs: add a sick_mask to struct xfs_btree_ops
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (65 preceding siblings ...)
2024-05-22 3:05 ` [PATCH 066/111] xfs: add a name field to struct xfs_btree_ops Darrick J. Wong
@ 2024-05-22 3:06 ` Darrick J. Wong
2024-05-22 3:06 ` [PATCH 068/111] xfs: split xfs_allocbt_init_cursor Darrick J. Wong
` (44 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:06 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 7f47734ad61af77a001b1e24691dcbfcb008c938
Clean up xfs_btree_mark_sick by adding a sick_mask to the btree-ops
for all AG-root btrees.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc_btree.c | 3 +++
libxfs/xfs_btree.h | 3 +++
libxfs/xfs_ialloc_btree.c | 3 +++
libxfs/xfs_refcount_btree.c | 2 ++
libxfs/xfs_rmap_btree.c | 2 ++
5 files changed, 13 insertions(+)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index d9e9ba53a..6ad44c146 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -17,6 +17,7 @@
#include "xfs_trace.h"
#include "xfs_trans.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
static struct kmem_cache *xfs_allocbt_cur_cache;
@@ -475,6 +476,7 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
.lru_refs = XFS_ALLOC_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_abtb_2),
+ .sick_mask = XFS_SICK_AG_BNOBT,
.dup_cursor = xfs_allocbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
@@ -506,6 +508,7 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
.lru_refs = XFS_ALLOC_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_abtc_2),
+ .sick_mask = XFS_SICK_AG_CNTBT,
.dup_cursor = xfs_allocbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 6bc609620..6e5fd0c06 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -142,6 +142,9 @@ struct xfs_btree_ops {
/* offset of btree stats array */
unsigned int statoff;
+ /* sick mask for health reporting (only for XFS_BTREE_TYPE_AG) */
+ unsigned int sick_mask;
+
/* cursor operations */
struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
void (*update_cursor)(struct xfs_btree_cur *src,
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 5e8a47563..08076ef12 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -20,6 +20,7 @@
#include "xfs_trans.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
static struct kmem_cache *xfs_inobt_cur_cache;
@@ -407,6 +408,7 @@ const struct xfs_btree_ops xfs_inobt_ops = {
.lru_refs = XFS_INO_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_ibt_2),
+ .sick_mask = XFS_SICK_AG_INOBT,
.dup_cursor = xfs_inobt_dup_cursor,
.set_root = xfs_inobt_set_root,
@@ -436,6 +438,7 @@ const struct xfs_btree_ops xfs_finobt_ops = {
.lru_refs = XFS_INO_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_fibt_2),
+ .sick_mask = XFS_SICK_AG_FINOBT,
.dup_cursor = xfs_inobt_dup_cursor,
.set_root = xfs_finobt_set_root,
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 397ce2131..31ef879ba 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -20,6 +20,7 @@
#include "xfs_bit.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
static struct kmem_cache *xfs_refcountbt_cur_cache;
@@ -326,6 +327,7 @@ const struct xfs_btree_ops xfs_refcountbt_ops = {
.lru_refs = XFS_REFC_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2),
+ .sick_mask = XFS_SICK_AG_REFCNTBT,
.dup_cursor = xfs_refcountbt_dup_cursor,
.set_root = xfs_refcountbt_set_root,
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 5bf5340c8..c7ca20043 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -19,6 +19,7 @@
#include "xfs_trace.h"
#include "xfs_ag.h"
#include "xfs_ag_resv.h"
+#include "xfs_health.h"
static struct kmem_cache *xfs_rmapbt_cur_cache;
@@ -481,6 +482,7 @@ const struct xfs_btree_ops xfs_rmapbt_ops = {
.lru_refs = XFS_RMAP_BTREE_REF,
.statoff = XFS_STATS_CALC_INDEX(xs_rmap_2),
+ .sick_mask = XFS_SICK_AG_RMAPBT,
.dup_cursor = xfs_rmapbt_dup_cursor,
.set_root = xfs_rmapbt_set_root,
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 068/111] xfs: split xfs_allocbt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (66 preceding siblings ...)
2024-05-22 3:06 ` [PATCH 067/111] xfs: add a sick_mask " Darrick J. Wong
@ 2024-05-22 3:06 ` Darrick J. Wong
2024-05-22 3:06 ` [PATCH 069/111] xfs: remove xfs_inobt_cur Darrick J. Wong
` (43 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:06 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 1c8b9fd278c08e16c27a41be484b77383738de1f
Split xfs_allocbt_init_cursor into separate routines for the by-bno
and by-cnt btrees to prepare for the removal of the xfs_btnum global
enumeration of btree types.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/libxfs_api_defs.h | 4 ++-
libxfs/xfs_alloc.c | 36 +++++++++++++--------------
libxfs/xfs_alloc_btree.c | 62 +++++++++++++++++++++++++++++++++-------------
libxfs/xfs_alloc_btree.h | 7 ++++-
repair/agbtree.c | 6 +---
5 files changed, 72 insertions(+), 43 deletions(-)
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index b0f9d9edb..8f4b98080 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -26,7 +26,6 @@
#define xfs_alloc_ag_max_usable libxfs_alloc_ag_max_usable
#define xfs_allocbt_calc_size libxfs_allocbt_calc_size
-#define xfs_allocbt_init_cursor libxfs_allocbt_init_cursor
#define xfs_allocbt_maxlevels_ondisk libxfs_allocbt_maxlevels_ondisk
#define xfs_allocbt_maxrecs libxfs_allocbt_maxrecs
#define xfs_allocbt_stage_cursor libxfs_allocbt_stage_cursor
@@ -60,6 +59,8 @@
#define xfs_bmbt_stage_cursor libxfs_bmbt_stage_cursor
#define xfs_bmdr_maxrecs libxfs_bmdr_maxrecs
+#define xfs_bnobt_init_cursor libxfs_bnobt_init_cursor
+
#define xfs_btree_bload libxfs_btree_bload
#define xfs_btree_bload_compute_geometry libxfs_btree_bload_compute_geometry
#define xfs_btree_del_cursor libxfs_btree_del_cursor
@@ -78,6 +79,7 @@
#define xfs_bunmapi libxfs_bunmapi
#define xfs_bwrite libxfs_bwrite
#define xfs_calc_dquots_per_chunk libxfs_calc_dquots_per_chunk
+#define xfs_cntbt_init_cursor libxfs_cntbt_init_cursor
#define xfs_compute_rextslog libxfs_compute_rextslog
#define xfs_da3_node_hdr_from_disk libxfs_da3_node_hdr_from_disk
#define xfs_da_get_buf libxfs_da_get_buf
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index b7690dfde..599271e5c 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -858,8 +858,8 @@ xfs_alloc_cur_setup(
* attempt a small allocation.
*/
if (!acur->cnt)
- acur->cnt = xfs_allocbt_init_cursor(args->mp, args->tp,
- args->agbp, args->pag, XFS_BTNUM_CNT);
+ acur->cnt = xfs_cntbt_init_cursor(args->mp, args->tp,
+ args->agbp, args->pag);
error = xfs_alloc_lookup_ge(acur->cnt, 0, args->maxlen, &i);
if (error)
return error;
@@ -868,11 +868,11 @@ xfs_alloc_cur_setup(
* Allocate the bnobt left and right search cursors.
*/
if (!acur->bnolt)
- acur->bnolt = xfs_allocbt_init_cursor(args->mp, args->tp,
- args->agbp, args->pag, XFS_BTNUM_BNO);
+ acur->bnolt = xfs_bnobt_init_cursor(args->mp, args->tp,
+ args->agbp, args->pag);
if (!acur->bnogt)
- acur->bnogt = xfs_allocbt_init_cursor(args->mp, args->tp,
- args->agbp, args->pag, XFS_BTNUM_BNO);
+ acur->bnogt = xfs_bnobt_init_cursor(args->mp, args->tp,
+ args->agbp, args->pag);
return i == 1 ? 0 : -ENOSPC;
}
@@ -1230,8 +1230,8 @@ xfs_alloc_ag_vextent_exact(
/*
* Allocate/initialize a cursor for the by-number freespace btree.
*/
- bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
- args->pag, XFS_BTNUM_BNO);
+ bno_cur = xfs_bnobt_init_cursor(args->mp, args->tp, args->agbp,
+ args->pag);
/*
* Lookup bno and minlen in the btree (minlen is irrelevant, really).
@@ -1291,8 +1291,8 @@ xfs_alloc_ag_vextent_exact(
* We are allocating agbno for args->len
* Allocate/initialize a cursor for the by-size btree.
*/
- cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
- args->pag, XFS_BTNUM_CNT);
+ cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, args->agbp,
+ args->pag);
ASSERT(args->agbno + args->len <= be32_to_cpu(agf->agf_length));
error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
args->len, XFSA_FIXUP_BNO_OK);
@@ -1706,8 +1706,8 @@ xfs_alloc_ag_vextent_size(
/*
* Allocate and initialize a cursor for the by-size btree.
*/
- cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
- args->pag, XFS_BTNUM_CNT);
+ cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, args->agbp,
+ args->pag);
bno_cur = NULL;
/*
@@ -1892,8 +1892,8 @@ xfs_alloc_ag_vextent_size(
/*
* Allocate and initialize a cursor for the by-block tree.
*/
- bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
- args->pag, XFS_BTNUM_BNO);
+ bno_cur = xfs_bnobt_init_cursor(args->mp, args->tp, args->agbp,
+ args->pag);
if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
rbno, rlen, XFSA_FIXUP_CNT_OK)))
goto error0;
@@ -1967,7 +1967,7 @@ xfs_free_ag_extent(
/*
* Allocate and initialize a cursor for the by-block btree.
*/
- bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_BNO);
+ bno_cur = xfs_bnobt_init_cursor(mp, tp, agbp, pag);
/*
* Look for a neighboring block on the left (lower block numbers)
* that is contiguous with this space.
@@ -2041,7 +2041,7 @@ xfs_free_ag_extent(
/*
* Now allocate and initialize a cursor for the by-size tree.
*/
- cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_CNT);
+ cnt_cur = xfs_cntbt_init_cursor(mp, tp, agbp, pag);
/*
* Have both left and right contiguous neighbors.
* Merge all three into a single free block.
@@ -2750,8 +2750,8 @@ xfs_exact_minlen_extent_available(
xfs_extlen_t flen;
int error = 0;
- cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, agbp,
- args->pag, XFS_BTNUM_CNT);
+ cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, agbp,
+ args->pag);
error = xfs_alloc_lookup_ge(cnt_cur, 0, args->minlen, stat);
if (error)
goto out;
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 6ad44c146..b219dc6ac 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -22,13 +22,22 @@
static struct kmem_cache *xfs_allocbt_cur_cache;
STATIC struct xfs_btree_cur *
-xfs_allocbt_dup_cursor(
+xfs_bnobt_dup_cursor(
struct xfs_btree_cur *cur)
{
- return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
- cur->bc_ag.agbp, cur->bc_ag.pag, cur->bc_btnum);
+ return xfs_bnobt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ag.agbp,
+ cur->bc_ag.pag);
}
+STATIC struct xfs_btree_cur *
+xfs_cntbt_dup_cursor(
+ struct xfs_btree_cur *cur)
+{
+ return xfs_cntbt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ag.agbp,
+ cur->bc_ag.pag);
+}
+
+
STATIC void
xfs_allocbt_set_root(
struct xfs_btree_cur *cur,
@@ -478,7 +487,7 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
.statoff = XFS_STATS_CALC_INDEX(xs_abtb_2),
.sick_mask = XFS_SICK_AG_BNOBT,
- .dup_cursor = xfs_allocbt_dup_cursor,
+ .dup_cursor = xfs_bnobt_dup_cursor,
.set_root = xfs_allocbt_set_root,
.alloc_block = xfs_allocbt_alloc_block,
.free_block = xfs_allocbt_free_block,
@@ -510,7 +519,7 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
.statoff = XFS_STATS_CALC_INDEX(xs_abtc_2),
.sick_mask = XFS_SICK_AG_CNTBT,
- .dup_cursor = xfs_allocbt_dup_cursor,
+ .dup_cursor = xfs_cntbt_dup_cursor,
.set_root = xfs_allocbt_set_root,
.alloc_block = xfs_allocbt_alloc_block,
.free_block = xfs_allocbt_free_block,
@@ -530,36 +539,53 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
};
/*
- * Allocate a new allocation btree cursor.
+ * Allocate a new bnobt cursor.
*
* For staging cursors tp and agbp are NULL.
*/
struct xfs_btree_cur *
-xfs_allocbt_init_cursor(
+xfs_bnobt_init_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
struct xfs_buf *agbp,
- struct xfs_perag *pag,
- xfs_btnum_t btnum)
+ struct xfs_perag *pag)
{
- const struct xfs_btree_ops *ops = &xfs_bnobt_ops;
struct xfs_btree_cur *cur;
- ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BNO, &xfs_bnobt_ops,
+ mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
+ cur->bc_ag.pag = xfs_perag_hold(pag);
+ cur->bc_ag.agbp = agbp;
+ if (agbp) {
+ struct xfs_agf *agf = agbp->b_addr;
- if (btnum == XFS_BTNUM_CNT)
- ops = &xfs_cntbt_ops;
+ cur->bc_nlevels = be32_to_cpu(agf->agf_bno_level);
+ }
+ return cur;
+}
+
+/*
+ * Allocate a new cntbt cursor.
+ *
+ * For staging cursors tp and agbp are NULL.
+ */
+struct xfs_btree_cur *
+xfs_cntbt_init_cursor(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_buf *agbp,
+ struct xfs_perag *pag)
+{
+ struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops, mp->m_alloc_maxlevels,
- xfs_allocbt_cur_cache);
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_CNT, &xfs_cntbt_ops,
+ mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
if (agbp) {
struct xfs_agf *agf = agbp->b_addr;
- cur->bc_nlevels = (btnum == XFS_BTNUM_BNO) ?
- be32_to_cpu(agf->agf_bno_level) :
- be32_to_cpu(agf->agf_cnt_level);
+ cur->bc_nlevels = be32_to_cpu(agf->agf_cnt_level);
}
return cur;
}
diff --git a/libxfs/xfs_alloc_btree.h b/libxfs/xfs_alloc_btree.h
index 1c9108625..155b47f23 100644
--- a/libxfs/xfs_alloc_btree.h
+++ b/libxfs/xfs_alloc_btree.h
@@ -47,9 +47,12 @@ struct xbtree_afakeroot;
(maxrecs) * sizeof(xfs_alloc_key_t) + \
((index) - 1) * sizeof(xfs_alloc_ptr_t)))
-extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *mp,
+struct xfs_btree_cur *xfs_bnobt_init_cursor(struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_buf *bp,
- struct xfs_perag *pag, xfs_btnum_t btnum);
+ struct xfs_perag *pag);
+struct xfs_btree_cur *xfs_cntbt_init_cursor(struct xfs_mount *mp,
+ struct xfs_trans *tp, struct xfs_buf *bp,
+ struct xfs_perag *pag);
extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int);
extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp,
unsigned long long len);
diff --git a/repair/agbtree.c b/repair/agbtree.c
index ab97c1d79..bd7368be6 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -262,12 +262,10 @@ init_freespace_cursors(
init_rebuild(sc, &XFS_RMAP_OINFO_AG, est_agfreeblocks, btr_bno);
init_rebuild(sc, &XFS_RMAP_OINFO_AG, est_agfreeblocks, btr_cnt);
- btr_bno->cur = libxfs_allocbt_init_cursor(sc->mp, NULL, NULL, pag,
- XFS_BTNUM_BNO);
+ btr_bno->cur = libxfs_bnobt_init_cursor(sc->mp, NULL, NULL, pag);
libxfs_btree_stage_afakeroot(btr_bno->cur, &btr_bno->newbt.afake);
- btr_cnt->cur = libxfs_allocbt_init_cursor(sc->mp, NULL, NULL, pag,
- XFS_BTNUM_CNT);
+ btr_cnt->cur = libxfs_cntbt_init_cursor(sc->mp, NULL, NULL, pag);
libxfs_btree_stage_afakeroot(btr_cnt->cur, &btr_cnt->newbt.afake);
btr_bno->bload.get_records = get_bnobt_records;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 069/111] xfs: remove xfs_inobt_cur
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (67 preceding siblings ...)
2024-05-22 3:06 ` [PATCH 068/111] xfs: split xfs_allocbt_init_cursor Darrick J. Wong
@ 2024-05-22 3:06 ` Darrick J. Wong
2024-05-22 3:07 ` [PATCH 070/111] xfs: remove the btnum argument to xfs_inobt_count_blocks Darrick J. Wong
` (42 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:06 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 3038fd8129384c64946c17198229ee61f6f2c8e1
This helper provides no real advantage over just open code the two
calls in it in the callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_ialloc_btree.c | 29 +++--------------------------
libxfs/xfs_ialloc_btree.h | 3 ---
2 files changed, 3 insertions(+), 29 deletions(-)
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 08076ef12..cf59530ea 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -709,30 +709,6 @@ xfs_inobt_max_size(
XFS_INODES_PER_CHUNK);
}
-/* Read AGI and create inobt cursor. */
-int
-xfs_inobt_cur(
- struct xfs_perag *pag,
- struct xfs_trans *tp,
- xfs_btnum_t which,
- struct xfs_btree_cur **curpp,
- struct xfs_buf **agi_bpp)
-{
- struct xfs_btree_cur *cur;
- int error;
-
- ASSERT(*agi_bpp == NULL);
- ASSERT(*curpp == NULL);
-
- error = xfs_ialloc_read_agi(pag, tp, agi_bpp);
- if (error)
- return error;
-
- cur = xfs_inobt_init_cursor(pag, tp, *agi_bpp, which);
- *curpp = cur;
- return 0;
-}
-
static int
xfs_inobt_count_blocks(
struct xfs_perag *pag,
@@ -741,13 +717,14 @@ xfs_inobt_count_blocks(
xfs_extlen_t *tree_blocks)
{
struct xfs_buf *agbp = NULL;
- struct xfs_btree_cur *cur = NULL;
+ struct xfs_btree_cur *cur;
int error;
- error = xfs_inobt_cur(pag, tp, btnum, &cur, &agbp);
+ error = xfs_ialloc_read_agi(pag, tp, &agbp);
if (error)
return error;
+ cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum);
error = xfs_btree_count_blocks(cur, tree_blocks);
xfs_btree_del_cursor(cur, error);
xfs_trans_brelse(tp, agbp);
diff --git a/libxfs/xfs_ialloc_btree.h b/libxfs/xfs_ialloc_btree.h
index 40f0fc0e8..2f1552d65 100644
--- a/libxfs/xfs_ialloc_btree.h
+++ b/libxfs/xfs_ialloc_btree.h
@@ -64,9 +64,6 @@ int xfs_finobt_calc_reserves(struct xfs_perag *perag, struct xfs_trans *tp,
xfs_extlen_t *ask, xfs_extlen_t *used);
extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp,
unsigned long long len);
-int xfs_inobt_cur(struct xfs_perag *pag, struct xfs_trans *tp,
- xfs_btnum_t btnum, struct xfs_btree_cur **curpp,
- struct xfs_buf **agi_bpp);
void xfs_inobt_commit_staged_btree(struct xfs_btree_cur *cur,
struct xfs_trans *tp, struct xfs_buf *agbp);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 070/111] xfs: remove the btnum argument to xfs_inobt_count_blocks
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (68 preceding siblings ...)
2024-05-22 3:06 ` [PATCH 069/111] xfs: remove xfs_inobt_cur Darrick J. Wong
@ 2024-05-22 3:07 ` Darrick J. Wong
2024-05-22 3:07 ` [PATCH 071/111] xfs: split xfs_inobt_insert_sprec Darrick J. Wong
` (41 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:07 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 4bfb028a4c00d0a079a625d7867325efb3c37de2
xfs_inobt_count_blocks is only used for the finobt. Hardcode the btnum
argument and rename the function to match that.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_ialloc_btree.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index cf59530ea..609f62c65 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -710,10 +710,9 @@ xfs_inobt_max_size(
}
static int
-xfs_inobt_count_blocks(
+xfs_finobt_count_blocks(
struct xfs_perag *pag,
struct xfs_trans *tp,
- xfs_btnum_t btnum,
xfs_extlen_t *tree_blocks)
{
struct xfs_buf *agbp = NULL;
@@ -724,7 +723,7 @@ xfs_inobt_count_blocks(
if (error)
return error;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
error = xfs_btree_count_blocks(cur, tree_blocks);
xfs_btree_del_cursor(cur, error);
xfs_trans_brelse(tp, agbp);
@@ -772,8 +771,7 @@ xfs_finobt_calc_reserves(
if (xfs_has_inobtcounts(pag->pag_mount))
error = xfs_finobt_read_blocks(pag, tp, &tree_len);
else
- error = xfs_inobt_count_blocks(pag, tp, XFS_BTNUM_FINO,
- &tree_len);
+ error = xfs_finobt_count_blocks(pag, tp, &tree_len);
if (error)
return error;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 071/111] xfs: split xfs_inobt_insert_sprec
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (69 preceding siblings ...)
2024-05-22 3:07 ` [PATCH 070/111] xfs: remove the btnum argument to xfs_inobt_count_blocks Darrick J. Wong
@ 2024-05-22 3:07 ` Darrick J. Wong
2024-05-22 3:07 ` [PATCH 072/111] xfs: split xfs_inobt_init_cursor Darrick J. Wong
` (40 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:07 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 8541a7d9da2dd6e44f401f2363b21749b7413fc9
Split the finobt version that never merges and uses a different cursor
out of xfs_inobt_insert_sprec to prepare for removing xfs_btnum_t.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_ialloc.c | 148 +++++++++++++++++++++++++++++++++------------------
1 file changed, 96 insertions(+), 52 deletions(-)
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 94f4f8690..4f3d7d4dc 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -524,16 +524,14 @@ __xfs_inobt_rec_merge(
}
/*
- * Insert a new sparse inode chunk into the associated inode btree. The inode
- * record for the sparse chunk is pre-aligned to a startino that should match
- * any pre-existing sparse inode record in the tree. This allows sparse chunks
- * to fill over time.
+ * Insert a new sparse inode chunk into the associated inode allocation btree.
+ * The inode record for the sparse chunk is pre-aligned to a startino that
+ * should match any pre-existing sparse inode record in the tree. This allows
+ * sparse chunks to fill over time.
*
- * This function supports two modes of handling preexisting records depending on
- * the merge flag. If merge is true, the provided record is merged with the
+ * If no preexisting record exists, the provided record is inserted.
+ * If there is a preexisting record, the provided record is merged with the
* existing record and updated in place. The merged record is returned in nrec.
- * If merge is false, an existing record is replaced with the provided record.
- * If no preexisting record exists, the provided record is always inserted.
*
* It is considered corruption if a merge is requested and not possible. Given
* the sparse inode alignment constraints, this should never happen.
@@ -543,9 +541,7 @@ xfs_inobt_insert_sprec(
struct xfs_perag *pag,
struct xfs_trans *tp,
struct xfs_buf *agbp,
- int btnum,
- struct xfs_inobt_rec_incore *nrec, /* in/out: new/merged rec. */
- bool merge) /* merge or replace */
+ struct xfs_inobt_rec_incore *nrec) /* in/out: new/merged rec. */
{
struct xfs_mount *mp = pag->pag_mount;
struct xfs_btree_cur *cur;
@@ -553,7 +549,7 @@ xfs_inobt_insert_sprec(
int i;
struct xfs_inobt_rec_incore rec;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
/* the new record is pre-aligned so we know where to look */
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
@@ -576,48 +572,45 @@ xfs_inobt_insert_sprec(
}
/*
- * A record exists at this startino. Merge or replace the record
- * depending on what we've been asked to do.
+ * A record exists at this startino. Merge the records.
*/
- if (merge) {
- error = xfs_inobt_get_rec(cur, &rec, &i);
- if (error)
- goto error;
- if (XFS_IS_CORRUPT(mp, i != 1)) {
- xfs_btree_mark_sick(cur);
- error = -EFSCORRUPTED;
- goto error;
- }
- if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
- xfs_btree_mark_sick(cur);
- error = -EFSCORRUPTED;
- goto error;
- }
+ error = xfs_inobt_get_rec(cur, &rec, &i);
+ if (error)
+ goto error;
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
+ error = -EFSCORRUPTED;
+ goto error;
+ }
+ if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
+ xfs_btree_mark_sick(cur);
+ error = -EFSCORRUPTED;
+ goto error;
+ }
- /*
- * This should never fail. If we have coexisting records that
- * cannot merge, something is seriously wrong.
- */
- if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
- xfs_btree_mark_sick(cur);
- error = -EFSCORRUPTED;
- goto error;
- }
+ /*
+ * This should never fail. If we have coexisting records that
+ * cannot merge, something is seriously wrong.
+ */
+ if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
+ xfs_btree_mark_sick(cur);
+ error = -EFSCORRUPTED;
+ goto error;
+ }
- trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
- rec.ir_holemask, nrec->ir_startino,
- nrec->ir_holemask);
+ trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
+ rec.ir_holemask, nrec->ir_startino,
+ nrec->ir_holemask);
- /* merge to nrec to output the updated record */
- __xfs_inobt_rec_merge(nrec, &rec);
+ /* merge to nrec to output the updated record */
+ __xfs_inobt_rec_merge(nrec, &rec);
- trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
- nrec->ir_holemask);
+ trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
+ nrec->ir_holemask);
- error = xfs_inobt_rec_check_count(mp, nrec);
- if (error)
- goto error;
- }
+ error = xfs_inobt_rec_check_count(mp, nrec);
+ if (error)
+ goto error;
error = xfs_inobt_update(cur, nrec);
if (error)
@@ -631,6 +624,59 @@ xfs_inobt_insert_sprec(
return error;
}
+/*
+ * Insert a new sparse inode chunk into the free inode btree. The inode
+ * record for the sparse chunk is pre-aligned to a startino that should match
+ * any pre-existing sparse inode record in the tree. This allows sparse chunks
+ * to fill over time.
+ *
+ * The new record is always inserted, overwriting a pre-existing record if
+ * there is one.
+ */
+STATIC int
+xfs_finobt_insert_sprec(
+ struct xfs_perag *pag,
+ struct xfs_trans *tp,
+ struct xfs_buf *agbp,
+ struct xfs_inobt_rec_incore *nrec) /* in/out: new rec. */
+{
+ struct xfs_mount *mp = pag->pag_mount;
+ struct xfs_btree_cur *cur;
+ int error;
+ int i;
+
+ cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
+
+ /* the new record is pre-aligned so we know where to look */
+ error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
+ if (error)
+ goto error;
+ /* if nothing there, insert a new record and return */
+ if (i == 0) {
+ error = xfs_inobt_insert_rec(cur, nrec->ir_holemask,
+ nrec->ir_count, nrec->ir_freecount,
+ nrec->ir_free, &i);
+ if (error)
+ goto error;
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
+ xfs_btree_mark_sick(cur);
+ error = -EFSCORRUPTED;
+ goto error;
+ }
+ } else {
+ error = xfs_inobt_update(cur, nrec);
+ if (error)
+ goto error;
+ }
+
+ xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
+ return 0;
+error:
+ xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
+ return error;
+}
+
+
/*
* Allocate new inodes in the allocation group specified by agbp. Returns 0 if
* inodes were allocated in this AG; -EAGAIN if there was no space in this AG so
@@ -857,8 +903,7 @@ xfs_ialloc_ag_alloc(
* if necessary. If a merge does occur, rec is updated to the
* merged record.
*/
- error = xfs_inobt_insert_sprec(pag, tp, agbp,
- XFS_BTNUM_INO, &rec, true);
+ error = xfs_inobt_insert_sprec(pag, tp, agbp, &rec);
if (error == -EFSCORRUPTED) {
xfs_alert(args.mp,
"invalid sparse inode record: ino 0x%llx holemask 0x%x count %u",
@@ -882,8 +927,7 @@ xfs_ialloc_ag_alloc(
* existing record with this one.
*/
if (xfs_has_finobt(args.mp)) {
- error = xfs_inobt_insert_sprec(pag, tp, agbp,
- XFS_BTNUM_FINO, &rec, false);
+ error = xfs_finobt_insert_sprec(pag, tp, agbp, &rec);
if (error)
return error;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 072/111] xfs: split xfs_inobt_init_cursor
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (70 preceding siblings ...)
2024-05-22 3:07 ` [PATCH 071/111] xfs: split xfs_inobt_insert_sprec Darrick J. Wong
@ 2024-05-22 3:07 ` Darrick J. Wong
2024-05-22 3:07 ` [PATCH 073/111] xfs: pass a 'bool is_finobt' to xfs_inobt_insert Darrick J. Wong
` (39 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:07 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 14dd46cf31f4aaffcf26b00de9af39d01ec8d547
Split xfs_inobt_init_cursor into separate routines for the inobt and
finobt to prepare for the removal of the xfs_btnum global enumeration
of btree types.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/libxfs_api_defs.h | 1 +
libxfs/xfs_ialloc.c | 23 +++++++++++---------
libxfs/xfs_ialloc_btree.c | 51 ++++++++++++++++++++++++++++++++++-----------
libxfs/xfs_ialloc_btree.h | 6 ++++-
repair/agbtree.c | 6 ++---
5 files changed, 58 insertions(+), 29 deletions(-)
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 8f4b98080..0e72944bc 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -129,6 +129,7 @@
#define xfs_dquot_verify libxfs_dquot_verify
#define xfs_finobt_calc_reserves libxfs_finobt_calc_reserves
+#define xfs_finobt_init_cursor libxfs_finobt_init_cursor
#define xfs_free_extent libxfs_free_extent
#define xfs_free_extent_later libxfs_free_extent_later
#define xfs_free_perag libxfs_free_perag
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 4f3d7d4dc..37d014713 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -208,7 +208,10 @@ xfs_inobt_insert(
int i;
int error;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, btnum);
+ if (btnum == XFS_BTNUM_FINO)
+ cur = xfs_finobt_init_cursor(pag, tp, agbp);
+ else
+ cur = xfs_inobt_init_cursor(pag, tp, agbp);
for (thisino = newino;
thisino < newino + newlen;
@@ -549,7 +552,7 @@ xfs_inobt_insert_sprec(
int i;
struct xfs_inobt_rec_incore rec;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp);
/* the new record is pre-aligned so we know where to look */
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
@@ -645,7 +648,7 @@ xfs_finobt_insert_sprec(
int error;
int i;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
+ cur = xfs_finobt_init_cursor(pag, tp, agbp);
/* the new record is pre-aligned so we know where to look */
error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
@@ -1078,7 +1081,7 @@ xfs_dialloc_ag_inobt(
ASSERT(pag->pagi_freecount > 0);
restart_pagno:
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp);
/*
* If pagino is 0 (this is the root inode allocation) use newino.
* This must work because we've just allocated some.
@@ -1552,7 +1555,7 @@ xfs_dialloc_ag(
if (!pagino)
pagino = be32_to_cpu(agi->agi_newino);
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
+ cur = xfs_finobt_init_cursor(pag, tp, agbp);
error = xfs_check_agi_freecount(cur);
if (error)
@@ -1595,7 +1598,7 @@ xfs_dialloc_ag(
* the original freecount. If all is well, make the equivalent update to
* the inobt using the finobt record and offset information.
*/
- icur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
+ icur = xfs_inobt_init_cursor(pag, tp, agbp);
error = xfs_check_agi_freecount(icur);
if (error)
@@ -2012,7 +2015,7 @@ xfs_difree_inobt(
/*
* Initialize the cursor.
*/
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp);
error = xfs_check_agi_freecount(cur);
if (error)
@@ -2139,7 +2142,7 @@ xfs_difree_finobt(
int error;
int i;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
+ cur = xfs_finobt_init_cursor(pag, tp, agbp);
error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i);
if (error)
@@ -2339,7 +2342,7 @@ xfs_imap_lookup(
* we have a record, we need to ensure it contains the inode number
* we are looking up.
*/
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_INO);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp);
error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
if (!error) {
if (i)
@@ -3058,7 +3061,7 @@ xfs_ialloc_check_shrink(
if (!xfs_has_sparseinodes(pag->pag_mount))
return 0;
- cur = xfs_inobt_init_cursor(pag, tp, agibp, XFS_BTNUM_INO);
+ cur = xfs_inobt_init_cursor(pag, tp, agibp);
/* Look up the inobt record that would correspond to the new EOFS. */
agino = XFS_AGB_TO_AGINO(pag->pag_mount, new_length);
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 609f62c65..2f095862e 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -37,7 +37,15 @@ xfs_inobt_dup_cursor(
struct xfs_btree_cur *cur)
{
return xfs_inobt_init_cursor(cur->bc_ag.pag, cur->bc_tp,
- cur->bc_ag.agbp, cur->bc_btnum);
+ cur->bc_ag.agbp);
+}
+
+STATIC struct xfs_btree_cur *
+xfs_finobt_dup_cursor(
+ struct xfs_btree_cur *cur)
+{
+ return xfs_finobt_init_cursor(cur->bc_ag.pag, cur->bc_tp,
+ cur->bc_ag.agbp);
}
STATIC void
@@ -440,7 +448,7 @@ const struct xfs_btree_ops xfs_finobt_ops = {
.statoff = XFS_STATS_CALC_INDEX(xs_fibt_2),
.sick_mask = XFS_SICK_AG_FINOBT,
- .dup_cursor = xfs_inobt_dup_cursor,
+ .dup_cursor = xfs_finobt_dup_cursor,
.set_root = xfs_finobt_set_root,
.alloc_block = xfs_finobt_alloc_block,
.free_block = xfs_finobt_free_block,
@@ -467,28 +475,45 @@ struct xfs_btree_cur *
xfs_inobt_init_cursor(
struct xfs_perag *pag,
struct xfs_trans *tp,
- struct xfs_buf *agbp,
- xfs_btnum_t btnum) /* ialloc or free ino btree */
+ struct xfs_buf *agbp)
{
struct xfs_mount *mp = pag->pag_mount;
- const struct xfs_btree_ops *ops = &xfs_inobt_ops;
struct xfs_btree_cur *cur;
- ASSERT(btnum == XFS_BTNUM_INO || btnum == XFS_BTNUM_FINO);
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_INO, &xfs_inobt_ops,
+ M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
+ cur->bc_ag.pag = xfs_perag_hold(pag);
+ cur->bc_ag.agbp = agbp;
+ if (agbp) {
+ struct xfs_agi *agi = agbp->b_addr;
- if (btnum == XFS_BTNUM_FINO)
- ops = &xfs_finobt_ops;
+ cur->bc_nlevels = be32_to_cpu(agi->agi_level);
+ }
+ return cur;
+}
+
+/*
+ * Create a free inode btree cursor.
+ *
+ * For staging cursors tp and agbp are NULL.
+ */
+struct xfs_btree_cur *
+xfs_finobt_init_cursor(
+ struct xfs_perag *pag,
+ struct xfs_trans *tp,
+ struct xfs_buf *agbp)
+{
+ struct xfs_mount *mp = pag->pag_mount;
+ struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops,
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_FINO, &xfs_finobt_ops,
M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
if (agbp) {
struct xfs_agi *agi = agbp->b_addr;
- cur->bc_nlevels = (btnum == XFS_BTNUM_INO) ?
- be32_to_cpu(agi->agi_level) :
- be32_to_cpu(agi->agi_free_level);
+ cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
}
return cur;
}
@@ -723,7 +748,7 @@ xfs_finobt_count_blocks(
if (error)
return error;
- cur = xfs_inobt_init_cursor(pag, tp, agbp, XFS_BTNUM_FINO);
+ cur = xfs_inobt_init_cursor(pag, tp, agbp);
error = xfs_btree_count_blocks(cur, tree_blocks);
xfs_btree_del_cursor(cur, error);
xfs_trans_brelse(tp, agbp);
diff --git a/libxfs/xfs_ialloc_btree.h b/libxfs/xfs_ialloc_btree.h
index 2f1552d65..6472ec1ec 100644
--- a/libxfs/xfs_ialloc_btree.h
+++ b/libxfs/xfs_ialloc_btree.h
@@ -46,8 +46,10 @@ struct xfs_perag;
(maxrecs) * sizeof(xfs_inobt_key_t) + \
((index) - 1) * sizeof(xfs_inobt_ptr_t)))
-extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_perag *pag,
- struct xfs_trans *tp, struct xfs_buf *agbp, xfs_btnum_t btnum);
+struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_perag *pag,
+ struct xfs_trans *tp, struct xfs_buf *agbp);
+struct xfs_btree_cur *xfs_finobt_init_cursor(struct xfs_perag *pag,
+ struct xfs_trans *tp, struct xfs_buf *agbp);
extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int);
/* ir_holemask to inode allocation bitmap conversion */
diff --git a/repair/agbtree.c b/repair/agbtree.c
index bd7368be6..7d7727151 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -522,8 +522,7 @@ init_ino_cursors(
fino_recs++;
}
- btr_ino->cur = libxfs_inobt_init_cursor(pag, NULL, NULL,
- XFS_BTNUM_INO);
+ btr_ino->cur = libxfs_inobt_init_cursor(pag, NULL, NULL);
libxfs_btree_stage_afakeroot(btr_ino->cur, &btr_ino->newbt.afake);
btr_ino->bload.get_records = get_inobt_records;
@@ -543,8 +542,7 @@ _("Unable to compute inode btree geometry, error %d.\n"), error);
return;
init_rebuild(sc, &XFS_RMAP_OINFO_INOBT, est_agfreeblocks, btr_fino);
- btr_fino->cur = libxfs_inobt_init_cursor(pag, NULL, NULL,
- XFS_BTNUM_FINO);
+ btr_fino->cur = libxfs_finobt_init_cursor(pag, NULL, NULL);
libxfs_btree_stage_afakeroot(btr_fino->cur, &btr_fino->newbt.afake);
btr_fino->bload.get_records = get_inobt_records;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 073/111] xfs: pass a 'bool is_finobt' to xfs_inobt_insert
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (71 preceding siblings ...)
2024-05-22 3:07 ` [PATCH 072/111] xfs: split xfs_inobt_init_cursor Darrick J. Wong
@ 2024-05-22 3:07 ` Darrick J. Wong
2024-05-22 3:08 ` [PATCH 074/111] xfs: remove xfs_btnum_t Darrick J. Wong
` (38 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:07 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: fbeef4e061ab28bf556af4ee2a5a9848dc4616c5
This is one of the last users of xfs_btnum_t and can only designate
either the inobt or finobt. Replace it with a simple bool.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_ialloc.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 37d014713..296548bc1 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -201,14 +201,14 @@ xfs_inobt_insert(
struct xfs_buf *agbp,
xfs_agino_t newino,
xfs_agino_t newlen,
- xfs_btnum_t btnum)
+ bool is_finobt)
{
struct xfs_btree_cur *cur;
xfs_agino_t thisino;
int i;
int error;
- if (btnum == XFS_BTNUM_FINO)
+ if (is_finobt)
cur = xfs_finobt_init_cursor(pag, tp, agbp);
else
cur = xfs_inobt_init_cursor(pag, tp, agbp);
@@ -936,14 +936,13 @@ xfs_ialloc_ag_alloc(
}
} else {
/* full chunk - insert new records to both btrees */
- error = xfs_inobt_insert(pag, tp, agbp, newino, newlen,
- XFS_BTNUM_INO);
+ error = xfs_inobt_insert(pag, tp, agbp, newino, newlen, false);
if (error)
return error;
if (xfs_has_finobt(args.mp)) {
error = xfs_inobt_insert(pag, tp, agbp, newino,
- newlen, XFS_BTNUM_FINO);
+ newlen, true);
if (error)
return error;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 074/111] xfs: remove xfs_btnum_t
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (72 preceding siblings ...)
2024-05-22 3:07 ` [PATCH 073/111] xfs: pass a 'bool is_finobt' to xfs_inobt_insert Darrick J. Wong
@ 2024-05-22 3:08 ` Darrick J. Wong
2024-05-22 3:08 ` [PATCH 075/111] xfs: simplify xfs_btree_check_sblock_siblings Darrick J. Wong
` (37 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:08 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: ec793e690f801d97a7ae2a0d429fea1fee4d44aa
The last checks for bc_btnum can be replaced with helpers that check
the btree ops. This allows adding new btrees to XFS without having
to update a global enum.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: complete the ops predicates]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc.c | 6 +++---
libxfs/xfs_alloc_btree.c | 12 ++++++------
libxfs/xfs_bmap_btree.c | 4 ++--
libxfs/xfs_btree.c | 4 ++--
libxfs/xfs_btree.h | 11 -----------
libxfs/xfs_ialloc.c | 2 +-
libxfs/xfs_ialloc_btree.c | 10 +++++-----
libxfs/xfs_refcount_btree.c | 5 ++---
libxfs/xfs_rmap_btree.c | 2 +-
libxfs/xfs_shared.h | 35 +++++++++++++++++++++++++++++++++++
libxfs/xfs_types.h | 9 ---------
repair/agbtree.c | 4 ++--
repair/phase5.c | 6 ++----
13 files changed, 61 insertions(+), 49 deletions(-)
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 599271e5c..0eefb16cc 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -914,7 +914,7 @@ xfs_alloc_cur_check(
bool busy;
unsigned busy_gen = 0;
bool deactivate = false;
- bool isbnobt = cur->bc_btnum == XFS_BTNUM_BNO;
+ bool isbnobt = xfs_btree_is_bno(cur->bc_ops);
*new = 0;
@@ -4022,7 +4022,7 @@ xfs_alloc_query_range(
union xfs_btree_irec high_brec = { .a = *high_rec };
struct xfs_alloc_query_range_info query = { .priv = priv, .fn = fn };
- ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
+ ASSERT(xfs_btree_is_bno(cur->bc_ops));
return xfs_btree_query_range(cur, &low_brec, &high_brec,
xfs_alloc_query_range_helper, &query);
}
@@ -4036,7 +4036,7 @@ xfs_alloc_query_all(
{
struct xfs_alloc_query_range_info query;
- ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
+ ASSERT(xfs_btree_is_bno(cur->bc_ops));
query.priv = priv;
query.fn = fn;
return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index b219dc6ac..35d3dde42 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -49,7 +49,7 @@ xfs_allocbt_set_root(
ASSERT(ptr->s != 0);
- if (cur->bc_btnum == XFS_BTNUM_BNO) {
+ if (xfs_btree_is_bno(cur->bc_ops)) {
agf->agf_bno_root = ptr->s;
be32_add_cpu(&agf->agf_bno_level, inc);
cur->bc_ag.pag->pagf_bno_level += inc;
@@ -129,7 +129,7 @@ xfs_allocbt_update_lastrec(
__be32 len;
int numrecs;
- ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
+ ASSERT(!xfs_btree_is_bno(cur->bc_ops));
switch (reason) {
case LASTREC_UPDATE:
@@ -239,7 +239,7 @@ xfs_allocbt_init_ptr_from_cur(
ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));
- if (cur->bc_btnum == XFS_BTNUM_BNO)
+ if (xfs_btree_is_bno(cur->bc_ops))
ptr->s = agf->agf_bno_root;
else
ptr->s = agf->agf_cnt_root;
@@ -552,7 +552,7 @@ xfs_bnobt_init_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BNO, &xfs_bnobt_ops,
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_bnobt_ops,
mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
@@ -578,7 +578,7 @@ xfs_cntbt_init_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_CNT, &xfs_cntbt_ops,
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_cntbt_ops,
mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
@@ -605,7 +605,7 @@ xfs_allocbt_commit_staged_btree(
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
- if (cur->bc_btnum == XFS_BTNUM_BNO) {
+ if (xfs_btree_is_bno(cur->bc_ops)) {
agf->agf_bno_root = cpu_to_be32(afake->af_root);
agf->agf_bno_level = cpu_to_be32(afake->af_levels);
} else {
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 12b94c74e..eede6ffd6 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -573,8 +573,8 @@ xfs_bmbt_init_cursor(
maxlevels = mp->m_bm_maxlevels[whichfork];
break;
}
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP, &xfs_bmbt_ops,
- maxlevels, xfs_bmbt_cur_cache);
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_bmbt_ops, maxlevels,
+ xfs_bmbt_cur_cache);
cur->bc_ino.ip = ip;
cur->bc_ino.whichfork = whichfork;
cur->bc_bmap.allocated = 0;
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 95f77fbe7..0b6d8d6f1 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -451,7 +451,7 @@ xfs_btree_del_cursor(
* zero, then we should be shut down or on our way to shutdown due to
* cancelling a dirty transaction on error.
*/
- ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_bmap.allocated == 0 ||
+ ASSERT(!xfs_btree_is_bmap(cur->bc_ops) || cur->bc_bmap.allocated == 0 ||
xfs_is_shutdown(cur->bc_mp) || error != 0);
switch (cur->bc_ops->type) {
@@ -3013,7 +3013,7 @@ xfs_btree_split(
struct xfs_btree_split_args args;
DECLARE_COMPLETION_ONSTACK(done);
- if (cur->bc_btnum != XFS_BTNUM_BMAP ||
+ if (!xfs_btree_is_bmap(cur->bc_ops) ||
cur->bc_tp->t_highest_agno == NULLAGNUMBER)
return __xfs_btree_split(cur, level, ptrp, key, curp, stat);
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 6e5fd0c06..9a264ffee 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -55,14 +55,6 @@ union xfs_btree_rec {
#define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi)
#define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi)
-#define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi)
-#define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi)
-#define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
-#define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
-#define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi)
-#define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi)
-#define XFS_BTNUM_REFC ((xfs_btnum_t)XFS_BTNUM_REFCi)
-
struct xfs_btree_ops;
uint32_t xfs_btree_magic(struct xfs_mount *mp, const struct xfs_btree_ops *ops);
@@ -272,7 +264,6 @@ struct xfs_btree_cur
const struct xfs_btree_ops *bc_ops;
struct kmem_cache *bc_cache; /* cursor cache */
unsigned int bc_flags; /* btree features - below */
- xfs_btnum_t bc_btnum; /* identifies which btree type */
union xfs_btree_irec bc_rec; /* current insert/search record value */
uint8_t bc_nlevels; /* number of levels in the tree */
uint8_t bc_maxlevels; /* maximum levels for this btree type */
@@ -726,7 +717,6 @@ static inline struct xfs_btree_cur *
xfs_btree_alloc_cursor(
struct xfs_mount *mp,
struct xfs_trans *tp,
- xfs_btnum_t btnum,
const struct xfs_btree_ops *ops,
uint8_t maxlevels,
struct kmem_cache *cache)
@@ -742,7 +732,6 @@ xfs_btree_alloc_cursor(
cur->bc_ops = ops;
cur->bc_tp = tp;
cur->bc_mp = mp;
- cur->bc_btnum = btnum;
cur->bc_maxlevels = maxlevels;
cur->bc_cache = cache;
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 296548bc1..c30e76830 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -2843,7 +2843,7 @@ xfs_ialloc_count_inodes(
struct xfs_ialloc_count_inodes ci = {0};
int error;
- ASSERT(cur->bc_btnum == XFS_BTNUM_INO);
+ ASSERT(xfs_btree_is_ino(cur->bc_ops));
error = xfs_btree_query_all(cur, xfs_ialloc_count_inodes_rec, &ci);
if (error)
return error;
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 2f095862e..cb0a7c779 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -89,9 +89,9 @@ xfs_inobt_mod_blockcount(
if (!xfs_has_inobtcounts(cur->bc_mp))
return;
- if (cur->bc_btnum == XFS_BTNUM_FINO)
+ if (xfs_btree_is_fino(cur->bc_ops))
be32_add_cpu(&agi->agi_fblocks, howmuch);
- else if (cur->bc_btnum == XFS_BTNUM_INO)
+ else
be32_add_cpu(&agi->agi_iblocks, howmuch);
xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_IBLOCKS);
}
@@ -480,7 +480,7 @@ xfs_inobt_init_cursor(
struct xfs_mount *mp = pag->pag_mount;
struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_INO, &xfs_inobt_ops,
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_inobt_ops,
M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
@@ -506,7 +506,7 @@ xfs_finobt_init_cursor(
struct xfs_mount *mp = pag->pag_mount;
struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_FINO, &xfs_finobt_ops,
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_finobt_ops,
M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
@@ -534,7 +534,7 @@ xfs_inobt_commit_staged_btree(
ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
- if (cur->bc_btnum == XFS_BTNUM_INO) {
+ if (xfs_btree_is_ino(cur->bc_ops)) {
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);
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 31ef879ba..6ec0e36e5 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -363,9 +363,8 @@ xfs_refcountbt_init_cursor(
ASSERT(pag->pag_agno < mp->m_sb.sb_agcount);
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC,
- &xfs_refcountbt_ops, mp->m_refc_maxlevels,
- xfs_refcountbt_cur_cache);
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_refcountbt_ops,
+ mp->m_refc_maxlevels, xfs_refcountbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_refc.nr_ops = 0;
cur->bc_refc.shape_changes = 0;
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index c7ca20043..18168db6e 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -516,7 +516,7 @@ xfs_rmapbt_init_cursor(
{
struct xfs_btree_cur *cur;
- cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, &xfs_rmapbt_ops,
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_rmapbt_ops,
mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache);
cur->bc_ag.pag = xfs_perag_hold(pag);
cur->bc_ag.agbp = agbp;
diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h
index 518ea9456..6b8bc276d 100644
--- a/libxfs/xfs_shared.h
+++ b/libxfs/xfs_shared.h
@@ -52,6 +52,41 @@ extern const struct xfs_btree_ops xfs_bmbt_ops;
extern const struct xfs_btree_ops xfs_refcountbt_ops;
extern const struct xfs_btree_ops xfs_rmapbt_ops;
+static inline bool xfs_btree_is_bno(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_bnobt_ops;
+}
+
+static inline bool xfs_btree_is_cnt(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_cntbt_ops;
+}
+
+static inline bool xfs_btree_is_bmap(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_bmbt_ops;
+}
+
+static inline bool xfs_btree_is_ino(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_inobt_ops;
+}
+
+static inline bool xfs_btree_is_fino(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_finobt_ops;
+}
+
+static inline bool xfs_btree_is_refcount(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_refcountbt_ops;
+}
+
+static inline bool xfs_btree_is_rmap(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_rmapbt_ops;
+}
+
/* log size calculation functions */
int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes);
int xfs_log_calc_minimum_size(struct xfs_mount *);
diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h
index f577247b7..76eb9e328 100644
--- a/libxfs/xfs_types.h
+++ b/libxfs/xfs_types.h
@@ -116,15 +116,6 @@ typedef enum {
{ XFS_LOOKUP_LEi, "le" }, \
{ XFS_LOOKUP_GEi, "ge" }
-/*
- * This enum is used in string mapping in xfs_trace.h and scrub/trace.h;
- * please keep the TRACE_DEFINE_ENUMs for it up to date.
- */
-typedef enum {
- XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi,
- XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_REFCi, XFS_BTNUM_MAX
-} xfs_btnum_t;
-
struct xfs_name {
const unsigned char *name;
int len;
diff --git a/repair/agbtree.c b/repair/agbtree.c
index 7d7727151..1a3e40cca 100644
--- a/repair/agbtree.c
+++ b/repair/agbtree.c
@@ -204,7 +204,7 @@ get_bno_rec(
{
xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno;
- if (cur->bc_btnum == XFS_BTNUM_BNO) {
+ if (xfs_btree_is_bno(cur->bc_ops)) {
if (!prev_value)
return findfirst_bno_extent(agno);
return findnext_bno_extent(prev_value);
@@ -378,7 +378,7 @@ get_ino_rec(
{
xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno;
- if (cur->bc_btnum == XFS_BTNUM_INO) {
+ if (xfs_btree_is_ino(cur->bc_ops)) {
if (!prev_value)
return findfirst_inode_rec(agno);
return next_ino_rec(prev_value);
diff --git a/repair/phase5.c b/repair/phase5.c
index 6ae2ea575..b689a4234 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -304,11 +304,9 @@ build_agf_agfl(
}
#ifdef XR_BLD_FREE_TRACE
- fprintf(stderr, "bno root = %u, bcnt root = %u, indices = %u %u\n",
+ fprintf(stderr, "bno root = %u, bcnt root = %u\n",
be32_to_cpu(agf->agf_bno_root),
- be32_to_cpu(agf->agf_cnt_root),
- XFS_BTNUM_BNO,
- XFS_BTNUM_CNT);
+ be32_to_cpu(agf->agf_cnt_root));
#endif
if (xfs_has_crc(mp))
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 075/111] xfs: simplify xfs_btree_check_sblock_siblings
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (73 preceding siblings ...)
2024-05-22 3:08 ` [PATCH 074/111] xfs: remove xfs_btnum_t Darrick J. Wong
@ 2024-05-22 3:08 ` Darrick J. Wong
2024-05-22 3:08 ` [PATCH 076/111] xfs: simplify xfs_btree_check_lblock_siblings Darrick J. Wong
` (36 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:08 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 4bc94bf640e08cf970354036683ec143a7ae974e
Stop using xfs_btree_check_sptr in xfs_btree_check_sblock_siblings,
as it only duplicates the xfs_verify_agbno call in the other leg of
if / else besides adding a tautological level check.
With this the cur and level arguments can be removed as they are
now unused.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 0b6d8d6f1..4ba36ecbb 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -83,8 +83,6 @@ xfs_btree_check_lblock_siblings(
static inline xfs_failaddr_t
xfs_btree_check_sblock_siblings(
struct xfs_perag *pag,
- struct xfs_btree_cur *cur,
- int level,
xfs_agblock_t agbno,
__be32 dsibling)
{
@@ -96,13 +94,8 @@ xfs_btree_check_sblock_siblings(
sibling = be32_to_cpu(dsibling);
if (sibling == agbno)
return __this_address;
- if (level >= 0) {
- if (!xfs_btree_check_sptr(cur, sibling, level + 1))
- return __this_address;
- } else {
- if (!xfs_verify_agbno(pag, sibling))
- return __this_address;
- }
+ if (!xfs_verify_agbno(pag, sibling))
+ return __this_address;
return NULL;
}
@@ -209,10 +202,10 @@ __xfs_btree_check_sblock(
if (bp)
agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_sblock_siblings(pag, cur, level, agbno,
+ fa = xfs_btree_check_sblock_siblings(pag, agbno,
block->bb_u.s.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_sblock_siblings(pag, cur, level, agbno,
+ fa = xfs_btree_check_sblock_siblings(pag, agbno,
block->bb_u.s.bb_rightsib);
return fa;
}
@@ -4710,10 +4703,10 @@ xfs_btree_sblock_verify(
/* sibling pointer verification */
agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_sblock_siblings(bp->b_pag, NULL, -1, agbno,
+ fa = xfs_btree_check_sblock_siblings(bp->b_pag, agbno,
block->bb_u.s.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_sblock_siblings(bp->b_pag, NULL, -1, agbno,
+ fa = xfs_btree_check_sblock_siblings(bp->b_pag, agbno,
block->bb_u.s.bb_rightsib);
return fa;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 076/111] xfs: simplify xfs_btree_check_lblock_siblings
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (74 preceding siblings ...)
2024-05-22 3:08 ` [PATCH 075/111] xfs: simplify xfs_btree_check_sblock_siblings Darrick J. Wong
@ 2024-05-22 3:08 ` Darrick J. Wong
2024-05-22 3:08 ` [PATCH 077/111] xfs: open code xfs_btree_check_lptr in xfs_bmap_btree_to_extents Darrick J. Wong
` (35 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:08 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 8b8ada973cacff338a0e817a97dd0afa301798c0
Stop using xfs_btree_check_lptr in xfs_btree_check_lblock_siblings,
as it only duplicates the xfs_verify_fsbno call in the other leg of
if / else besides adding a tautological level check.
With this the cur and level arguments can be removed as they are
now unused.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 4ba36ecbb..55775ddf0 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -56,8 +56,6 @@ xfs_btree_magic(
static inline xfs_failaddr_t
xfs_btree_check_lblock_siblings(
struct xfs_mount *mp,
- struct xfs_btree_cur *cur,
- int level,
xfs_fsblock_t fsb,
__be64 dsibling)
{
@@ -69,14 +67,8 @@ xfs_btree_check_lblock_siblings(
sibling = be64_to_cpu(dsibling);
if (sibling == fsb)
return __this_address;
- if (level >= 0) {
- if (!xfs_btree_check_lptr(cur, sibling, level + 1))
- return __this_address;
- } else {
- if (!xfs_verify_fsbno(mp, sibling))
- return __this_address;
- }
-
+ if (!xfs_verify_fsbno(mp, sibling))
+ return __this_address;
return NULL;
}
@@ -136,10 +128,9 @@ __xfs_btree_check_lblock(
if (bp)
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_lblock_siblings(mp, cur, level, fsb,
- block->bb_u.l.bb_leftsib);
+ fa = xfs_btree_check_lblock_siblings(mp, fsb, block->bb_u.l.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_lblock_siblings(mp, cur, level, fsb,
+ fa = xfs_btree_check_lblock_siblings(mp, fsb,
block->bb_u.l.bb_rightsib);
return fa;
}
@@ -4648,10 +4639,9 @@ xfs_btree_lblock_verify(
/* sibling pointer verification */
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_lblock_siblings(mp, NULL, -1, fsb,
- block->bb_u.l.bb_leftsib);
+ fa = xfs_btree_check_lblock_siblings(mp, fsb, block->bb_u.l.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_lblock_siblings(mp, NULL, -1, fsb,
+ fa = xfs_btree_check_lblock_siblings(mp, fsb,
block->bb_u.l.bb_rightsib);
return fa;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 077/111] xfs: open code xfs_btree_check_lptr in xfs_bmap_btree_to_extents
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (75 preceding siblings ...)
2024-05-22 3:08 ` [PATCH 076/111] xfs: simplify xfs_btree_check_lblock_siblings Darrick J. Wong
@ 2024-05-22 3:08 ` Darrick J. Wong
2024-05-22 3:09 ` [PATCH 078/111] xfs: consolidate btree ptr checking Darrick J. Wong
` (34 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:08 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: fb0793f206701a68f8588a09bf32f7cf44878ea3
xfs_bmap_btree_to_extents always passes a level of 1 to
xfs_btree_check_lptr, thus making the level check redundant.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 2d332989b..86643f4c3 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -562,7 +562,7 @@ xfs_bmap_btree_to_extents(
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
cbno = be64_to_cpu(*pp);
#ifdef DEBUG
- if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) {
+ if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_verify_fsbno(mp, cbno))) {
xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 078/111] xfs: consolidate btree ptr checking
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (76 preceding siblings ...)
2024-05-22 3:08 ` [PATCH 077/111] xfs: open code xfs_btree_check_lptr in xfs_bmap_btree_to_extents Darrick J. Wong
@ 2024-05-22 3:09 ` Darrick J. Wong
2024-05-22 3:09 ` [PATCH 079/111] xfs: misc cleanups for __xfs_btree_check_sblock Darrick J. Wong
` (33 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:09 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 57982d6c835a71da5c66e6090680de1adf6e736a
Merge xfs_btree_check_sptr and xfs_btree_check_lptr into a single
__xfs_btree_check_ptr that can be shared between xfs_btree_check_ptr
and the scrub code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 60 +++++++++++++++++++++++++---------------------------
libxfs/xfs_btree.h | 21 +++---------------
2 files changed, 32 insertions(+), 49 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 55775ddf0..4fb167f57 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -239,28 +239,27 @@ xfs_btree_check_block(
return xfs_btree_check_sblock(cur, block, level, bp);
}
-/* Check that this long pointer is valid and points within the fs. */
-bool
-xfs_btree_check_lptr(
- struct xfs_btree_cur *cur,
- xfs_fsblock_t fsbno,
- int level)
+int
+__xfs_btree_check_ptr(
+ struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *ptr,
+ int index,
+ int level)
{
if (level <= 0)
- return false;
- return xfs_verify_fsbno(cur->bc_mp, fsbno);
-}
+ return -EFSCORRUPTED;
-/* Check that this short pointer is valid and points within the AG. */
-bool
-xfs_btree_check_sptr(
- struct xfs_btree_cur *cur,
- xfs_agblock_t agbno,
- int level)
-{
- if (level <= 0)
- return false;
- return xfs_verify_agbno(cur->bc_ag.pag, agbno);
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
+ if (!xfs_verify_fsbno(cur->bc_mp,
+ be64_to_cpu((&ptr->l)[index])))
+ return -EFSCORRUPTED;
+ } else {
+ if (!xfs_verify_agbno(cur->bc_ag.pag,
+ be32_to_cpu((&ptr->s)[index])))
+ return -EFSCORRUPTED;
+ }
+
+ return 0;
}
/*
@@ -274,27 +273,26 @@ xfs_btree_check_ptr(
int index,
int level)
{
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
- if (xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]),
- level))
- return 0;
- xfs_err(cur->bc_mp,
+ int error;
+
+ error = __xfs_btree_check_ptr(cur, ptr, index, level);
+ if (error) {
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
+ xfs_err(cur->bc_mp,
"Inode %llu fork %d: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ino.ip->i_ino,
cur->bc_ino.whichfork, cur->bc_ops->name,
level, index);
- } else {
- if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]),
- level))
- return 0;
- xfs_err(cur->bc_mp,
+ } else {
+ xfs_err(cur->bc_mp,
"AG %u: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ag.pag->pag_agno, cur->bc_ops->name,
level, index);
+ }
+ xfs_btree_mark_sick(cur);
}
- xfs_btree_mark_sick(cur);
- return -EFSCORRUPTED;
+ return error;
}
#ifdef DEBUG
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 9a264ffee..ca4a305eb 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -343,6 +343,9 @@ xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur,
xfs_failaddr_t __xfs_btree_check_sblock(struct xfs_btree_cur *cur,
struct xfs_btree_block *block, int level, struct xfs_buf *bp);
+int __xfs_btree_check_ptr(struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *ptr, int index, int level);
+
/*
* Check that block header is ok.
*/
@@ -353,24 +356,6 @@ xfs_btree_check_block(
int level, /* level of the btree block */
struct xfs_buf *bp); /* buffer containing block, if any */
-/*
- * Check that (long) pointer is ok.
- */
-bool /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lptr(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_fsblock_t fsbno, /* btree block disk address */
- int level); /* btree block level */
-
-/*
- * Check that (short) pointer is ok.
- */
-bool /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_sptr(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agblock_t agbno, /* btree block disk address */
- int level); /* btree block level */
-
/*
* Delete the btree cursor.
*/
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 079/111] xfs: misc cleanups for __xfs_btree_check_sblock
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (77 preceding siblings ...)
2024-05-22 3:09 ` [PATCH 078/111] xfs: consolidate btree ptr checking Darrick J. Wong
@ 2024-05-22 3:09 ` Darrick J. Wong
2024-05-22 3:09 ` [PATCH 080/111] xfs: remove the crc variable in __xfs_btree_check_lblock Darrick J. Wong
` (32 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:09 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 43be09192ce1f3cf9c3d2073e822a1d0a42fe5b2
Remove the local crc variable that is only used once and remove the bp
NULL checking as it can't ever be NULL for short form blocks.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 4fb167f57..359125a21 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -170,15 +170,13 @@ __xfs_btree_check_sblock(
{
struct xfs_mount *mp = cur->bc_mp;
struct xfs_perag *pag = cur->bc_ag.pag;
- bool crc = xfs_has_crc(mp);
xfs_failaddr_t fa;
- xfs_agblock_t agbno = NULLAGBLOCK;
+ xfs_agblock_t agbno;
- if (crc) {
+ if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
return __this_address;
- if (block->bb_u.s.bb_blkno !=
- cpu_to_be64(bp ? xfs_buf_daddr(bp) : XFS_BUF_DADDR_NULL))
+ if (block->bb_u.s.bb_blkno != cpu_to_be64(xfs_buf_daddr(bp)))
return __this_address;
}
@@ -190,9 +188,7 @@ __xfs_btree_check_sblock(
cur->bc_ops->get_maxrecs(cur, level))
return __this_address;
- if (bp)
- agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
-
+ agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_sblock_siblings(pag, agbno,
block->bb_u.s.bb_leftsib);
if (!fa)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 080/111] xfs: remove the crc variable in __xfs_btree_check_lblock
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (78 preceding siblings ...)
2024-05-22 3:09 ` [PATCH 079/111] xfs: misc cleanups for __xfs_btree_check_sblock Darrick J. Wong
@ 2024-05-22 3:09 ` Darrick J. Wong
2024-05-22 3:09 ` [PATCH 081/111] xfs: tighten up validation of root block in inode forks Darrick J. Wong
` (31 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:09 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: bd45019d9aa942d1c2457d96a7dbf2ad3051754b
crc is only used once, just use the xfs_has_crc check directly.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 359125a21..0b5002540 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -103,11 +103,10 @@ __xfs_btree_check_lblock(
struct xfs_buf *bp)
{
struct xfs_mount *mp = cur->bc_mp;
- bool crc = xfs_has_crc(mp);
xfs_failaddr_t fa;
xfs_fsblock_t fsb = NULLFSBLOCK;
- if (crc) {
+ if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
return __this_address;
if (block->bb_u.l.bb_blkno !=
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 081/111] xfs: tighten up validation of root block in inode forks
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (79 preceding siblings ...)
2024-05-22 3:09 ` [PATCH 080/111] xfs: remove the crc variable in __xfs_btree_check_lblock Darrick J. Wong
@ 2024-05-22 3:09 ` Darrick J. Wong
2024-05-22 3:10 ` [PATCH 082/111] xfs: consolidate btree block verification Darrick J. Wong
` (30 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:09 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: d477f1749f00899c71605ea01aba0ce67e030471
Check that root blocks that sit in the inode fork and thus have a NULL
bp don't have siblings.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 0b5002540..2f5848b9d 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -104,7 +104,7 @@ __xfs_btree_check_lblock(
{
struct xfs_mount *mp = cur->bc_mp;
xfs_failaddr_t fa;
- xfs_fsblock_t fsb = NULLFSBLOCK;
+ xfs_fsblock_t fsb;
if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -124,9 +124,19 @@ __xfs_btree_check_lblock(
cur->bc_ops->get_maxrecs(cur, level))
return __this_address;
- if (bp)
- fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
+ /*
+ * For inode-rooted btrees, the root block sits in the inode fork. In
+ * that case bp is NULL, and the block must not have any siblings.
+ */
+ if (!bp) {
+ if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK))
+ return __this_address;
+ if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK))
+ return __this_address;
+ return NULL;
+ }
+ fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_lblock_siblings(mp, fsb, block->bb_u.l.bb_leftsib);
if (!fa)
fa = xfs_btree_check_lblock_siblings(mp, fsb,
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 082/111] xfs: consolidate btree block verification
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (80 preceding siblings ...)
2024-05-22 3:09 ` [PATCH 081/111] xfs: tighten up validation of root block in inode forks Darrick J. Wong
@ 2024-05-22 3:10 ` Darrick J. Wong
2024-05-22 3:10 ` [PATCH 083/111] xfs: rename btree helpers that depends on the block number representation Darrick J. Wong
` (29 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:10 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 4ce0c711d9ab3a435bc605cd2f36a3f6b4e12c05
Add a __xfs_btree_check_block helper that can be called by the scrub code
to validate a btree block of any form, and move the duplicate error
handling code from xfs_btree_check_sblock and xfs_btree_check_lblock into
xfs_btree_check_block and thus remove these two helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 72 ++++++++++++++++++++++------------------------------
libxfs/xfs_btree.h | 9 +------
2 files changed, 31 insertions(+), 50 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 2f5848b9d..fae121ace 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -95,7 +95,7 @@ xfs_btree_check_sblock_siblings(
* Check a long btree block header. Return the address of the failing check,
* or NULL if everything is ok.
*/
-xfs_failaddr_t
+static xfs_failaddr_t
__xfs_btree_check_lblock(
struct xfs_btree_cur *cur,
struct xfs_btree_block *block,
@@ -144,33 +144,11 @@ __xfs_btree_check_lblock(
return fa;
}
-/* Check a long btree block header. */
-static int
-xfs_btree_check_lblock(
- struct xfs_btree_cur *cur,
- struct xfs_btree_block *block,
- int level,
- struct xfs_buf *bp)
-{
- struct xfs_mount *mp = cur->bc_mp;
- xfs_failaddr_t fa;
-
- fa = __xfs_btree_check_lblock(cur, block, level, bp);
- if (XFS_IS_CORRUPT(mp, fa != NULL) ||
- XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) {
- if (bp)
- trace_xfs_btree_corrupt(bp, _RET_IP_);
- xfs_btree_mark_sick(cur);
- return -EFSCORRUPTED;
- }
- return 0;
-}
-
/*
* Check a short btree block header. Return the address of the failing check,
* or NULL if everything is ok.
*/
-xfs_failaddr_t
+static xfs_failaddr_t
__xfs_btree_check_sblock(
struct xfs_btree_cur *cur,
struct xfs_btree_block *block,
@@ -206,26 +184,28 @@ __xfs_btree_check_sblock(
return fa;
}
-/* Check a short btree block header. */
-STATIC int
-xfs_btree_check_sblock(
+/*
+ * Internal btree block check.
+ *
+ * Return NULL if the block is ok or the address of the failed check otherwise.
+ */
+xfs_failaddr_t
+__xfs_btree_check_block(
struct xfs_btree_cur *cur,
struct xfs_btree_block *block,
int level,
struct xfs_buf *bp)
{
- struct xfs_mount *mp = cur->bc_mp;
- xfs_failaddr_t fa;
+ if (cur->bc_ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN)
+ return __xfs_btree_check_sblock(cur, block, level, bp);
+ return __xfs_btree_check_lblock(cur, block, level, bp);
+}
- fa = __xfs_btree_check_sblock(cur, block, level, bp);
- if (XFS_IS_CORRUPT(mp, fa != NULL) ||
- XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) {
- if (bp)
- trace_xfs_btree_corrupt(bp, _RET_IP_);
- xfs_btree_mark_sick(cur);
- return -EFSCORRUPTED;
- }
- return 0;
+static inline unsigned int xfs_btree_block_errtag(struct xfs_btree_cur *cur)
+{
+ if (cur->bc_ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN)
+ return XFS_ERRTAG_BTREE_CHECK_SBLOCK;
+ return XFS_ERRTAG_BTREE_CHECK_LBLOCK;
}
/*
@@ -238,10 +218,18 @@ xfs_btree_check_block(
int level, /* level of the btree block */
struct xfs_buf *bp) /* buffer containing block, if any */
{
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
- return xfs_btree_check_lblock(cur, block, level, bp);
- else
- return xfs_btree_check_sblock(cur, block, level, bp);
+ struct xfs_mount *mp = cur->bc_mp;
+ xfs_failaddr_t fa;
+
+ fa = __xfs_btree_check_block(cur, block, level, bp);
+ if (XFS_IS_CORRUPT(mp, fa != NULL) ||
+ XFS_TEST_ERROR(false, mp, xfs_btree_block_errtag(cur))) {
+ if (bp)
+ trace_xfs_btree_corrupt(bp, _RET_IP_);
+ xfs_btree_mark_sick(cur);
+ return -EFSCORRUPTED;
+ }
+ return 0;
}
int
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index ca4a305eb..d3afa6209 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -334,15 +334,8 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
*/
#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr))
-/*
- * Internal long and short btree block checks. They return NULL if the
- * block is ok or the address of the failed check otherwise.
- */
-xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur,
+xfs_failaddr_t __xfs_btree_check_block(struct xfs_btree_cur *cur,
struct xfs_btree_block *block, int level, struct xfs_buf *bp);
-xfs_failaddr_t __xfs_btree_check_sblock(struct xfs_btree_cur *cur,
- struct xfs_btree_block *block, int level, struct xfs_buf *bp);
-
int __xfs_btree_check_ptr(struct xfs_btree_cur *cur,
const union xfs_btree_ptr *ptr, int index, int level);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 083/111] xfs: rename btree helpers that depends on the block number representation
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (81 preceding siblings ...)
2024-05-22 3:10 ` [PATCH 082/111] xfs: consolidate btree block verification Darrick J. Wong
@ 2024-05-22 3:10 ` Darrick J. Wong
2024-05-22 3:10 ` [PATCH 084/111] xfs: factor out a __xfs_btree_check_lblock_hdr helper Darrick J. Wong
` (28 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:10 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 5ef819c34f954fccfc42f79b9b0bea9b40cef9a1
All these helpers hardcode fsblocks or agblocks and not just the pointer
size. Rename them so that the names are still fitting when we add the
long format in-memory blocks and adjust the checks when calling them to
check the btree types and not just pointer length.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_alloc_btree.c | 8 +++--
libxfs/xfs_bmap_btree.c | 8 +++--
libxfs/xfs_btree.c | 64 ++++++++++++++++++++++---------------------
libxfs/xfs_btree.h | 16 +++++------
libxfs/xfs_ialloc_btree.c | 8 +++--
libxfs/xfs_refcount_btree.c | 8 +++--
libxfs/xfs_rmap_btree.c | 8 +++--
7 files changed, 61 insertions(+), 59 deletions(-)
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 35d3dde42..949eb02cd 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -320,7 +320,7 @@ xfs_allocbt_verify(
return __this_address;
if (xfs_has_crc(mp)) {
- fa = xfs_btree_sblock_v5hdr_verify(bp);
+ fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa)
return fa;
}
@@ -360,7 +360,7 @@ xfs_allocbt_verify(
} else if (level >= mp->m_alloc_maxlevels)
return __this_address;
- return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]);
+ return xfs_btree_agblock_verify(bp, mp->m_alloc_mxr[level != 0]);
}
static void
@@ -369,7 +369,7 @@ xfs_allocbt_read_verify(
{
xfs_failaddr_t fa;
- if (!xfs_btree_sblock_verify_crc(bp))
+ if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else {
fa = xfs_allocbt_verify(bp);
@@ -393,7 +393,7 @@ xfs_allocbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return;
}
- xfs_btree_sblock_calc_crc(bp);
+ xfs_btree_agblock_calc_crc(bp);
}
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index eede6ffd6..2a603b4d1 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -419,7 +419,7 @@ xfs_bmbt_verify(
* XXX: need a better way of verifying the owner here. Right now
* just make sure there has been one set.
*/
- fa = xfs_btree_lblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN);
+ fa = xfs_btree_fsblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN);
if (fa)
return fa;
}
@@ -435,7 +435,7 @@ xfs_bmbt_verify(
if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1]))
return __this_address;
- return xfs_btree_lblock_verify(bp, mp->m_bmap_dmxr[level != 0]);
+ return xfs_btree_fsblock_verify(bp, mp->m_bmap_dmxr[level != 0]);
}
static void
@@ -444,7 +444,7 @@ xfs_bmbt_read_verify(
{
xfs_failaddr_t fa;
- if (!xfs_btree_lblock_verify_crc(bp))
+ if (!xfs_btree_fsblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else {
fa = xfs_bmbt_verify(bp);
@@ -468,7 +468,7 @@ xfs_bmbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return;
}
- xfs_btree_lblock_calc_crc(bp);
+ xfs_btree_fsblock_calc_crc(bp);
}
const struct xfs_buf_ops xfs_bmbt_buf_ops = {
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index fae121ace..e69b88b90 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -54,7 +54,7 @@ xfs_btree_magic(
* bytes.
*/
static inline xfs_failaddr_t
-xfs_btree_check_lblock_siblings(
+xfs_btree_check_fsblock_siblings(
struct xfs_mount *mp,
xfs_fsblock_t fsb,
__be64 dsibling)
@@ -73,7 +73,7 @@ xfs_btree_check_lblock_siblings(
}
static inline xfs_failaddr_t
-xfs_btree_check_sblock_siblings(
+xfs_btree_check_agblock_siblings(
struct xfs_perag *pag,
xfs_agblock_t agbno,
__be32 dsibling)
@@ -96,7 +96,7 @@ xfs_btree_check_sblock_siblings(
* or NULL if everything is ok.
*/
static xfs_failaddr_t
-__xfs_btree_check_lblock(
+__xfs_btree_check_fsblock(
struct xfs_btree_cur *cur,
struct xfs_btree_block *block,
int level,
@@ -137,9 +137,10 @@ __xfs_btree_check_lblock(
}
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_lblock_siblings(mp, fsb, block->bb_u.l.bb_leftsib);
+ fa = xfs_btree_check_fsblock_siblings(mp, fsb,
+ block->bb_u.l.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_lblock_siblings(mp, fsb,
+ fa = xfs_btree_check_fsblock_siblings(mp, fsb,
block->bb_u.l.bb_rightsib);
return fa;
}
@@ -149,7 +150,7 @@ __xfs_btree_check_lblock(
* or NULL if everything is ok.
*/
static xfs_failaddr_t
-__xfs_btree_check_sblock(
+__xfs_btree_check_agblock(
struct xfs_btree_cur *cur,
struct xfs_btree_block *block,
int level,
@@ -176,10 +177,10 @@ __xfs_btree_check_sblock(
return __this_address;
agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_sblock_siblings(pag, agbno,
+ fa = xfs_btree_check_agblock_siblings(pag, agbno,
block->bb_u.s.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_sblock_siblings(pag, agbno,
+ fa = xfs_btree_check_agblock_siblings(pag, agbno,
block->bb_u.s.bb_rightsib);
return fa;
}
@@ -196,9 +197,9 @@ __xfs_btree_check_block(
int level,
struct xfs_buf *bp)
{
- if (cur->bc_ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN)
- return __xfs_btree_check_sblock(cur, block, level, bp);
- return __xfs_btree_check_lblock(cur, block, level, bp);
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_AG)
+ return __xfs_btree_check_agblock(cur, block, level, bp);
+ return __xfs_btree_check_fsblock(cur, block, level, bp);
}
static inline unsigned int xfs_btree_block_errtag(struct xfs_btree_cur *cur)
@@ -242,7 +243,7 @@ __xfs_btree_check_ptr(
if (level <= 0)
return -EFSCORRUPTED;
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
if (!xfs_verify_fsbno(cur->bc_mp,
be64_to_cpu((&ptr->l)[index])))
return -EFSCORRUPTED;
@@ -270,7 +271,7 @@ xfs_btree_check_ptr(
error = __xfs_btree_check_ptr(cur, ptr, index, level);
if (error) {
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
xfs_err(cur->bc_mp,
"Inode %llu fork %d: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ino.ip->i_ino,
@@ -303,7 +304,7 @@ xfs_btree_check_ptr(
* it to disk.
*/
void
-xfs_btree_lblock_calc_crc(
+xfs_btree_fsblock_calc_crc(
struct xfs_buf *bp)
{
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
@@ -317,7 +318,7 @@ xfs_btree_lblock_calc_crc(
}
bool
-xfs_btree_lblock_verify_crc(
+xfs_btree_fsblock_verify_crc(
struct xfs_buf *bp)
{
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
@@ -341,7 +342,7 @@ xfs_btree_lblock_verify_crc(
* it to disk.
*/
void
-xfs_btree_sblock_calc_crc(
+xfs_btree_agblock_calc_crc(
struct xfs_buf *bp)
{
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
@@ -355,7 +356,7 @@ xfs_btree_sblock_calc_crc(
}
bool
-xfs_btree_sblock_verify_crc(
+xfs_btree_agblock_verify_crc(
struct xfs_buf *bp)
{
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
@@ -910,7 +911,7 @@ xfs_btree_reada_bufs(
}
STATIC int
-xfs_btree_readahead_lblock(
+xfs_btree_readahead_fsblock(
struct xfs_btree_cur *cur,
int lr,
struct xfs_btree_block *block)
@@ -935,7 +936,7 @@ xfs_btree_readahead_lblock(
}
STATIC int
-xfs_btree_readahead_sblock(
+xfs_btree_readahead_agblock(
struct xfs_btree_cur *cur,
int lr,
struct xfs_btree_block *block)
@@ -986,8 +987,8 @@ xfs_btree_readahead(
block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp);
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
- return xfs_btree_readahead_lblock(cur, lr, block);
- return xfs_btree_readahead_sblock(cur, lr, block);
+ return xfs_btree_readahead_fsblock(cur, lr, block);
+ return xfs_btree_readahead_agblock(cur, lr, block);
}
STATIC int
@@ -4594,7 +4595,7 @@ xfs_btree_change_owner(
/* Verify the v5 fields of a long-format btree block. */
xfs_failaddr_t
-xfs_btree_lblock_v5hdr_verify(
+xfs_btree_fsblock_v5hdr_verify(
struct xfs_buf *bp,
uint64_t owner)
{
@@ -4615,7 +4616,7 @@ xfs_btree_lblock_v5hdr_verify(
/* Verify a long-format btree block. */
xfs_failaddr_t
-xfs_btree_lblock_verify(
+xfs_btree_fsblock_verify(
struct xfs_buf *bp,
unsigned int max_recs)
{
@@ -4630,21 +4631,22 @@ xfs_btree_lblock_verify(
/* sibling pointer verification */
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_lblock_siblings(mp, fsb, block->bb_u.l.bb_leftsib);
+ fa = xfs_btree_check_fsblock_siblings(mp, fsb,
+ block->bb_u.l.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_lblock_siblings(mp, fsb,
+ fa = xfs_btree_check_fsblock_siblings(mp, fsb,
block->bb_u.l.bb_rightsib);
return fa;
}
/**
- * xfs_btree_sblock_v5hdr_verify() -- verify the v5 fields of a short-format
+ * xfs_btree_agblock_v5hdr_verify() -- verify the v5 fields of a short-format
* btree block
*
* @bp: buffer containing the btree block
*/
xfs_failaddr_t
-xfs_btree_sblock_v5hdr_verify(
+xfs_btree_agblock_v5hdr_verify(
struct xfs_buf *bp)
{
struct xfs_mount *mp = bp->b_mount;
@@ -4663,13 +4665,13 @@ xfs_btree_sblock_v5hdr_verify(
}
/**
- * xfs_btree_sblock_verify() -- verify a short-format btree block
+ * xfs_btree_agblock_verify() -- verify a short-format btree block
*
* @bp: buffer containing the btree block
* @max_recs: maximum records allowed in this btree node
*/
xfs_failaddr_t
-xfs_btree_sblock_verify(
+xfs_btree_agblock_verify(
struct xfs_buf *bp,
unsigned int max_recs)
{
@@ -4684,10 +4686,10 @@ xfs_btree_sblock_verify(
/* sibling pointer verification */
agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
- fa = xfs_btree_check_sblock_siblings(bp->b_pag, agbno,
+ fa = xfs_btree_check_agblock_siblings(bp->b_pag, agbno,
block->bb_u.s.bb_leftsib);
if (!fa)
- fa = xfs_btree_check_sblock_siblings(bp->b_pag, agbno,
+ fa = xfs_btree_check_agblock_siblings(bp->b_pag, agbno,
block->bb_u.s.bb_rightsib);
return fa;
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index d3afa6209..b9b46a573 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -441,10 +441,10 @@ int xfs_btree_change_owner(struct xfs_btree_cur *cur, uint64_t new_owner,
/*
* btree block CRC helpers
*/
-void xfs_btree_lblock_calc_crc(struct xfs_buf *);
-bool xfs_btree_lblock_verify_crc(struct xfs_buf *);
-void xfs_btree_sblock_calc_crc(struct xfs_buf *);
-bool xfs_btree_sblock_verify_crc(struct xfs_buf *);
+void xfs_btree_fsblock_calc_crc(struct xfs_buf *);
+bool xfs_btree_fsblock_verify_crc(struct xfs_buf *);
+void xfs_btree_agblock_calc_crc(struct xfs_buf *);
+bool xfs_btree_agblock_verify_crc(struct xfs_buf *);
/*
* Internal btree helpers also used by xfs_bmap.c.
@@ -484,12 +484,12 @@ static inline int xfs_btree_get_level(const struct xfs_btree_block *block)
#define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b))
#define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b))
-xfs_failaddr_t xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp);
-xfs_failaddr_t xfs_btree_sblock_verify(struct xfs_buf *bp,
+xfs_failaddr_t xfs_btree_agblock_v5hdr_verify(struct xfs_buf *bp);
+xfs_failaddr_t xfs_btree_agblock_verify(struct xfs_buf *bp,
unsigned int max_recs);
-xfs_failaddr_t xfs_btree_lblock_v5hdr_verify(struct xfs_buf *bp,
+xfs_failaddr_t xfs_btree_fsblock_v5hdr_verify(struct xfs_buf *bp,
uint64_t owner);
-xfs_failaddr_t xfs_btree_lblock_verify(struct xfs_buf *bp,
+xfs_failaddr_t xfs_btree_fsblock_verify(struct xfs_buf *bp,
unsigned int max_recs);
unsigned int xfs_btree_compute_maxlevels(const unsigned int *limits,
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index cb0a7c779..58c520ecb 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -308,7 +308,7 @@ xfs_inobt_verify(
* xfs_perag_initialised_agi(pag)) if we ever do.
*/
if (xfs_has_crc(mp)) {
- fa = xfs_btree_sblock_v5hdr_verify(bp);
+ fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa)
return fa;
}
@@ -318,7 +318,7 @@ xfs_inobt_verify(
if (level >= M_IGEO(mp)->inobt_maxlevels)
return __this_address;
- return xfs_btree_sblock_verify(bp,
+ return xfs_btree_agblock_verify(bp,
M_IGEO(mp)->inobt_mxr[level != 0]);
}
@@ -328,7 +328,7 @@ xfs_inobt_read_verify(
{
xfs_failaddr_t fa;
- if (!xfs_btree_sblock_verify_crc(bp))
+ if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else {
fa = xfs_inobt_verify(bp);
@@ -352,7 +352,7 @@ xfs_inobt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return;
}
- xfs_btree_sblock_calc_crc(bp);
+ xfs_btree_agblock_calc_crc(bp);
}
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 6ec0e36e5..362b2a2d7 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -216,7 +216,7 @@ xfs_refcountbt_verify(
if (!xfs_has_reflink(mp))
return __this_address;
- fa = xfs_btree_sblock_v5hdr_verify(bp);
+ fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa)
return fa;
@@ -238,7 +238,7 @@ xfs_refcountbt_verify(
} else if (level >= mp->m_refc_maxlevels)
return __this_address;
- return xfs_btree_sblock_verify(bp, mp->m_refc_mxr[level != 0]);
+ return xfs_btree_agblock_verify(bp, mp->m_refc_mxr[level != 0]);
}
STATIC void
@@ -247,7 +247,7 @@ xfs_refcountbt_read_verify(
{
xfs_failaddr_t fa;
- if (!xfs_btree_sblock_verify_crc(bp))
+ if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else {
fa = xfs_refcountbt_verify(bp);
@@ -271,7 +271,7 @@ xfs_refcountbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return;
}
- xfs_btree_sblock_calc_crc(bp);
+ xfs_btree_agblock_calc_crc(bp);
}
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 18168db6e..2b7504f7a 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -334,7 +334,7 @@ xfs_rmapbt_verify(
if (!xfs_has_rmapbt(mp))
return __this_address;
- fa = xfs_btree_sblock_v5hdr_verify(bp);
+ fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa)
return fa;
@@ -345,7 +345,7 @@ xfs_rmapbt_verify(
} else if (level >= mp->m_rmap_maxlevels)
return __this_address;
- return xfs_btree_sblock_verify(bp, mp->m_rmap_mxr[level != 0]);
+ return xfs_btree_agblock_verify(bp, mp->m_rmap_mxr[level != 0]);
}
static void
@@ -354,7 +354,7 @@ xfs_rmapbt_read_verify(
{
xfs_failaddr_t fa;
- if (!xfs_btree_sblock_verify_crc(bp))
+ if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else {
fa = xfs_rmapbt_verify(bp);
@@ -378,7 +378,7 @@ xfs_rmapbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return;
}
- xfs_btree_sblock_calc_crc(bp);
+ xfs_btree_agblock_calc_crc(bp);
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 084/111] xfs: factor out a __xfs_btree_check_lblock_hdr helper
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (82 preceding siblings ...)
2024-05-22 3:10 ` [PATCH 083/111] xfs: rename btree helpers that depends on the block number representation Darrick J. Wong
@ 2024-05-22 3:10 ` Darrick J. Wong
2024-05-22 3:10 ` [PATCH 085/111] xfs: remove xfs_btree_reada_bufl Darrick J. Wong
` (27 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:10 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 79e72304dcba471e5c0dea2f3c67fe1a0558c140
This will allow sharing code with the in-memory block checking helper.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index e69b88b90..6b1839243 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -91,20 +91,14 @@ xfs_btree_check_agblock_siblings(
return NULL;
}
-/*
- * Check a long btree block header. Return the address of the failing check,
- * or NULL if everything is ok.
- */
static xfs_failaddr_t
-__xfs_btree_check_fsblock(
+__xfs_btree_check_lblock_hdr(
struct xfs_btree_cur *cur,
struct xfs_btree_block *block,
int level,
struct xfs_buf *bp)
{
struct xfs_mount *mp = cur->bc_mp;
- xfs_failaddr_t fa;
- xfs_fsblock_t fsb;
if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -124,6 +118,28 @@ __xfs_btree_check_fsblock(
cur->bc_ops->get_maxrecs(cur, level))
return __this_address;
+ return NULL;
+}
+
+/*
+ * Check a long btree block header. Return the address of the failing check,
+ * or NULL if everything is ok.
+ */
+static xfs_failaddr_t
+__xfs_btree_check_fsblock(
+ struct xfs_btree_cur *cur,
+ struct xfs_btree_block *block,
+ int level,
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = cur->bc_mp;
+ xfs_failaddr_t fa;
+ xfs_fsblock_t fsb;
+
+ fa = __xfs_btree_check_lblock_hdr(cur, block, level, bp);
+ if (fa)
+ return fa;
+
/*
* For inode-rooted btrees, the root block sits in the inode fork. In
* that case bp is NULL, and the block must not have any siblings.
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 085/111] xfs: remove xfs_btree_reada_bufl
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (83 preceding siblings ...)
2024-05-22 3:10 ` [PATCH 084/111] xfs: factor out a __xfs_btree_check_lblock_hdr helper Darrick J. Wong
@ 2024-05-22 3:10 ` Darrick J. Wong
2024-05-22 3:11 ` [PATCH 086/111] xfs: remove xfs_btree_reada_bufs Darrick J. Wong
` (26 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:10 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 5eec8fa30dfa548d07332756101053f47f6ba26c
xfs_btree_reada_bufl just wraps xfs_btree_readahead and a fsblock
to daddr conversion. Just open code it's two callsites in the only
caller.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 30 ++++++------------------------
libxfs/xfs_btree.h | 11 -----------
2 files changed, 6 insertions(+), 35 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 6b1839243..2bef2f3e2 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -886,25 +886,6 @@ xfs_btree_read_bufl(
return 0;
}
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Long-form addressing.
- */
-/* ARGSUSED */
-void
-xfs_btree_reada_bufl(
- struct xfs_mount *mp, /* file system mount point */
- xfs_fsblock_t fsbno, /* file system block number */
- xfs_extlen_t count, /* count of filesystem blocks */
- const struct xfs_buf_ops *ops)
-{
- xfs_daddr_t d;
-
- ASSERT(fsbno != NULLFSBLOCK);
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
-}
-
/*
* Read-ahead the block, don't wait for it, don't return a buffer.
* Short-form addressing.
@@ -932,19 +913,20 @@ xfs_btree_readahead_fsblock(
int lr,
struct xfs_btree_block *block)
{
- int rval = 0;
+ struct xfs_mount *mp = cur->bc_mp;
xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib);
xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib);
+ int rval = 0;
if ((lr & XFS_BTCUR_LEFTRA) && left != NULLFSBLOCK) {
- xfs_btree_reada_bufl(cur->bc_mp, left, 1,
- cur->bc_ops->buf_ops);
+ xfs_buf_readahead(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, left),
+ mp->m_bsize, cur->bc_ops->buf_ops);
rval++;
}
if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLFSBLOCK) {
- xfs_btree_reada_bufl(cur->bc_mp, right, 1,
- cur->bc_ops->buf_ops);
+ xfs_buf_readahead(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, right),
+ mp->m_bsize, cur->bc_ops->buf_ops);
rval++;
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index b9b46a573..001ff9392 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -391,17 +391,6 @@ xfs_btree_read_bufl(
int refval, /* ref count value for buffer */
const struct xfs_buf_ops *ops);
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Long-form addressing.
- */
-void /* error */
-xfs_btree_reada_bufl(
- struct xfs_mount *mp, /* file system mount point */
- xfs_fsblock_t fsbno, /* file system block number */
- xfs_extlen_t count, /* count of filesystem blocks */
- const struct xfs_buf_ops *ops);
-
/*
* Read-ahead the block, don't wait for it, don't return a buffer.
* Short-form addressing.
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 086/111] xfs: remove xfs_btree_reada_bufs
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (84 preceding siblings ...)
2024-05-22 3:10 ` [PATCH 085/111] xfs: remove xfs_btree_reada_bufl Darrick J. Wong
@ 2024-05-22 3:11 ` Darrick J. Wong
2024-05-22 3:11 ` [PATCH 087/111] xfs: move and rename xfs_btree_read_bufl Darrick J. Wong
` (25 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:11 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 6324b00c9ecb8d11a157d2a4bc3e5a495534bdf1
xfs_btree_reada_bufl just wraps xfs_btree_readahead and a agblock
to daddr conversion. Just open code it's three callsites in the
two callers (One of which isn't even btree related).
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 38 ++++++++++----------------------------
libxfs/xfs_btree.h | 12 ------------
2 files changed, 10 insertions(+), 40 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 2bef2f3e2..7168a5753 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -886,27 +886,6 @@ xfs_btree_read_bufl(
return 0;
}
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Short-form addressing.
- */
-/* ARGSUSED */
-void
-xfs_btree_reada_bufs(
- struct xfs_mount *mp, /* file system mount point */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- xfs_extlen_t count, /* count of filesystem blocks */
- const struct xfs_buf_ops *ops)
-{
- xfs_daddr_t d;
-
- ASSERT(agno != NULLAGNUMBER);
- ASSERT(agbno != NULLAGBLOCK);
- d = XFS_AGB_TO_DADDR(mp, agno, agbno);
- xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
-}
-
STATIC int
xfs_btree_readahead_fsblock(
struct xfs_btree_cur *cur,
@@ -937,22 +916,25 @@ STATIC int
xfs_btree_readahead_agblock(
struct xfs_btree_cur *cur,
int lr,
- struct xfs_btree_block *block)
+ struct xfs_btree_block *block)
{
- int rval = 0;
+ struct xfs_mount *mp = cur->bc_mp;
+ xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno;
xfs_agblock_t left = be32_to_cpu(block->bb_u.s.bb_leftsib);
xfs_agblock_t right = be32_to_cpu(block->bb_u.s.bb_rightsib);
-
+ int rval = 0;
if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
- xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.pag->pag_agno,
- left, 1, cur->bc_ops->buf_ops);
+ xfs_buf_readahead(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, left),
+ mp->m_bsize, cur->bc_ops->buf_ops);
rval++;
}
if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
- xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.pag->pag_agno,
- right, 1, cur->bc_ops->buf_ops);
+ xfs_buf_readahead(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, right),
+ mp->m_bsize, cur->bc_ops->buf_ops);
rval++;
}
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index 001ff9392..c48b4fdeb 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -391,18 +391,6 @@ xfs_btree_read_bufl(
int refval, /* ref count value for buffer */
const struct xfs_buf_ops *ops);
-/*
- * Read-ahead the block, don't wait for it, don't return a buffer.
- * Short-form addressing.
- */
-void /* error */
-xfs_btree_reada_bufs(
- struct xfs_mount *mp, /* file system mount point */
- xfs_agnumber_t agno, /* allocation group number */
- xfs_agblock_t agbno, /* allocation group block number */
- xfs_extlen_t count, /* count of filesystem blocks */
- const struct xfs_buf_ops *ops);
-
/*
* Initialise a new btree block header
*/
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 087/111] xfs: move and rename xfs_btree_read_bufl
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (85 preceding siblings ...)
2024-05-22 3:11 ` [PATCH 086/111] xfs: remove xfs_btree_reada_bufs Darrick J. Wong
@ 2024-05-22 3:11 ` Darrick J. Wong
2024-05-22 3:11 ` [PATCH 088/111] libxfs: teach buftargs to maintain their own buffer hashtable Darrick J. Wong
` (24 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:11 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 6a701eb8fbbb5f500684947883fd77ed0475fa82
Despite its name, xfs_btree_read_bufl doesn't contain any btree-related
functionaliy and isn't used by the btree code. Move it to xfs_bmap.c,
hard code the refval and ops arguments and rename it to
xfs_bmap_read_buf.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_bmap.c | 33 +++++++++++++++++++++++++--------
libxfs/xfs_btree.c | 30 ------------------------------
libxfs/xfs_btree.h | 13 -------------
3 files changed, 25 insertions(+), 51 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 86643f4c3..4790efd3d 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -220,6 +220,28 @@ xfs_bmap_forkoff_reset(
}
}
+static int
+xfs_bmap_read_buf(
+ struct xfs_mount *mp, /* file system mount point */
+ struct xfs_trans *tp, /* transaction pointer */
+ xfs_fsblock_t fsbno, /* file system block number */
+ struct xfs_buf **bpp) /* buffer for fsbno */
+{
+ struct xfs_buf *bp; /* return value */
+ int error;
+
+ if (!xfs_verify_fsbno(mp, fsbno))
+ return -EFSCORRUPTED;
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
+ XFS_FSB_TO_DADDR(mp, fsbno), mp->m_bsize, 0, &bp,
+ &xfs_bmbt_buf_ops);
+ if (!error) {
+ xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF);
+ *bpp = bp;
+ }
+ return error;
+}
+
#ifdef DEBUG
STATIC struct xfs_buf *
xfs_bmap_get_bp(
@@ -359,9 +381,7 @@ xfs_bmap_check_leaf_extents(
bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
if (!bp) {
bp_release = 1;
- error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
- XFS_BMAP_BTREE_REF,
- &xfs_bmbt_buf_ops);
+ error = xfs_bmap_read_buf(mp, NULL, bno, &bp);
if (xfs_metadata_is_sick(error))
xfs_btree_mark_sick(cur);
if (error)
@@ -448,9 +468,7 @@ xfs_bmap_check_leaf_extents(
bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
if (!bp) {
bp_release = 1;
- error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
- XFS_BMAP_BTREE_REF,
- &xfs_bmbt_buf_ops);
+ error = xfs_bmap_read_buf(mp, NULL, bno, &bp);
if (xfs_metadata_is_sick(error))
xfs_btree_mark_sick(cur);
if (error)
@@ -567,8 +585,7 @@ xfs_bmap_btree_to_extents(
return -EFSCORRUPTED;
}
#endif
- error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
- &xfs_bmbt_buf_ops);
+ error = xfs_bmap_read_buf(mp, tp, cbno, &cbp);
if (xfs_metadata_is_sick(error))
xfs_btree_mark_sick(cur);
if (error)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 7168a5753..a989b2da2 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -856,36 +856,6 @@ xfs_btree_offsets(
}
}
-/*
- * Get a buffer for the block, return it read in.
- * Long-form addressing.
- */
-int
-xfs_btree_read_bufl(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_fsblock_t fsbno, /* file system block number */
- struct xfs_buf **bpp, /* buffer for fsbno */
- int refval, /* ref count value for buffer */
- const struct xfs_buf_ops *ops)
-{
- struct xfs_buf *bp; /* return value */
- xfs_daddr_t d; /* real disk block address */
- int error;
-
- if (!xfs_verify_fsbno(mp, fsbno))
- return -EFSCORRUPTED;
- d = XFS_FSB_TO_DADDR(mp, fsbno);
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
- mp->m_bsize, 0, &bp, ops);
- if (error)
- return error;
- if (bp)
- xfs_buf_set_ref(bp, refval);
- *bpp = bp;
- return 0;
-}
-
STATIC int
xfs_btree_readahead_fsblock(
struct xfs_btree_cur *cur,
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index c48b4fdeb..bacd67cc8 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -378,19 +378,6 @@ xfs_btree_offsets(
int *first, /* output: first byte offset */
int *last); /* output: last byte offset */
-/*
- * Get a buffer for the block, return it read in.
- * Long-form addressing.
- */
-int /* error */
-xfs_btree_read_bufl(
- struct xfs_mount *mp, /* file system mount point */
- struct xfs_trans *tp, /* transaction pointer */
- xfs_fsblock_t fsbno, /* file system block number */
- struct xfs_buf **bpp, /* buffer for fsbno */
- int refval, /* ref count value for buffer */
- const struct xfs_buf_ops *ops);
-
/*
* Initialise a new btree block header
*/
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 088/111] libxfs: teach buftargs to maintain their own buffer hashtable
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (86 preceding siblings ...)
2024-05-22 3:11 ` [PATCH 087/111] xfs: move and rename xfs_btree_read_bufl Darrick J. Wong
@ 2024-05-22 3:11 ` Darrick J. Wong
2024-05-22 3:11 ` [PATCH 089/111] libxfs: add xfile support Darrick J. Wong
` (23 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:11 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Currently, cached buffers are indexed with a single global bcache
structure. This works ok for the limited use case where we only support
reading from the data device, but will fail badly when we want to
support buffers from in-memory btrees. Move the bcache structure into
the buftarg.
As a side effect, we don't need to compare buftarg->bt_bdev anymore
since libxfs is careful enough not to create more than one buftarg per
open fd.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/libxfs.h | 1 -
libxfs/init.c | 48 +++++++++++++++++++++---------------------------
libxfs/libxfs_io.h | 10 ++++++----
libxfs/logitem.c | 2 +-
libxfs/rdwr.c | 45 +++++++++++++++++++++++++++++----------------
mkfs/xfs_mkfs.c | 2 +-
repair/prefetch.c | 12 ++++++++----
repair/prefetch.h | 1 +
repair/progress.c | 14 +++++++++-----
repair/progress.h | 2 +-
repair/scan.c | 2 +-
repair/xfs_repair.c | 32 +++++++++++++++++---------------
12 files changed, 95 insertions(+), 76 deletions(-)
diff --git a/include/libxfs.h b/include/libxfs.h
index aeec2bc76..60d3b7968 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -147,7 +147,6 @@ int libxfs_init(struct libxfs_init *);
void libxfs_destroy(struct libxfs_init *li);
extern int libxfs_device_alignment (void);
-extern void libxfs_report(FILE *);
/* check or write log footer: specify device, log size in blocks & uuid */
typedef char *(libxfs_get_block_t)(char *, int, void *);
diff --git a/libxfs/init.c b/libxfs/init.c
index b2d7bc136..eaeb0b666 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -36,7 +36,6 @@ pthread_mutex_t atomic64_lock = PTHREAD_MUTEX_INITIALIZER;
char *progname = "libxfs"; /* default, changed by each tool */
-struct cache *libxfs_bcache; /* global buffer cache */
int libxfs_bhash_size; /* #buckets in bcache */
int use_xfs_buf_lock; /* global flag: use xfs_buf locks for MT */
@@ -267,8 +266,6 @@ libxfs_init(struct libxfs_init *a)
if (!libxfs_bhash_size)
libxfs_bhash_size = LIBXFS_BHASHSIZE(sbp);
- libxfs_bcache = cache_init(a->bcache_flags, libxfs_bhash_size,
- &libxfs_bcache_operations);
use_xfs_buf_lock = a->flags & LIBXFS_USEBUFLOCK;
xfs_dir_startup();
init_caches();
@@ -451,6 +448,7 @@ xfs_set_inode_alloc(
static struct xfs_buftarg *
libxfs_buftarg_alloc(
struct xfs_mount *mp,
+ struct libxfs_init *xi,
struct libxfs_dev *dev,
unsigned long write_fails)
{
@@ -472,6 +470,9 @@ libxfs_buftarg_alloc(
}
pthread_mutex_init(&btp->lock, NULL);
+ btp->bcache = cache_init(xi->bcache_flags, libxfs_bhash_size,
+ &libxfs_bcache_operations);
+
return btp;
}
@@ -568,12 +569,13 @@ libxfs_buftarg_init(
return;
}
- mp->m_ddev_targp = libxfs_buftarg_alloc(mp, &xi->data, dfail);
+ mp->m_ddev_targp = libxfs_buftarg_alloc(mp, xi, &xi->data, dfail);
if (!xi->log.dev || xi->log.dev == xi->data.dev)
mp->m_logdev_targp = mp->m_ddev_targp;
else
- mp->m_logdev_targp = libxfs_buftarg_alloc(mp, &xi->log, lfail);
- mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, &xi->rt, rfail);
+ mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log,
+ lfail);
+ mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt, rfail);
}
/* Compute maximum possible height for per-AG btree types for this fs. */
@@ -856,7 +858,7 @@ libxfs_flush_mount(
* LOST_WRITE flag to be set in the buftarg. Once that's done,
* instruct the disks to persist their write caches.
*/
- libxfs_bcache_flush();
+ libxfs_bcache_flush(mp);
/* Flush all kernel and disk write caches, and report failures. */
if (mp->m_ddev_targp) {
@@ -882,6 +884,14 @@ libxfs_flush_mount(
return error;
}
+static void
+libxfs_buftarg_free(
+ struct xfs_buftarg *btp)
+{
+ cache_destroy(btp->bcache);
+ kmem_free(btp);
+}
+
/*
* Release any resource obtained during a mount.
*/
@@ -898,7 +908,7 @@ libxfs_umount(
* all incore buffers, then pick up the outcome when we tell the disks
* to persist their write caches.
*/
- libxfs_bcache_purge();
+ libxfs_bcache_purge(mp);
error = libxfs_flush_mount(mp);
/*
@@ -913,10 +923,10 @@ libxfs_umount(
free(mp->m_fsname);
mp->m_fsname = NULL;
- kmem_free(mp->m_rtdev_targp);
+ libxfs_buftarg_free(mp->m_rtdev_targp);
if (mp->m_logdev_targp != mp->m_ddev_targp)
- kmem_free(mp->m_logdev_targp);
- kmem_free(mp->m_ddev_targp);
+ libxfs_buftarg_free(mp->m_logdev_targp);
+ libxfs_buftarg_free(mp->m_ddev_targp);
return error;
}
@@ -932,10 +942,7 @@ libxfs_destroy(
libxfs_close_devices(li);
- /* Free everything from the buffer cache before freeing buffer cache */
- libxfs_bcache_purge();
libxfs_bcache_free();
- cache_destroy(libxfs_bcache);
leaked = destroy_caches();
rcu_unregister_thread();
if (getenv("LIBXFS_LEAK_CHECK") && leaked)
@@ -947,16 +954,3 @@ libxfs_device_alignment(void)
{
return platform_align_blockdev();
}
-
-void
-libxfs_report(FILE *fp)
-{
- time_t t;
- char *c;
-
- cache_report(fp, "libxfs_bcache", libxfs_bcache);
-
- t = time(NULL);
- c = asctime(localtime(&t));
- fprintf(fp, "%s", c);
-}
diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index 259c6a7cf..7877e1768 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -28,6 +28,7 @@ struct xfs_buftarg {
dev_t bt_bdev;
int bt_bdev_fd;
unsigned int flags;
+ struct cache *bcache; /* buffer cache */
};
/* We purged a dirty buffer and lost a write. */
@@ -36,6 +37,8 @@ struct xfs_buftarg {
#define XFS_BUFTARG_CORRUPT_WRITE (1 << 1)
/* Simulate failure after a certain number of writes. */
#define XFS_BUFTARG_INJECT_WRITE_FAIL (1 << 2)
+/* purge buffers when lookups find a size mismatch */
+#define XFS_BUFTARG_MISCOMPARE_PURGE (1 << 3)
/* Simulate the system crashing after a certain number of writes. */
static inline void
@@ -140,7 +143,6 @@ int libxfs_buf_priority(struct xfs_buf *bp);
/* Buffer Cache Interfaces */
-extern struct cache *libxfs_bcache;
extern struct cache_operations libxfs_bcache_operations;
#define LIBXFS_GETBUF_TRYLOCK (1 << 0)
@@ -184,10 +186,10 @@ libxfs_buf_read(
int libxfs_readbuf_verify(struct xfs_buf *bp, const struct xfs_buf_ops *ops);
struct xfs_buf *libxfs_getsb(struct xfs_mount *mp);
-extern void libxfs_bcache_purge(void);
+extern void libxfs_bcache_purge(struct xfs_mount *mp);
extern void libxfs_bcache_free(void);
-extern void libxfs_bcache_flush(void);
-extern int libxfs_bcache_overflowed(void);
+extern void libxfs_bcache_flush(struct xfs_mount *mp);
+extern int libxfs_bcache_overflowed(struct xfs_mount *mp);
/* Buffer (Raw) Interfaces */
int libxfs_bwrite(struct xfs_buf *bp);
diff --git a/libxfs/logitem.c b/libxfs/logitem.c
index 3ce2d7574..7757259df 100644
--- a/libxfs/logitem.c
+++ b/libxfs/logitem.c
@@ -46,7 +46,7 @@ xfs_trans_buf_item_match(
list_for_each_entry(lip, &tp->t_items, li_trans) {
blip = (struct xfs_buf_log_item *)lip;
if (blip->bli_item.li_type == XFS_LI_BUF &&
- blip->bli_buf->b_target->bt_bdev == btp->bt_bdev &&
+ blip->bli_buf->b_target == btp &&
xfs_buf_daddr(blip->bli_buf) == map[0].bm_bn &&
blip->bli_buf->b_length == len) {
ASSERT(blip->bli_buf->b_map_count == nmaps);
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 153007d5f..cf986a7e7 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -198,18 +198,20 @@ libxfs_bhash(cache_key_t key, unsigned int hashsize, unsigned int hashshift)
}
static int
-libxfs_bcompare(struct cache_node *node, cache_key_t key)
+libxfs_bcompare(
+ struct cache_node *node,
+ cache_key_t key)
{
struct xfs_buf *bp = container_of(node, struct xfs_buf,
b_node);
struct xfs_bufkey *bkey = (struct xfs_bufkey *)key;
+ struct cache *bcache = bkey->buftarg->bcache;
- if (bp->b_target->bt_bdev == bkey->buftarg->bt_bdev &&
- bp->b_cache_key == bkey->blkno) {
+ if (bp->b_cache_key == bkey->blkno) {
if (bp->b_length == bkey->bblen)
return CACHE_HIT;
#ifdef IO_BCOMPARE_CHECK
- if (!(libxfs_bcache->c_flags & CACHE_MISCOMPARE_PURGE)) {
+ if (!(bcache->c_flags & CACHE_MISCOMPARE_PURGE)) {
fprintf(stderr,
"%lx: Badness in key lookup (length)\n"
"bp=(bno 0x%llx, len %u bytes) key=(bno 0x%llx, len %u bytes)\n",
@@ -399,11 +401,12 @@ __cache_lookup(
struct xfs_buf **bpp)
{
struct cache_node *cn = NULL;
+ struct cache *bcache = key->buftarg->bcache;
struct xfs_buf *bp;
*bpp = NULL;
- cache_node_get(libxfs_bcache, key, &cn);
+ cache_node_get(bcache, key, &cn);
if (!cn)
return -ENOMEM;
bp = container_of(cn, struct xfs_buf, b_node);
@@ -415,7 +418,7 @@ __cache_lookup(
if (ret) {
ASSERT(ret == EAGAIN);
if (flags & LIBXFS_GETBUF_TRYLOCK) {
- cache_node_put(libxfs_bcache, cn);
+ cache_node_put(bcache, cn);
return -EAGAIN;
}
@@ -434,7 +437,7 @@ __cache_lookup(
bp->b_holder = pthread_self();
}
- cache_node_set_priority(libxfs_bcache, cn,
+ cache_node_set_priority(bcache, cn,
cache_node_get_priority(cn) - CACHE_PREFETCH_PRIORITY);
*bpp = bp;
return 0;
@@ -550,7 +553,7 @@ libxfs_buf_relse(
}
if (!list_empty(&bp->b_node.cn_hash))
- cache_node_put(libxfs_bcache, &bp->b_node);
+ cache_node_put(bp->b_target->bcache, &bp->b_node);
else if (--bp->b_node.cn_count == 0) {
if (bp->b_flags & LIBXFS_B_DIRTY)
libxfs_bwrite(bp);
@@ -606,7 +609,7 @@ libxfs_readbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, struct xfs_buf *bp,
error = __read_buf(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno), flags);
if (!error &&
- bp->b_target->bt_bdev == btp->bt_bdev &&
+ bp->b_target == btp &&
bp->b_cache_key == blkno &&
bp->b_length == len)
bp->b_flags |= LIBXFS_B_UPTODATE;
@@ -1003,21 +1006,31 @@ libxfs_bflush(
}
void
-libxfs_bcache_purge(void)
+libxfs_bcache_purge(struct xfs_mount *mp)
{
- cache_purge(libxfs_bcache);
+ if (!mp)
+ return;
+ cache_purge(mp->m_ddev_targp->bcache);
+ cache_purge(mp->m_logdev_targp->bcache);
+ cache_purge(mp->m_rtdev_targp->bcache);
}
void
-libxfs_bcache_flush(void)
+libxfs_bcache_flush(struct xfs_mount *mp)
{
- cache_flush(libxfs_bcache);
+ if (!mp)
+ return;
+ cache_flush(mp->m_ddev_targp->bcache);
+ cache_flush(mp->m_logdev_targp->bcache);
+ cache_flush(mp->m_rtdev_targp->bcache);
}
int
-libxfs_bcache_overflowed(void)
+libxfs_bcache_overflowed(struct xfs_mount *mp)
{
- return cache_overflowed(libxfs_bcache);
+ return cache_overflowed(mp->m_ddev_targp->bcache) ||
+ cache_overflowed(mp->m_logdev_targp->bcache) ||
+ cache_overflowed(mp->m_rtdev_targp->bcache);
}
struct cache_operations libxfs_bcache_operations = {
@@ -1466,7 +1479,7 @@ libxfs_buf_set_priority(
struct xfs_buf *bp,
int priority)
{
- cache_node_set_priority(libxfs_bcache, &bp->b_node, priority);
+ cache_node_set_priority(bp->b_target->bcache, &bp->b_node, priority);
}
int
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index f4a9bf20f..d6fa48ede 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -4613,7 +4613,7 @@ main(
* Need to drop references to inodes we still hold, first.
*/
libxfs_rtmount_destroy(mp);
- libxfs_bcache_purge();
+ libxfs_bcache_purge(mp);
/*
* Mark the filesystem ok.
diff --git a/repair/prefetch.c b/repair/prefetch.c
index b0dd19775..de36c5fe2 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -886,10 +886,12 @@ init_prefetch(
prefetch_args_t *
start_inode_prefetch(
+ struct xfs_mount *mp,
xfs_agnumber_t agno,
int dirs_only,
prefetch_args_t *prev_args)
{
+ struct cache *bcache = mp->m_ddev_targp->bcache;
prefetch_args_t *args;
long max_queue;
struct xfs_ino_geometry *igeo = M_IGEO(mp);
@@ -914,7 +916,7 @@ start_inode_prefetch(
* and not any other associated metadata like directories
*/
- max_queue = libxfs_bcache->c_maxcount / thread_count / 8;
+ max_queue = bcache->c_maxcount / thread_count / 8;
if (igeo->inode_cluster_size > mp->m_sb.sb_blocksize)
max_queue = max_queue * igeo->blocks_per_cluster /
igeo->ialloc_blks;
@@ -970,14 +972,16 @@ prefetch_ag_range(
void (*func)(struct workqueue *,
xfs_agnumber_t, void *))
{
+ struct xfs_mount *mp = work->wq_ctx;
int i;
struct prefetch_args *pf_args[2];
- pf_args[start_ag & 1] = start_inode_prefetch(start_ag, dirs_only, NULL);
+ pf_args[start_ag & 1] = start_inode_prefetch(mp, start_ag, dirs_only,
+ NULL);
for (i = start_ag; i < end_ag; i++) {
/* Don't prefetch end_ag */
if (i + 1 < end_ag)
- pf_args[(~i) & 1] = start_inode_prefetch(i + 1,
+ pf_args[(~i) & 1] = start_inode_prefetch(mp, i + 1,
dirs_only, pf_args[i & 1]);
func(work, i, pf_args[i & 1]);
}
@@ -1027,7 +1031,7 @@ do_inode_prefetch(
* filesystem - it's all in the cache. In that case, run a thread per
* CPU to maximise parallelism of the queue to be processed.
*/
- if (check_cache && !libxfs_bcache_overflowed()) {
+ if (check_cache && !libxfs_bcache_overflowed(mp)) {
queue.wq_ctx = mp;
create_work_queue(&queue, mp, platform_nproc());
for (i = 0; i < mp->m_sb.sb_agcount; i++)
diff --git a/repair/prefetch.h b/repair/prefetch.h
index 54ece48ad..a8c52a119 100644
--- a/repair/prefetch.h
+++ b/repair/prefetch.h
@@ -39,6 +39,7 @@ init_prefetch(
prefetch_args_t *
start_inode_prefetch(
+ struct xfs_mount *mp,
xfs_agnumber_t agno,
int dirs_only,
prefetch_args_t *prev_args);
diff --git a/repair/progress.c b/repair/progress.c
index 2ce36cef0..084afa63c 100644
--- a/repair/progress.c
+++ b/repair/progress.c
@@ -384,14 +384,18 @@ timediff(int phase)
** array.
*/
char *
-timestamp(int end, int phase, char *buf)
+timestamp(
+ struct xfs_mount *mp,
+ int end,
+ int phase,
+ char *buf)
{
- time_t now;
- struct tm *tmp;
+ time_t now;
+ struct tm *tmp;
- if (verbose > 1)
- cache_report(stderr, "libxfs_bcache", libxfs_bcache);
+ if (verbose > 1 && mp && mp->m_ddev_targp)
+ cache_report(stderr, "libxfs_bcache", mp->m_ddev_targp->bcache);
now = time(NULL);
diff --git a/repair/progress.h b/repair/progress.h
index 9575df164..0b06b2c4f 100644
--- a/repair/progress.h
+++ b/repair/progress.h
@@ -37,7 +37,7 @@ extern void stop_progress_rpt(void);
extern void summary_report(void);
extern int set_progress_msg(int report, uint64_t total);
extern uint64_t print_final_rpt(void);
-extern char *timestamp(int end, int phase, char *buf);
+extern char *timestamp(struct xfs_mount *mp, int end, int phase, char *buf);
extern char *duration(time_t val, char *buf);
extern int do_parallel;
diff --git a/repair/scan.c b/repair/scan.c
index 7e6d94cfa..715be1166 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -42,7 +42,7 @@ struct aghdr_cnts {
void
set_mp(xfs_mount_t *mpp)
{
- libxfs_bcache_purge();
+ libxfs_bcache_purge(mp);
mp = mpp;
}
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 2fc89dac3..ae3d2fcb0 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -980,9 +980,11 @@ repair_capture_writeback(
}
static inline void
-phase_end(int phase)
+phase_end(
+ struct xfs_mount *mp,
+ int phase)
{
- timestamp(PHASE_END, phase, NULL);
+ timestamp(mp, PHASE_END, phase, NULL);
/* Fail if someone injected an post-phase error. */
if (fail_after_phase && phase == fail_after_phase)
@@ -1017,8 +1019,8 @@ main(int argc, char **argv)
msgbuf = malloc(DURATION_BUF_SIZE);
- timestamp(PHASE_START, 0, NULL);
- phase_end(0);
+ timestamp(temp_mp, PHASE_START, 0, NULL);
+ phase_end(temp_mp, 0);
/* -f forces this, but let's be nice and autodetect it, as well. */
if (!isa_file) {
@@ -1040,7 +1042,7 @@ main(int argc, char **argv)
/* do phase1 to make sure we have a superblock */
phase1(temp_mp);
- phase_end(1);
+ phase_end(temp_mp, 1);
if (no_modify && primary_sb_modified) {
do_warn(_("Primary superblock would have been modified.\n"
@@ -1177,8 +1179,8 @@ main(int argc, char **argv)
unsigned long max_mem;
struct rlimit rlim;
- libxfs_bcache_purge();
- cache_destroy(libxfs_bcache);
+ libxfs_bcache_purge(mp);
+ cache_destroy(mp->m_ddev_targp->bcache);
mem_used = (mp->m_sb.sb_icount >> (10 - 2)) +
(mp->m_sb.sb_dblocks >> (10 + 1)) +
@@ -1238,7 +1240,7 @@ main(int argc, char **argv)
do_log(_(" - block cache size set to %d entries\n"),
libxfs_bhash_size * HASH_CACHE_RATIO);
- libxfs_bcache = cache_init(0, libxfs_bhash_size,
+ mp->m_ddev_targp->bcache = cache_init(0, libxfs_bhash_size,
&libxfs_bcache_operations);
}
@@ -1266,16 +1268,16 @@ main(int argc, char **argv)
/* make sure the per-ag freespace maps are ok so we can mount the fs */
phase2(mp, phase2_threads);
- phase_end(2);
+ phase_end(mp, 2);
if (do_prefetch)
init_prefetch(mp);
phase3(mp, phase2_threads);
- phase_end(3);
+ phase_end(mp, 3);
phase4(mp);
- phase_end(4);
+ phase_end(mp, 4);
if (no_modify) {
printf(_("No modify flag set, skipping phase 5\n"));
@@ -1285,7 +1287,7 @@ main(int argc, char **argv)
} else {
phase5(mp);
}
- phase_end(5);
+ phase_end(mp, 5);
/*
* Done with the block usage maps, toss them...
@@ -1295,10 +1297,10 @@ main(int argc, char **argv)
if (!bad_ino_btree) {
phase6(mp);
- phase_end(6);
+ phase_end(mp, 6);
phase7(mp, phase2_threads);
- phase_end(7);
+ phase_end(mp, 7);
} else {
do_warn(
_("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n"));
@@ -1423,7 +1425,7 @@ _("Note - stripe unit (%d) and width (%d) were copied from a backup superblock.\
* verifiers are run (where we discover the max metadata LSN), reformat
* the log if necessary and unmount.
*/
- libxfs_bcache_flush();
+ libxfs_bcache_flush(mp);
format_log_max_lsn(mp);
if (xfs_sb_version_needsrepair(&mp->m_sb))
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 089/111] libxfs: add xfile support
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (87 preceding siblings ...)
2024-05-22 3:11 ` [PATCH 088/111] libxfs: teach buftargs to maintain their own buffer hashtable Darrick J. Wong
@ 2024-05-22 3:11 ` Darrick J. Wong
2024-05-22 3:12 ` [PATCH 090/111] libxfs: partition memfd files to avoid using too many fds Darrick J. Wong
` (22 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:11 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Port the xfile functionality (anonymous pageable file-index memory) from
the kernel. In userspace, we try to use memfd() to create tmpfs files
that are not in any namespace, matching the kernel.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/Makefile | 2
libxfs/xfile.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++
libxfs/xfile.h | 21 +++++
repair/xfs_repair.c | 15 ++++
4 files changed, 248 insertions(+)
create mode 100644 libxfs/xfile.c
create mode 100644 libxfs/xfile.h
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 6f688c0ad..43e8ae183 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -26,6 +26,7 @@ HFILES = \
libxfs_priv.h \
linux-err.h \
topology.h \
+ xfile.h \
xfs_ag_resv.h \
xfs_alloc.h \
xfs_alloc_btree.h \
@@ -66,6 +67,7 @@ CFILES = cache.c \
topology.c \
trans.c \
util.c \
+ xfile.c \
xfs_ag.c \
xfs_ag_resv.c \
xfs_alloc.c \
diff --git a/libxfs/xfile.c b/libxfs/xfile.c
new file mode 100644
index 000000000..cba173cc1
--- /dev/null
+++ b/libxfs/xfile.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "libxfs_priv.h"
+#include "libxfs.h"
+#include "libxfs/xfile.h"
+#include <linux/memfd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/*
+ * Swappable Temporary Memory
+ * ==========================
+ *
+ * Offline checking sometimes needs to be able to stage a large amount of data
+ * in memory. This information might not fit in the available memory and it
+ * doesn't all need to be accessible at all times. In other words, we want an
+ * indexed data buffer to store data that can be paged out.
+ *
+ * memfd files meet those requirements. Therefore, the xfile mechanism uses
+ * one to store our staging data. The xfile must be freed with xfile_destroy.
+ *
+ * xfiles assume that the caller will handle all required concurrency
+ * management; file locks are not taken.
+ */
+
+/*
+ * Starting with Linux 6.3, there's a new MFD_NOEXEC_SEAL flag that disables
+ * the longstanding memfd behavior that files are created with the executable
+ * bit set, and seals the file against it being turned back on.
+ */
+#ifndef MFD_NOEXEC_SEAL
+# define MFD_NOEXEC_SEAL (0x0008U)
+#endif
+
+/*
+ * Open a memory-backed fd to back an xfile. We require close-on-exec here,
+ * because these memfd files function as windowed RAM and hence should never
+ * be shared with other processes.
+ */
+static int
+xfile_create_fd(
+ const char *description)
+{
+ int fd = -1;
+ int ret;
+
+ /*
+ * memfd_create was added to kernel 3.17 (2014). MFD_NOEXEC_SEAL
+ * causes -EINVAL on old kernels, so fall back to omitting it so that
+ * new xfs_repair can run on an older recovery cd kernel.
+ */
+ fd = memfd_create(description, MFD_CLOEXEC | MFD_NOEXEC_SEAL);
+ if (fd >= 0)
+ goto got_fd;
+ fd = memfd_create(description, MFD_CLOEXEC);
+ if (fd >= 0)
+ goto got_fd;
+
+ /*
+ * O_TMPFILE exists as of kernel 3.11 (2013), which means that if we
+ * find it, we're pretty safe in assuming O_CLOEXEC exists too.
+ */
+ fd = open("/dev/shm", O_TMPFILE | O_CLOEXEC | O_RDWR, 0600);
+ if (fd >= 0)
+ goto got_fd;
+
+ fd = open("/tmp", O_TMPFILE | O_CLOEXEC | O_RDWR, 0600);
+ if (fd >= 0)
+ goto got_fd;
+
+ /*
+ * mkostemp exists as of glibc 2.7 (2007) and O_CLOEXEC exists as of
+ * kernel 2.6.23 (2007).
+ */
+ fd = mkostemp("libxfsXXXXXX", O_CLOEXEC);
+ if (fd >= 0)
+ goto got_fd;
+
+ if (!errno)
+ errno = EOPNOTSUPP;
+ return -1;
+got_fd:
+ /*
+ * Turn off mode bits we don't want -- group members and others should
+ * not have access to the xfile, nor it be executable. memfds are
+ * created with mode 0777, but we'll be careful just in case the other
+ * implementations fail to set 0600.
+ */
+ ret = fchmod(fd, 0600);
+ if (ret)
+ perror("disabling xfile executable bit");
+
+ return fd;
+}
+
+/*
+ * Create an xfile of the given size. The description will be used in the
+ * trace output.
+ */
+int
+xfile_create(
+ const char *description,
+ struct xfile **xfilep)
+{
+ struct xfile *xf;
+ int error;
+
+ xf = kmalloc(sizeof(struct xfile), 0);
+ if (!xf)
+ return -ENOMEM;
+
+ xf->fd = xfile_create_fd(description);
+ if (xf->fd < 0) {
+ error = -errno;
+ kfree(xf);
+ return error;
+ }
+
+ *xfilep = xf;
+ return 0;
+}
+
+/* Close the file and release all resources. */
+void
+xfile_destroy(
+ struct xfile *xf)
+{
+ close(xf->fd);
+ kfree(xf);
+}
+
+static inline loff_t
+xfile_maxbytes(
+ struct xfile *xf)
+{
+ if (sizeof(loff_t) == 8)
+ return LLONG_MAX;
+ return LONG_MAX;
+}
+
+/*
+ * Load an object. Since we're treating this file as "memory", any error or
+ * short IO is treated as a failure to allocate memory.
+ */
+ssize_t
+xfile_load(
+ struct xfile *xf,
+ void *buf,
+ size_t count,
+ loff_t pos)
+{
+ ssize_t ret;
+
+ if (count > INT_MAX)
+ return -ENOMEM;
+ if (xfile_maxbytes(xf) - pos < count)
+ return -ENOMEM;
+
+ ret = pread(xf->fd, buf, count, pos);
+ if (ret < 0)
+ return -errno;
+ if (ret != count)
+ return -ENOMEM;
+ return 0;
+}
+
+/*
+ * Store an object. Since we're treating this file as "memory", any error or
+ * short IO is treated as a failure to allocate memory.
+ */
+ssize_t
+xfile_store(
+ struct xfile *xf,
+ const void *buf,
+ size_t count,
+ loff_t pos)
+{
+ ssize_t ret;
+
+ if (count > INT_MAX)
+ return -E2BIG;
+ if (xfile_maxbytes(xf) - pos < count)
+ return -EFBIG;
+
+ ret = pwrite(xf->fd, buf, count, pos);
+ if (ret < 0)
+ return -errno;
+ if (ret != count)
+ return -ENOMEM;
+ return 0;
+}
+
+/* Compute the number of bytes used by a xfile. */
+unsigned long long
+xfile_bytes(
+ struct xfile *xf)
+{
+ struct stat statbuf;
+ int error;
+
+ error = fstat(xf->fd, &statbuf);
+ if (error)
+ return -errno;
+
+ return (unsigned long long)statbuf.st_blocks << 9;
+}
diff --git a/libxfs/xfile.h b/libxfs/xfile.h
new file mode 100644
index 000000000..d60084011
--- /dev/null
+++ b/libxfs/xfile.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __LIBXFS_XFILE_H__
+#define __LIBXFS_XFILE_H__
+
+struct xfile {
+ int fd;
+};
+
+int xfile_create(const char *description, struct xfile **xfilep);
+void xfile_destroy(struct xfile *xf);
+
+ssize_t xfile_load(struct xfile *xf, void *buf, size_t count, loff_t pos);
+ssize_t xfile_store(struct xfile *xf, const void *buf, size_t count, loff_t pos);
+
+unsigned long long xfile_bytes(struct xfile *xf);
+
+#endif /* __LIBXFS_XFILE_H__ */
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index ae3d2fcb0..bf56daa93 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -991,6 +991,20 @@ phase_end(
platform_crash();
}
+/* Try to allow as many memfds as possible. */
+static void
+bump_max_fds(void)
+{
+ struct rlimit rlim = { };
+ int ret;
+
+ ret = getrlimit(RLIMIT_NOFILE, &rlim);
+ if (!ret) {
+ rlim.rlim_cur = rlim.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+ }
+}
+
int
main(int argc, char **argv)
{
@@ -1010,6 +1024,7 @@ main(int argc, char **argv)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
dinode_bmbt_translation_init();
+ bump_max_fds();
temp_mp = &xfs_m;
setbuf(stdout, NULL);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 090/111] libxfs: partition memfd files to avoid using too many fds
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (88 preceding siblings ...)
2024-05-22 3:11 ` [PATCH 089/111] libxfs: add xfile support Darrick J. Wong
@ 2024-05-22 3:12 ` Darrick J. Wong
2024-05-31 9:30 ` Carlos Maiolino
2024-05-22 3:12 ` [PATCH 091/111] xfs: teach buftargs to maintain their own buffer hashtable Darrick J. Wong
` (21 subsequent siblings)
111 siblings, 1 reply; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:12 UTC (permalink / raw)
To: djwong, cem; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
In a few patchsets from now, we'll transition xfs_repair to use
memfd-backed rmap and rcbag btrees for storing repair data instead of
heap allocations. This allows repair to use libxfs code shared from the
online repair code, which reduces the size of the codebase. It also
reduces heap fragmentation, which might be critical on 32-bit systems.
However, there's one hitch -- userspace xfiles naively allocate one
memfd per data structure, but there's only so many file descriptors that
a process can open. If a filesystem has a lot of allocation groups, we
can run out of fds and fail. xfs_repair already tries to increase
RLIMIT_NOFILE to the maximum (~1M) but this can fail due to system or
memory constraints.
Fortunately, it is possible to compute the upper bound of a memfd btree,
which implies that we can store multiple btrees per memfd. Make it so
that we can partition a memfd file to avoid running out of file
descriptors.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfile.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
libxfs/xfile.h | 17 ++++-
2 files changed, 205 insertions(+), 9 deletions(-)
diff --git a/libxfs/xfile.c b/libxfs/xfile.c
index cba173cc1..fdb76f406 100644
--- a/libxfs/xfile.c
+++ b/libxfs/xfile.c
@@ -97,6 +97,149 @@ xfile_create_fd(
return fd;
}
+static LIST_HEAD(fcb_list);
+static pthread_mutex_t fcb_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Create a new memfd. */
+static inline int
+xfile_fcb_create(
+ const char *description,
+ struct xfile_fcb **fcbp)
+{
+ struct xfile_fcb *fcb;
+ int fd;
+
+ fd = xfile_create_fd(description);
+ if (fd < 0)
+ return -errno;
+
+ fcb = malloc(sizeof(struct xfile_fcb));
+ if (!fcb) {
+ close(fd);
+ return -ENOMEM;
+ }
+
+ list_head_init(&fcb->fcb_list);
+ fcb->fd = fd;
+ fcb->refcount = 1;
+
+ *fcbp = fcb;
+ return 0;
+}
+
+/* Release an xfile control block */
+static void
+xfile_fcb_irele(
+ struct xfile_fcb *fcb,
+ loff_t pos,
+ uint64_t len)
+{
+ /*
+ * If this memfd is linked only to itself, it's private, so we can
+ * close it without taking any locks.
+ */
+ if (list_empty(&fcb->fcb_list)) {
+ close(fcb->fd);
+ free(fcb);
+ return;
+ }
+
+ pthread_mutex_lock(&fcb_mutex);
+ if (--fcb->refcount == 0) {
+ /* If we're the last user of this memfd file, kill it fast. */
+ list_del(&fcb->fcb_list);
+ close(fcb->fd);
+ free(fcb);
+ } else if (len > 0) {
+ struct stat statbuf;
+ int ret;
+
+ /*
+ * If we were using the end of a partitioned file, free the
+ * address space. IOWs, bonus points if you delete these in
+ * reverse-order of creation.
+ */
+ ret = fstat(fcb->fd, &statbuf);
+ if (!ret && statbuf.st_size == pos + len) {
+ ret = ftruncate(fcb->fd, pos);
+ }
+ }
+ pthread_mutex_unlock(&fcb_mutex);
+}
+
+/*
+ * Find an memfd that can accomodate the given amount of address space.
+ */
+static int
+xfile_fcb_find(
+ const char *description,
+ uint64_t maxbytes,
+ loff_t *posp,
+ struct xfile_fcb **fcbp)
+{
+ struct xfile_fcb *fcb;
+ int ret;
+ int error;
+
+ /* No maximum range means that the caller gets a private memfd. */
+ if (maxbytes == 0) {
+ *posp = 0;
+ return xfile_fcb_create(description, fcbp);
+ }
+
+ /* round up to page granularity so we can do mmap */
+ maxbytes = roundup_64(maxbytes, PAGE_SIZE);
+
+ pthread_mutex_lock(&fcb_mutex);
+
+ /*
+ * If we only need a certain number of byte range, look for one with
+ * available file range.
+ */
+ list_for_each_entry(fcb, &fcb_list, fcb_list) {
+ struct stat statbuf;
+ loff_t pos;
+
+ ret = fstat(fcb->fd, &statbuf);
+ if (ret)
+ continue;
+ pos = roundup_64(statbuf.st_size, PAGE_SIZE);
+
+ /*
+ * Truncate up to ensure that the memfd can actually handle
+ * writes to the end of the range.
+ */
+ ret = ftruncate(fcb->fd, pos + maxbytes);
+ if (ret)
+ continue;
+
+ fcb->refcount++;
+ *posp = pos;
+ *fcbp = fcb;
+ goto out_unlock;
+ }
+
+ /* Otherwise, open a new memfd and add it to our list. */
+ error = xfile_fcb_create(description, &fcb);
+ if (error)
+ return error;
+
+ ret = ftruncate(fcb->fd, maxbytes);
+ if (ret) {
+ error = -errno;
+ xfile_fcb_irele(fcb, 0, maxbytes);
+ return error;
+ }
+
+ list_add_tail(&fcb->fcb_list, &fcb_list);
+ *posp = 0;
+ *fcbp = fcb;
+
+out_unlock:
+ pthread_mutex_unlock(&fcb_mutex);
+ return error;
+}
+
/*
* Create an xfile of the given size. The description will be used in the
* trace output.
@@ -104,6 +247,7 @@ xfile_create_fd(
int
xfile_create(
const char *description,
+ unsigned long long maxbytes,
struct xfile **xfilep)
{
struct xfile *xf;
@@ -113,13 +257,14 @@ xfile_create(
if (!xf)
return -ENOMEM;
- xf->fd = xfile_create_fd(description);
- if (xf->fd < 0) {
- error = -errno;
+ error = xfile_fcb_find(description, maxbytes, &xf->partition_pos,
+ &xf->fcb);
+ if (error) {
kfree(xf);
return error;
}
+ xf->maxbytes = maxbytes;
*xfilep = xf;
return 0;
}
@@ -129,7 +274,7 @@ void
xfile_destroy(
struct xfile *xf)
{
- close(xf->fd);
+ xfile_fcb_irele(xf->fcb, xf->partition_pos, xf->maxbytes);
kfree(xf);
}
@@ -137,6 +282,9 @@ static inline loff_t
xfile_maxbytes(
struct xfile *xf)
{
+ if (xf->maxbytes > 0)
+ return xf->maxbytes;
+
if (sizeof(loff_t) == 8)
return LLONG_MAX;
return LONG_MAX;
@@ -160,7 +308,7 @@ xfile_load(
if (xfile_maxbytes(xf) - pos < count)
return -ENOMEM;
- ret = pread(xf->fd, buf, count, pos);
+ ret = pread(xf->fcb->fd, buf, count, pos + xf->partition_pos);
if (ret < 0)
return -errno;
if (ret != count)
@@ -186,7 +334,7 @@ xfile_store(
if (xfile_maxbytes(xf) - pos < count)
return -EFBIG;
- ret = pwrite(xf->fd, buf, count, pos);
+ ret = pwrite(xf->fcb->fd, buf, count, pos + xf->partition_pos);
if (ret < 0)
return -errno;
if (ret != count)
@@ -194,6 +342,38 @@ xfile_store(
return 0;
}
+/* Compute the number of bytes used by a partitioned xfile. */
+static unsigned long long
+xfile_partition_bytes(
+ struct xfile *xf)
+{
+ loff_t data_pos = xf->partition_pos;
+ loff_t stop_pos = data_pos + xf->maxbytes;
+ loff_t hole_pos;
+ unsigned long long bytes = 0;
+
+ data_pos = lseek(xf->fcb->fd, data_pos, SEEK_DATA);
+ while (data_pos >= 0 && data_pos < stop_pos) {
+ hole_pos = lseek(xf->fcb->fd, data_pos, SEEK_HOLE);
+ if (hole_pos < 0) {
+ /* save error, break */
+ data_pos = hole_pos;
+ break;
+ }
+ if (hole_pos >= stop_pos) {
+ bytes += stop_pos - data_pos;
+ return bytes;
+ }
+ bytes += hole_pos - data_pos;
+
+ data_pos = lseek(xf->fcb->fd, hole_pos, SEEK_DATA);
+ }
+ if (data_pos < 0 && errno != ENXIO)
+ return xf->maxbytes;
+
+ return bytes;
+}
+
/* Compute the number of bytes used by a xfile. */
unsigned long long
xfile_bytes(
@@ -202,7 +382,10 @@ xfile_bytes(
struct stat statbuf;
int error;
- error = fstat(xf->fd, &statbuf);
+ if (xf->maxbytes > 0)
+ return xfile_partition_bytes(xf);
+
+ error = fstat(xf->fcb->fd, &statbuf);
if (error)
return -errno;
diff --git a/libxfs/xfile.h b/libxfs/xfile.h
index d60084011..180a42bbb 100644
--- a/libxfs/xfile.h
+++ b/libxfs/xfile.h
@@ -6,11 +6,24 @@
#ifndef __LIBXFS_XFILE_H__
#define __LIBXFS_XFILE_H__
-struct xfile {
+struct xfile_fcb {
+ struct list_head fcb_list;
int fd;
+ unsigned int refcount;
};
-int xfile_create(const char *description, struct xfile **xfilep);
+struct xfile {
+ struct xfile_fcb *fcb;
+
+ /* File position within fcb->fd where this partition starts */
+ loff_t partition_pos;
+
+ /* Maximum number of bytes that can be written to the partition. */
+ uint64_t maxbytes;
+};
+
+int xfile_create(const char *description, unsigned long long maxbytes,
+ struct xfile **xfilep);
void xfile_destroy(struct xfile *xf);
ssize_t xfile_load(struct xfile *xf, void *buf, size_t count, loff_t pos);
^ permalink raw reply related [flat|nested] 154+ messages in thread* Re: [PATCH 090/111] libxfs: partition memfd files to avoid using too many fds
2024-05-22 3:12 ` [PATCH 090/111] libxfs: partition memfd files to avoid using too many fds Darrick J. Wong
@ 2024-05-31 9:30 ` Carlos Maiolino
2024-05-31 14:54 ` Darrick J. Wong
0 siblings, 1 reply; 154+ messages in thread
From: Carlos Maiolino @ 2024-05-31 9:30 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On Tue, May 21, 2024 at 08:12:14PM GMT, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> In a few patchsets from now, we'll transition xfs_repair to use
> memfd-backed rmap and rcbag btrees for storing repair data instead of
> heap allocations. This allows repair to use libxfs code shared from the
> online repair code, which reduces the size of the codebase. It also
> reduces heap fragmentation, which might be critical on 32-bit systems.
>
> However, there's one hitch -- userspace xfiles naively allocate one
> memfd per data structure, but there's only so many file descriptors that
> a process can open. If a filesystem has a lot of allocation groups, we
> can run out of fds and fail. xfs_repair already tries to increase
> RLIMIT_NOFILE to the maximum (~1M) but this can fail due to system or
> memory constraints.
>
> Fortunately, it is possible to compute the upper bound of a memfd btree,
> which implies that we can store multiple btrees per memfd. Make it so
> that we can partition a memfd file to avoid running out of file
> descriptors.
>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
I usually see bigger problems on those filesystems like mount timing out, before users reach
system's max fd limit, but I'm ok with it if you've seen it in the wild. Giving that - in theory -
cloud instances resources are pretty limited, we could get to pretty small max fd limits, so it
seems fair to me.
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---
> libxfs/xfile.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> libxfs/xfile.h | 17 ++++-
> 2 files changed, 205 insertions(+), 9 deletions(-)
>
>
> diff --git a/libxfs/xfile.c b/libxfs/xfile.c
> index cba173cc1..fdb76f406 100644
> --- a/libxfs/xfile.c
> +++ b/libxfs/xfile.c
> @@ -97,6 +97,149 @@ xfile_create_fd(
> return fd;
> }
>
> +static LIST_HEAD(fcb_list);
> +static pthread_mutex_t fcb_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> +/* Create a new memfd. */
> +static inline int
> +xfile_fcb_create(
> + const char *description,
> + struct xfile_fcb **fcbp)
> +{
> + struct xfile_fcb *fcb;
> + int fd;
> +
> + fd = xfile_create_fd(description);
> + if (fd < 0)
> + return -errno;
> +
> + fcb = malloc(sizeof(struct xfile_fcb));
> + if (!fcb) {
> + close(fd);
> + return -ENOMEM;
> + }
> +
> + list_head_init(&fcb->fcb_list);
> + fcb->fd = fd;
> + fcb->refcount = 1;
> +
> + *fcbp = fcb;
> + return 0;
> +}
> +
> +/* Release an xfile control block */
> +static void
> +xfile_fcb_irele(
> + struct xfile_fcb *fcb,
> + loff_t pos,
> + uint64_t len)
> +{
> + /*
> + * If this memfd is linked only to itself, it's private, so we can
> + * close it without taking any locks.
> + */
> + if (list_empty(&fcb->fcb_list)) {
> + close(fcb->fd);
> + free(fcb);
> + return;
> + }
> +
> + pthread_mutex_lock(&fcb_mutex);
> + if (--fcb->refcount == 0) {
> + /* If we're the last user of this memfd file, kill it fast. */
> + list_del(&fcb->fcb_list);
> + close(fcb->fd);
> + free(fcb);
> + } else if (len > 0) {
> + struct stat statbuf;
> + int ret;
> +
> + /*
> + * If we were using the end of a partitioned file, free the
> + * address space. IOWs, bonus points if you delete these in
> + * reverse-order of creation.
> + */
> + ret = fstat(fcb->fd, &statbuf);
> + if (!ret && statbuf.st_size == pos + len) {
> + ret = ftruncate(fcb->fd, pos);
> + }
> + }
> + pthread_mutex_unlock(&fcb_mutex);
> +}
> +
> +/*
> + * Find an memfd that can accomodate the given amount of address space.
> + */
> +static int
> +xfile_fcb_find(
> + const char *description,
> + uint64_t maxbytes,
> + loff_t *posp,
> + struct xfile_fcb **fcbp)
> +{
> + struct xfile_fcb *fcb;
> + int ret;
> + int error;
> +
> + /* No maximum range means that the caller gets a private memfd. */
> + if (maxbytes == 0) {
> + *posp = 0;
> + return xfile_fcb_create(description, fcbp);
> + }
> +
> + /* round up to page granularity so we can do mmap */
> + maxbytes = roundup_64(maxbytes, PAGE_SIZE);
> +
> + pthread_mutex_lock(&fcb_mutex);
> +
> + /*
> + * If we only need a certain number of byte range, look for one with
> + * available file range.
> + */
> + list_for_each_entry(fcb, &fcb_list, fcb_list) {
> + struct stat statbuf;
> + loff_t pos;
> +
> + ret = fstat(fcb->fd, &statbuf);
> + if (ret)
> + continue;
> + pos = roundup_64(statbuf.st_size, PAGE_SIZE);
> +
> + /*
> + * Truncate up to ensure that the memfd can actually handle
> + * writes to the end of the range.
> + */
> + ret = ftruncate(fcb->fd, pos + maxbytes);
> + if (ret)
> + continue;
> +
> + fcb->refcount++;
> + *posp = pos;
> + *fcbp = fcb;
> + goto out_unlock;
> + }
> +
> + /* Otherwise, open a new memfd and add it to our list. */
> + error = xfile_fcb_create(description, &fcb);
> + if (error)
> + return error;
> +
> + ret = ftruncate(fcb->fd, maxbytes);
> + if (ret) {
> + error = -errno;
> + xfile_fcb_irele(fcb, 0, maxbytes);
> + return error;
> + }
> +
> + list_add_tail(&fcb->fcb_list, &fcb_list);
> + *posp = 0;
> + *fcbp = fcb;
> +
> +out_unlock:
> + pthread_mutex_unlock(&fcb_mutex);
> + return error;
> +}
> +
> /*
> * Create an xfile of the given size. The description will be used in the
> * trace output.
> @@ -104,6 +247,7 @@ xfile_create_fd(
> int
> xfile_create(
> const char *description,
> + unsigned long long maxbytes,
> struct xfile **xfilep)
> {
> struct xfile *xf;
> @@ -113,13 +257,14 @@ xfile_create(
> if (!xf)
> return -ENOMEM;
>
> - xf->fd = xfile_create_fd(description);
> - if (xf->fd < 0) {
> - error = -errno;
> + error = xfile_fcb_find(description, maxbytes, &xf->partition_pos,
> + &xf->fcb);
> + if (error) {
> kfree(xf);
> return error;
> }
>
> + xf->maxbytes = maxbytes;
> *xfilep = xf;
> return 0;
> }
> @@ -129,7 +274,7 @@ void
> xfile_destroy(
> struct xfile *xf)
> {
> - close(xf->fd);
> + xfile_fcb_irele(xf->fcb, xf->partition_pos, xf->maxbytes);
> kfree(xf);
> }
>
> @@ -137,6 +282,9 @@ static inline loff_t
> xfile_maxbytes(
> struct xfile *xf)
> {
> + if (xf->maxbytes > 0)
> + return xf->maxbytes;
> +
> if (sizeof(loff_t) == 8)
> return LLONG_MAX;
> return LONG_MAX;
> @@ -160,7 +308,7 @@ xfile_load(
> if (xfile_maxbytes(xf) - pos < count)
> return -ENOMEM;
>
> - ret = pread(xf->fd, buf, count, pos);
> + ret = pread(xf->fcb->fd, buf, count, pos + xf->partition_pos);
> if (ret < 0)
> return -errno;
> if (ret != count)
> @@ -186,7 +334,7 @@ xfile_store(
> if (xfile_maxbytes(xf) - pos < count)
> return -EFBIG;
>
> - ret = pwrite(xf->fd, buf, count, pos);
> + ret = pwrite(xf->fcb->fd, buf, count, pos + xf->partition_pos);
> if (ret < 0)
> return -errno;
> if (ret != count)
> @@ -194,6 +342,38 @@ xfile_store(
> return 0;
> }
>
> +/* Compute the number of bytes used by a partitioned xfile. */
> +static unsigned long long
> +xfile_partition_bytes(
> + struct xfile *xf)
> +{
> + loff_t data_pos = xf->partition_pos;
> + loff_t stop_pos = data_pos + xf->maxbytes;
> + loff_t hole_pos;
> + unsigned long long bytes = 0;
> +
> + data_pos = lseek(xf->fcb->fd, data_pos, SEEK_DATA);
> + while (data_pos >= 0 && data_pos < stop_pos) {
> + hole_pos = lseek(xf->fcb->fd, data_pos, SEEK_HOLE);
> + if (hole_pos < 0) {
> + /* save error, break */
> + data_pos = hole_pos;
> + break;
> + }
> + if (hole_pos >= stop_pos) {
> + bytes += stop_pos - data_pos;
> + return bytes;
> + }
> + bytes += hole_pos - data_pos;
> +
> + data_pos = lseek(xf->fcb->fd, hole_pos, SEEK_DATA);
> + }
> + if (data_pos < 0 && errno != ENXIO)
> + return xf->maxbytes;
> +
> + return bytes;
> +}
> +
> /* Compute the number of bytes used by a xfile. */
> unsigned long long
> xfile_bytes(
> @@ -202,7 +382,10 @@ xfile_bytes(
> struct stat statbuf;
> int error;
>
> - error = fstat(xf->fd, &statbuf);
> + if (xf->maxbytes > 0)
> + return xfile_partition_bytes(xf);
> +
> + error = fstat(xf->fcb->fd, &statbuf);
> if (error)
> return -errno;
>
> diff --git a/libxfs/xfile.h b/libxfs/xfile.h
> index d60084011..180a42bbb 100644
> --- a/libxfs/xfile.h
> +++ b/libxfs/xfile.h
> @@ -6,11 +6,24 @@
> #ifndef __LIBXFS_XFILE_H__
> #define __LIBXFS_XFILE_H__
>
> -struct xfile {
> +struct xfile_fcb {
> + struct list_head fcb_list;
> int fd;
> + unsigned int refcount;
> };
>
> -int xfile_create(const char *description, struct xfile **xfilep);
> +struct xfile {
> + struct xfile_fcb *fcb;
> +
> + /* File position within fcb->fd where this partition starts */
> + loff_t partition_pos;
> +
> + /* Maximum number of bytes that can be written to the partition. */
> + uint64_t maxbytes;
> +};
> +
> +int xfile_create(const char *description, unsigned long long maxbytes,
> + struct xfile **xfilep);
> void xfile_destroy(struct xfile *xf);
>
> ssize_t xfile_load(struct xfile *xf, void *buf, size_t count, loff_t pos);
>
^ permalink raw reply [flat|nested] 154+ messages in thread* Re: [PATCH 090/111] libxfs: partition memfd files to avoid using too many fds
2024-05-31 9:30 ` Carlos Maiolino
@ 2024-05-31 14:54 ` Darrick J. Wong
0 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-31 14:54 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: linux-xfs
On Fri, May 31, 2024 at 11:30:07AM +0200, Carlos Maiolino wrote:
> On Tue, May 21, 2024 at 08:12:14PM GMT, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > In a few patchsets from now, we'll transition xfs_repair to use
> > memfd-backed rmap and rcbag btrees for storing repair data instead of
> > heap allocations. This allows repair to use libxfs code shared from the
> > online repair code, which reduces the size of the codebase. It also
> > reduces heap fragmentation, which might be critical on 32-bit systems.
> >
> > However, there's one hitch -- userspace xfiles naively allocate one
> > memfd per data structure, but there's only so many file descriptors that
> > a process can open. If a filesystem has a lot of allocation groups, we
> > can run out of fds and fail. xfs_repair already tries to increase
> > RLIMIT_NOFILE to the maximum (~1M) but this can fail due to system or
> > memory constraints.
> >
> > Fortunately, it is possible to compute the upper bound of a memfd btree,
> > which implies that we can store multiple btrees per memfd. Make it so
> > that we can partition a memfd file to avoid running out of file
> > descriptors.
> >
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
>
> I usually see bigger problems on those filesystems like mount timing
> out, before users reach system's max fd limit, but I'm ok with it if
> you've seen it in the wild. Giving that - in theory - cloud instances
> resources are pretty limited, we could get to pretty small max fd
> limits, so it seems fair to me.
Yes indeed you can hit the practical limits on a VM with not a lot
of memory and a severely overgrowfs'd filesystem.
> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Thanks!
--D
> > ---
> > libxfs/xfile.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> > libxfs/xfile.h | 17 ++++-
> > 2 files changed, 205 insertions(+), 9 deletions(-)
> >
> >
> > diff --git a/libxfs/xfile.c b/libxfs/xfile.c
> > index cba173cc1..fdb76f406 100644
> > --- a/libxfs/xfile.c
> > +++ b/libxfs/xfile.c
> > @@ -97,6 +97,149 @@ xfile_create_fd(
> > return fd;
> > }
> >
> > +static LIST_HEAD(fcb_list);
> > +static pthread_mutex_t fcb_mutex = PTHREAD_MUTEX_INITIALIZER;
> > +
> > +/* Create a new memfd. */
> > +static inline int
> > +xfile_fcb_create(
> > + const char *description,
> > + struct xfile_fcb **fcbp)
> > +{
> > + struct xfile_fcb *fcb;
> > + int fd;
> > +
> > + fd = xfile_create_fd(description);
> > + if (fd < 0)
> > + return -errno;
> > +
> > + fcb = malloc(sizeof(struct xfile_fcb));
> > + if (!fcb) {
> > + close(fd);
> > + return -ENOMEM;
> > + }
> > +
> > + list_head_init(&fcb->fcb_list);
> > + fcb->fd = fd;
> > + fcb->refcount = 1;
> > +
> > + *fcbp = fcb;
> > + return 0;
> > +}
> > +
> > +/* Release an xfile control block */
> > +static void
> > +xfile_fcb_irele(
> > + struct xfile_fcb *fcb,
> > + loff_t pos,
> > + uint64_t len)
> > +{
> > + /*
> > + * If this memfd is linked only to itself, it's private, so we can
> > + * close it without taking any locks.
> > + */
> > + if (list_empty(&fcb->fcb_list)) {
> > + close(fcb->fd);
> > + free(fcb);
> > + return;
> > + }
> > +
> > + pthread_mutex_lock(&fcb_mutex);
> > + if (--fcb->refcount == 0) {
> > + /* If we're the last user of this memfd file, kill it fast. */
> > + list_del(&fcb->fcb_list);
> > + close(fcb->fd);
> > + free(fcb);
> > + } else if (len > 0) {
> > + struct stat statbuf;
> > + int ret;
> > +
> > + /*
> > + * If we were using the end of a partitioned file, free the
> > + * address space. IOWs, bonus points if you delete these in
> > + * reverse-order of creation.
> > + */
> > + ret = fstat(fcb->fd, &statbuf);
> > + if (!ret && statbuf.st_size == pos + len) {
> > + ret = ftruncate(fcb->fd, pos);
> > + }
> > + }
> > + pthread_mutex_unlock(&fcb_mutex);
> > +}
> > +
> > +/*
> > + * Find an memfd that can accomodate the given amount of address space.
> > + */
> > +static int
> > +xfile_fcb_find(
> > + const char *description,
> > + uint64_t maxbytes,
> > + loff_t *posp,
> > + struct xfile_fcb **fcbp)
> > +{
> > + struct xfile_fcb *fcb;
> > + int ret;
> > + int error;
> > +
> > + /* No maximum range means that the caller gets a private memfd. */
> > + if (maxbytes == 0) {
> > + *posp = 0;
> > + return xfile_fcb_create(description, fcbp);
> > + }
> > +
> > + /* round up to page granularity so we can do mmap */
> > + maxbytes = roundup_64(maxbytes, PAGE_SIZE);
> > +
> > + pthread_mutex_lock(&fcb_mutex);
> > +
> > + /*
> > + * If we only need a certain number of byte range, look for one with
> > + * available file range.
> > + */
> > + list_for_each_entry(fcb, &fcb_list, fcb_list) {
> > + struct stat statbuf;
> > + loff_t pos;
> > +
> > + ret = fstat(fcb->fd, &statbuf);
> > + if (ret)
> > + continue;
> > + pos = roundup_64(statbuf.st_size, PAGE_SIZE);
> > +
> > + /*
> > + * Truncate up to ensure that the memfd can actually handle
> > + * writes to the end of the range.
> > + */
> > + ret = ftruncate(fcb->fd, pos + maxbytes);
> > + if (ret)
> > + continue;
> > +
> > + fcb->refcount++;
> > + *posp = pos;
> > + *fcbp = fcb;
> > + goto out_unlock;
> > + }
> > +
> > + /* Otherwise, open a new memfd and add it to our list. */
> > + error = xfile_fcb_create(description, &fcb);
> > + if (error)
> > + return error;
> > +
> > + ret = ftruncate(fcb->fd, maxbytes);
> > + if (ret) {
> > + error = -errno;
> > + xfile_fcb_irele(fcb, 0, maxbytes);
> > + return error;
> > + }
> > +
> > + list_add_tail(&fcb->fcb_list, &fcb_list);
> > + *posp = 0;
> > + *fcbp = fcb;
> > +
> > +out_unlock:
> > + pthread_mutex_unlock(&fcb_mutex);
> > + return error;
> > +}
> > +
> > /*
> > * Create an xfile of the given size. The description will be used in the
> > * trace output.
> > @@ -104,6 +247,7 @@ xfile_create_fd(
> > int
> > xfile_create(
> > const char *description,
> > + unsigned long long maxbytes,
> > struct xfile **xfilep)
> > {
> > struct xfile *xf;
> > @@ -113,13 +257,14 @@ xfile_create(
> > if (!xf)
> > return -ENOMEM;
> >
> > - xf->fd = xfile_create_fd(description);
> > - if (xf->fd < 0) {
> > - error = -errno;
> > + error = xfile_fcb_find(description, maxbytes, &xf->partition_pos,
> > + &xf->fcb);
> > + if (error) {
> > kfree(xf);
> > return error;
> > }
> >
> > + xf->maxbytes = maxbytes;
> > *xfilep = xf;
> > return 0;
> > }
> > @@ -129,7 +274,7 @@ void
> > xfile_destroy(
> > struct xfile *xf)
> > {
> > - close(xf->fd);
> > + xfile_fcb_irele(xf->fcb, xf->partition_pos, xf->maxbytes);
> > kfree(xf);
> > }
> >
> > @@ -137,6 +282,9 @@ static inline loff_t
> > xfile_maxbytes(
> > struct xfile *xf)
> > {
> > + if (xf->maxbytes > 0)
> > + return xf->maxbytes;
> > +
> > if (sizeof(loff_t) == 8)
> > return LLONG_MAX;
> > return LONG_MAX;
> > @@ -160,7 +308,7 @@ xfile_load(
> > if (xfile_maxbytes(xf) - pos < count)
> > return -ENOMEM;
> >
> > - ret = pread(xf->fd, buf, count, pos);
> > + ret = pread(xf->fcb->fd, buf, count, pos + xf->partition_pos);
> > if (ret < 0)
> > return -errno;
> > if (ret != count)
> > @@ -186,7 +334,7 @@ xfile_store(
> > if (xfile_maxbytes(xf) - pos < count)
> > return -EFBIG;
> >
> > - ret = pwrite(xf->fd, buf, count, pos);
> > + ret = pwrite(xf->fcb->fd, buf, count, pos + xf->partition_pos);
> > if (ret < 0)
> > return -errno;
> > if (ret != count)
> > @@ -194,6 +342,38 @@ xfile_store(
> > return 0;
> > }
> >
> > +/* Compute the number of bytes used by a partitioned xfile. */
> > +static unsigned long long
> > +xfile_partition_bytes(
> > + struct xfile *xf)
> > +{
> > + loff_t data_pos = xf->partition_pos;
> > + loff_t stop_pos = data_pos + xf->maxbytes;
> > + loff_t hole_pos;
> > + unsigned long long bytes = 0;
> > +
> > + data_pos = lseek(xf->fcb->fd, data_pos, SEEK_DATA);
> > + while (data_pos >= 0 && data_pos < stop_pos) {
> > + hole_pos = lseek(xf->fcb->fd, data_pos, SEEK_HOLE);
> > + if (hole_pos < 0) {
> > + /* save error, break */
> > + data_pos = hole_pos;
> > + break;
> > + }
> > + if (hole_pos >= stop_pos) {
> > + bytes += stop_pos - data_pos;
> > + return bytes;
> > + }
> > + bytes += hole_pos - data_pos;
> > +
> > + data_pos = lseek(xf->fcb->fd, hole_pos, SEEK_DATA);
> > + }
> > + if (data_pos < 0 && errno != ENXIO)
> > + return xf->maxbytes;
> > +
> > + return bytes;
> > +}
> > +
> > /* Compute the number of bytes used by a xfile. */
> > unsigned long long
> > xfile_bytes(
> > @@ -202,7 +382,10 @@ xfile_bytes(
> > struct stat statbuf;
> > int error;
> >
> > - error = fstat(xf->fd, &statbuf);
> > + if (xf->maxbytes > 0)
> > + return xfile_partition_bytes(xf);
> > +
> > + error = fstat(xf->fcb->fd, &statbuf);
> > if (error)
> > return -errno;
> >
> > diff --git a/libxfs/xfile.h b/libxfs/xfile.h
> > index d60084011..180a42bbb 100644
> > --- a/libxfs/xfile.h
> > +++ b/libxfs/xfile.h
> > @@ -6,11 +6,24 @@
> > #ifndef __LIBXFS_XFILE_H__
> > #define __LIBXFS_XFILE_H__
> >
> > -struct xfile {
> > +struct xfile_fcb {
> > + struct list_head fcb_list;
> > int fd;
> > + unsigned int refcount;
> > };
> >
> > -int xfile_create(const char *description, struct xfile **xfilep);
> > +struct xfile {
> > + struct xfile_fcb *fcb;
> > +
> > + /* File position within fcb->fd where this partition starts */
> > + loff_t partition_pos;
> > +
> > + /* Maximum number of bytes that can be written to the partition. */
> > + uint64_t maxbytes;
> > +};
> > +
> > +int xfile_create(const char *description, unsigned long long maxbytes,
> > + struct xfile **xfilep);
> > void xfile_destroy(struct xfile *xf);
> >
> > ssize_t xfile_load(struct xfile *xf, void *buf, size_t count, loff_t pos);
> >
>
^ permalink raw reply [flat|nested] 154+ messages in thread
* [PATCH 091/111] xfs: teach buftargs to maintain their own buffer hashtable
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (89 preceding siblings ...)
2024-05-22 3:12 ` [PATCH 090/111] libxfs: partition memfd files to avoid using too many fds Darrick J. Wong
@ 2024-05-22 3:12 ` Darrick J. Wong
2024-05-22 3:12 ` [PATCH 092/111] libxfs: support in-memory buffer cache targets Darrick J. Wong
` (20 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:12 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: e7b58f7c1be20550d4f51cec6307b811e7555f52
Currently, cached buffers are indexed by per-AG hashtables. This works
great for the data device, but won't work for in-memory btrees. To
handle that use case, buftargs will need to be able to index buffers
independently of other data structures.
We accomplish this by hoisting the rhashtable and its lock into a
separate xfs_buf_cache structure, make the buftarg point to the
_buf_cache structure, and rework various functions to use it. This
will enable the in-memory buftarg to come up with its own _buf_cache.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/libxfs_priv.h | 4 ++--
libxfs/xfs_ag.c | 6 +++---
libxfs/xfs_ag.h | 4 +---
3 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 0a4f686d9..aee85c155 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -550,8 +550,8 @@ unsigned int hweight8(unsigned int w);
unsigned int hweight32(unsigned int w);
unsigned int hweight64(__u64 w);
-static inline int xfs_buf_hash_init(struct xfs_perag *pag) { return 0; }
-static inline void xfs_buf_hash_destroy(struct xfs_perag *pag) { }
+#define xfs_buf_cache_init(bch) (0)
+#define xfs_buf_cache_destroy(bch) ((void)0)
static inline int xfs_iunlink_init(struct xfs_perag *pag) { return 0; }
static inline void xfs_iunlink_destroy(struct xfs_perag *pag) { }
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 389a8288e..06a881285 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -262,7 +262,7 @@ xfs_free_perag(
xfs_defer_drain_free(&pag->pag_intents_drain);
cancel_delayed_work_sync(&pag->pag_blockgc_work);
- xfs_buf_hash_destroy(pag);
+ xfs_buf_cache_destroy(&pag->pag_bcache);
/* drop the mount's active reference */
xfs_perag_rele(pag);
@@ -350,7 +350,7 @@ xfs_free_unused_perag_range(
spin_unlock(&mp->m_perag_lock);
if (!pag)
break;
- xfs_buf_hash_destroy(pag);
+ xfs_buf_cache_destroy(&pag->pag_bcache);
xfs_defer_drain_free(&pag->pag_intents_drain);
kfree(pag);
}
@@ -417,7 +417,7 @@ xfs_initialize_perag(
pag->pagb_tree = RB_ROOT;
#endif /* __KERNEL__ */
- error = xfs_buf_hash_init(pag);
+ error = xfs_buf_cache_init(&pag->pag_bcache);
if (error)
goto out_remove_pag;
diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h
index 19eddba09..29bfa6273 100644
--- a/libxfs/xfs_ag.h
+++ b/libxfs/xfs_ag.h
@@ -106,9 +106,7 @@ struct xfs_perag {
int pag_ici_reclaimable; /* reclaimable inodes */
unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */
- /* buffer cache index */
- spinlock_t pag_buf_lock; /* lock for pag_buf_hash */
- struct rhashtable pag_buf_hash;
+ struct xfs_buf_cache pag_bcache;
/* background prealloc block trimming */
struct delayed_work pag_blockgc_work;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 092/111] libxfs: support in-memory buffer cache targets
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (90 preceding siblings ...)
2024-05-22 3:12 ` [PATCH 091/111] xfs: teach buftargs to maintain their own buffer hashtable Darrick J. Wong
@ 2024-05-22 3:12 ` Darrick J. Wong
2024-05-22 3:13 ` [PATCH 093/111] xfs: add a xfs_btree_ptrs_equal helper Darrick J. Wong
` (19 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:12 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Allow the buffer cache to target in-memory files by connecting it to
xfiles. The next few patches will enable creating xfs_btrees in memory.
Unlike the kernel version of this patch, we use a partitioned xfile to
avoid overflowing the fd table instead of opening a separate memfd for
each target.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/Makefile | 4 +
libxfs/buf_mem.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++
libxfs/buf_mem.h | 26 ++++++
libxfs/init.c | 4 +
libxfs/libxfs_io.h | 22 +++++
libxfs/rdwr.c | 41 ++++-----
6 files changed, 310 insertions(+), 22 deletions(-)
create mode 100644 libxfs/buf_mem.c
create mode 100644 libxfs/buf_mem.h
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 43e8ae183..8dc9a7905 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -26,6 +26,7 @@ HFILES = \
libxfs_priv.h \
linux-err.h \
topology.h \
+ buf_mem.h \
xfile.h \
xfs_ag_resv.h \
xfs_alloc.h \
@@ -58,7 +59,8 @@ HFILES = \
xfs_trans_space.h \
xfs_dir2_priv.h
-CFILES = cache.c \
+CFILES = buf_mem.c \
+ cache.c \
defer_item.c \
init.c \
kmem.c \
diff --git a/libxfs/buf_mem.c b/libxfs/buf_mem.c
new file mode 100644
index 000000000..7c8fa1d2c
--- /dev/null
+++ b/libxfs/buf_mem.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "libxfs_priv.h"
+#include "libxfs.h"
+#include "libxfs/xfile.h"
+#include "libxfs/buf_mem.h"
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/*
+ * Buffer Cache for In-Memory Files
+ * ================================
+ *
+ * Offline fsck wants to create ephemeral ordered recordsets. The existing
+ * btree infrastructure can do this, but we need the buffer cache to target
+ * memory instead of block devices.
+ *
+ * xfiles meet those requirements. Therefore, the xmbuf mechanism uses a
+ * partition on an xfile to store the staging data.
+ *
+ * xmbufs assume that the caller will handle all required concurrency
+ * management. The resulting xfs_buf objects are kept private to the xmbuf
+ * (they are not recycled to the LRU) because b_addr is mapped directly to the
+ * memfd file.
+ *
+ * The only supported block size is the system page size.
+ */
+
+/* Figure out the xfile buffer cache block size here */
+unsigned int XMBUF_BLOCKSIZE;
+unsigned int XMBUF_BLOCKSHIFT;
+
+void
+xmbuf_libinit(void)
+{
+ long ret = sysconf(_SC_PAGESIZE);
+
+ /* If we don't find a power-of-two page size, go with 4k. */
+ if (ret < 0 || !is_power_of_2(ret))
+ ret = 4096;
+
+ XMBUF_BLOCKSIZE = ret;
+ XMBUF_BLOCKSHIFT = libxfs_highbit32(XMBUF_BLOCKSIZE);
+}
+
+/* Allocate a new cache node (aka a xfs_buf) */
+static struct cache_node *
+xmbuf_cache_alloc(
+ cache_key_t key)
+{
+ struct xfs_bufkey *bufkey = (struct xfs_bufkey *)key;
+ struct xfs_buf *bp;
+ int error;
+
+ bp = kmem_cache_zalloc(xfs_buf_cache, 0);
+ if (!bp)
+ return NULL;
+
+ bp->b_cache_key = bufkey->blkno;
+ bp->b_length = bufkey->bblen;
+ bp->b_target = bufkey->buftarg;
+ bp->b_mount = bufkey->buftarg->bt_mount;
+
+ pthread_mutex_init(&bp->b_lock, NULL);
+ INIT_LIST_HEAD(&bp->b_li_list);
+ bp->b_maps = &bp->__b_map;
+
+ bp->b_nmaps = 1;
+ bp->b_maps[0].bm_bn = bufkey->blkno;
+ bp->b_maps[0].bm_len = bp->b_length;
+
+ error = xmbuf_map_page(bp);
+ if (error) {
+ fprintf(stderr,
+ _("%s: %s can't mmap %u bytes at xfile offset %llu: %s\n"),
+ progname, __FUNCTION__, BBTOB(bp->b_length),
+ (unsigned long long)BBTOB(bufkey->blkno),
+ strerror(error));
+
+ kmem_cache_free(xfs_buf_cache, bp);
+ return NULL;
+ }
+
+ return &bp->b_node;
+}
+
+/* Flush a buffer to disk before purging the cache node */
+static int
+xmbuf_cache_flush(
+ struct cache_node *node)
+{
+ /* direct mapped buffers do not need writing */
+ return 0;
+}
+
+/* Release resources, free the buffer. */
+static void
+xmbuf_cache_relse(
+ struct cache_node *node)
+{
+ struct xfs_buf *bp;
+
+ bp = container_of(node, struct xfs_buf, b_node);
+ xmbuf_unmap_page(bp);
+ kmem_cache_free(xfs_buf_cache, bp);
+}
+
+/* Release a bunch of buffers */
+static unsigned int
+xmbuf_cache_bulkrelse(
+ struct cache *cache,
+ struct list_head *list)
+{
+ struct cache_node *cn, *n;
+ int count = 0;
+
+ if (list_empty(list))
+ return 0;
+
+ list_for_each_entry_safe(cn, n, list, cn_mru) {
+ xmbuf_cache_relse(cn);
+ count++;
+ }
+
+ return count;
+}
+
+static struct cache_operations xmbuf_bcache_operations = {
+ .hash = libxfs_bhash,
+ .alloc = xmbuf_cache_alloc,
+ .flush = xmbuf_cache_flush,
+ .relse = xmbuf_cache_relse,
+ .compare = libxfs_bcompare,
+ .bulkrelse = xmbuf_cache_bulkrelse
+};
+
+/*
+ * Allocate a buffer cache target for a memory-backed file and set up the
+ * buffer target.
+ */
+int
+xmbuf_alloc(
+ struct xfs_mount *mp,
+ const char *descr,
+ unsigned long long maxpos,
+ struct xfs_buftarg **btpp)
+{
+ struct xfs_buftarg *btp;
+ struct xfile *xfile;
+ struct cache *cache;
+ int error;
+
+ btp = kzalloc(sizeof(*btp), GFP_KERNEL);
+ if (!btp)
+ return -ENOMEM;
+
+ error = xfile_create(descr, maxpos, &xfile);
+ if (error)
+ goto out_btp;
+
+ cache = cache_init(0, LIBXFS_BHASHSIZE(NULL), &xmbuf_bcache_operations);
+ if (!cache) {
+ error = -ENOMEM;
+ goto out_xfile;
+ }
+
+ /* Initialize buffer target */
+ btp->bt_mount = mp;
+ btp->bt_bdev = (dev_t)-1;
+ btp->bt_bdev_fd = -1;
+ btp->bt_xfile = xfile;
+ btp->bcache = cache;
+
+ error = pthread_mutex_init(&btp->lock, NULL);
+ if (error)
+ goto out_cache;
+
+ *btpp = btp;
+ return 0;
+
+out_cache:
+ cache_destroy(cache);
+out_xfile:
+ xfile_destroy(xfile);
+out_btp:
+ kfree(btp);
+ return error;
+}
+
+/* Free a buffer cache target for a memory-backed file. */
+void
+xmbuf_free(
+ struct xfs_buftarg *btp)
+{
+ ASSERT(xfs_buftarg_is_mem(btp));
+
+ cache_destroy(btp->bcache);
+ pthread_mutex_destroy(&btp->lock);
+ xfile_destroy(btp->bt_xfile);
+ kfree(btp);
+}
+
+/* Directly map a memfd page into the buffer cache. */
+int
+xmbuf_map_page(
+ struct xfs_buf *bp)
+{
+ struct xfile *xfile = bp->b_target->bt_xfile;
+ void *p;
+ loff_t pos;
+
+ pos = xfile->partition_pos + BBTOB(xfs_buf_daddr(bp));
+ p = mmap(NULL, BBTOB(bp->b_length), PROT_READ | PROT_WRITE, MAP_SHARED,
+ xfile->fcb->fd, pos);
+ if (p == MAP_FAILED)
+ return -errno;
+
+ bp->b_addr = p;
+ bp->b_flags |= LIBXFS_B_UPTODATE | LIBXFS_B_UNCHECKED;
+ bp->b_error = 0;
+ return 0;
+}
+
+/* Unmap a memfd page that was mapped into the buffer cache. */
+void
+xmbuf_unmap_page(
+ struct xfs_buf *bp)
+{
+ munmap(bp->b_addr, BBTOB(bp->b_length));
+ bp->b_addr = NULL;
+}
diff --git a/libxfs/buf_mem.h b/libxfs/buf_mem.h
new file mode 100644
index 000000000..d2be2c424
--- /dev/null
+++ b/libxfs/buf_mem.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __XFS_BUF_MEM_H__
+#define __XFS_BUF_MEM_H__
+
+extern unsigned int XMBUF_BLOCKSIZE;
+extern unsigned int XMBUF_BLOCKSHIFT;
+
+void xmbuf_libinit(void);
+
+static inline bool xfs_buftarg_is_mem(const struct xfs_buftarg *target)
+{
+ return target->bt_xfile != NULL;
+}
+
+int xmbuf_alloc(struct xfs_mount *mp, const char *descr,
+ unsigned long long maxpos, struct xfs_buftarg **btpp);
+void xmbuf_free(struct xfs_buftarg *btp);
+
+int xmbuf_map_page(struct xfs_buf *bp);
+void xmbuf_unmap_page(struct xfs_buf *bp);
+
+#endif /* __XFS_BUF_MEM_H__ */
diff --git a/libxfs/init.c b/libxfs/init.c
index eaeb0b666..82618a07e 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -22,6 +22,8 @@
#include "xfs_rmap_btree.h"
#include "xfs_refcount_btree.h"
#include "libfrog/platform.h"
+#include "libxfs/xfile.h"
+#include "libxfs/buf_mem.h"
#include "xfs_format.h"
#include "xfs_da_format.h"
@@ -253,6 +255,7 @@ int
libxfs_init(struct libxfs_init *a)
{
xfs_check_ondisk_structs();
+ xmbuf_libinit();
rcu_init();
rcu_register_thread();
radix_tree_init();
@@ -463,6 +466,7 @@ libxfs_buftarg_alloc(
btp->bt_mount = mp;
btp->bt_bdev = dev->dev;
btp->bt_bdev_fd = dev->fd;
+ btp->bt_xfile = NULL;
btp->flags = 0;
if (write_fails) {
btp->writes_left = write_fails;
diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index 7877e1768..ae3c4a948 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -27,6 +27,7 @@ struct xfs_buftarg {
unsigned long writes_left;
dev_t bt_bdev;
int bt_bdev_fd;
+ struct xfile *bt_xfile;
unsigned int flags;
struct cache *bcache; /* buffer cache */
};
@@ -58,6 +59,27 @@ xfs_buftarg_trip_write(
void libxfs_buftarg_init(struct xfs_mount *mp, struct libxfs_init *xi);
int libxfs_blkdev_issue_flush(struct xfs_buftarg *btp);
+/*
+ * The bufkey is used to pass the new buffer information to the cache object
+ * allocation routine. Because discontiguous buffers need to pass different
+ * information, we need fields to pass that information. However, because the
+ * blkno and bblen is needed for the initial cache entry lookup (i.e. for
+ * bcompare) the fact that the map/nmaps is non-null to switch to discontiguous
+ * buffer initialisation instead of a contiguous buffer.
+ */
+struct xfs_bufkey {
+ struct xfs_buftarg *buftarg;
+ xfs_daddr_t blkno;
+ unsigned int bblen;
+ struct xfs_buf_map *map;
+ int nmaps;
+};
+
+/* for buf_mem.c only: */
+unsigned int libxfs_bhash(cache_key_t key, unsigned int hashsize,
+ unsigned int hashshift);
+int libxfs_bcompare(struct cache_node *node, cache_key_t key);
+
#define LIBXFS_BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT)
#define XB_PAGES 2
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index cf986a7e7..50760cd86 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -18,7 +18,8 @@
#include "xfs_inode.h"
#include "xfs_trans.h"
#include "libfrog/platform.h"
-
+#include "libxfs/xfile.h"
+#include "libxfs/buf_mem.h"
#include "libxfs.h"
static void libxfs_brelse(struct cache_node *node);
@@ -69,6 +70,9 @@ libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
char *z;
int error;
+ if (xfs_buftarg_is_mem(btp))
+ return -EOPNOTSUPP;
+
start_offset = LIBXFS_BBTOOFF64(start);
/* try to use special zeroing methods, fall back to writes if needed */
@@ -167,26 +171,10 @@ static struct cache_mru xfs_buf_freelist =
{{&xfs_buf_freelist.cm_list, &xfs_buf_freelist.cm_list},
0, PTHREAD_MUTEX_INITIALIZER };
-/*
- * The bufkey is used to pass the new buffer information to the cache object
- * allocation routine. Because discontiguous buffers need to pass different
- * information, we need fields to pass that information. However, because the
- * blkno and bblen is needed for the initial cache entry lookup (i.e. for
- * bcompare) the fact that the map/nmaps is non-null to switch to discontiguous
- * buffer initialisation instead of a contiguous buffer.
- */
-struct xfs_bufkey {
- struct xfs_buftarg *buftarg;
- xfs_daddr_t blkno;
- unsigned int bblen;
- struct xfs_buf_map *map;
- int nmaps;
-};
-
/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
#define CACHE_LINE_SIZE 64
-static unsigned int
+unsigned int
libxfs_bhash(cache_key_t key, unsigned int hashsize, unsigned int hashshift)
{
uint64_t hashval = ((struct xfs_bufkey *)key)->blkno;
@@ -197,7 +185,7 @@ libxfs_bhash(cache_key_t key, unsigned int hashsize, unsigned int hashshift)
return tmp % hashsize;
}
-static int
+int
libxfs_bcompare(
struct cache_node *node,
cache_key_t key)
@@ -231,6 +219,8 @@ static void
__initbuf(struct xfs_buf *bp, struct xfs_buftarg *btp, xfs_daddr_t bno,
unsigned int bytes)
{
+ ASSERT(!xfs_buftarg_is_mem(btp));
+
bp->b_flags = 0;
bp->b_cache_key = bno;
bp->b_length = BTOBB(bytes);
@@ -577,7 +567,6 @@ libxfs_balloc(
return &bp->b_node;
}
-
static int
__read_buf(int fd, void *buf, int len, off_t offset, int flags)
{
@@ -607,6 +596,9 @@ libxfs_readbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, struct xfs_buf *bp,
ASSERT(len <= bp->b_length);
+ if (xfs_buftarg_is_mem(btp))
+ return 0;
+
error = __read_buf(fd, bp->b_addr, bytes, LIBXFS_BBTOOFF64(blkno), flags);
if (!error &&
bp->b_target == btp &&
@@ -639,6 +631,9 @@ libxfs_readbufr_map(struct xfs_buftarg *btp, struct xfs_buf *bp, int flags)
void *buf;
int i;
+ if (xfs_buftarg_is_mem(btp))
+ return 0;
+
buf = bp->b_addr;
for (i = 0; i < bp->b_nmaps; i++) {
off_t offset = LIBXFS_BBTOOFF64(bp->b_maps[i].bm_bn);
@@ -857,7 +852,9 @@ libxfs_bwrite(
}
}
- if (!(bp->b_flags & LIBXFS_B_DISCONTIG)) {
+ if (xfs_buftarg_is_mem(bp->b_target)) {
+ bp->b_error = 0;
+ } else if (!(bp->b_flags & LIBXFS_B_DISCONTIG)) {
bp->b_error = __write_buf(fd, bp->b_addr, BBTOB(bp->b_length),
LIBXFS_BBTOOFF64(xfs_buf_daddr(bp)),
bp->b_flags);
@@ -917,6 +914,8 @@ libxfs_buf_prepare_mru(
xfs_perag_put(bp->b_pag);
bp->b_pag = NULL;
+ ASSERT(!xfs_buftarg_is_mem(btp));
+
if (!(bp->b_flags & LIBXFS_B_DIRTY))
return;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 093/111] xfs: add a xfs_btree_ptrs_equal helper
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (91 preceding siblings ...)
2024-05-22 3:12 ` [PATCH 092/111] libxfs: support in-memory buffer cache targets Darrick J. Wong
@ 2024-05-22 3:13 ` Darrick J. Wong
2024-05-22 3:13 ` [PATCH 094/111] xfs: support in-memory btrees Darrick J. Wong
` (18 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:13 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 8c1771c45dfa9dddd4569727c48204b66073d2c2
This only has a single caller and thus might be a bit questionable,
but I think it really improves the readability of
xfs_btree_visit_block.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libxfs/xfs_btree.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index a989b2da2..5fd966a63 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -1040,6 +1040,17 @@ xfs_btree_set_ptr_null(
ptr->s = cpu_to_be32(NULLAGBLOCK);
}
+static inline bool
+xfs_btree_ptrs_equal(
+ struct xfs_btree_cur *cur,
+ union xfs_btree_ptr *ptr1,
+ union xfs_btree_ptr *ptr2)
+{
+ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
+ return ptr1->l == ptr2->l;
+ return ptr1->s == ptr2->s;
+}
+
/*
* Get/set/init sibling pointers
*/
@@ -4362,7 +4373,7 @@ xfs_btree_visit_block(
{
struct xfs_btree_block *block;
struct xfs_buf *bp;
- union xfs_btree_ptr rptr;
+ union xfs_btree_ptr rptr, bufptr;
int error;
/* do right sibling readahead */
@@ -4385,19 +4396,12 @@ xfs_btree_visit_block(
* return the same block without checking if the right sibling points
* back to us and creates a cyclic reference in the btree.
*/
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
- if (be64_to_cpu(rptr.l) == XFS_DADDR_TO_FSB(cur->bc_mp,
- xfs_buf_daddr(bp))) {
- xfs_btree_mark_sick(cur);
- return -EFSCORRUPTED;
- }
- } else {
- if (be32_to_cpu(rptr.s) == xfs_daddr_to_agbno(cur->bc_mp,
- xfs_buf_daddr(bp))) {
- xfs_btree_mark_sick(cur);
- return -EFSCORRUPTED;
- }
+ xfs_btree_buf_to_ptr(cur, bp, &bufptr);
+ if (xfs_btree_ptrs_equal(cur, &rptr, &bufptr)) {
+ xfs_btree_mark_sick(cur);
+ return -EFSCORRUPTED;
}
+
return xfs_btree_lookup_get_block(cur, level, &rptr, &block);
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 094/111] xfs: support in-memory btrees
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (92 preceding siblings ...)
2024-05-22 3:13 ` [PATCH 093/111] xfs: add a xfs_btree_ptrs_equal helper Darrick J. Wong
@ 2024-05-22 3:13 ` Darrick J. Wong
2024-05-22 3:13 ` [PATCH 095/111] xfs: launder in-memory btree buffers before transaction commit Darrick J. Wong
` (17 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:13 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: a095686a2383526d7315197e2419d84ee8470217
Adapt the generic btree cursor code to be able to create a btree whose
buffers come from a (presumably in-memory) buftarg with a header block
that's specific to in-memory btrees. We'll connect this to other parts
of online scrub in the next patches.
Note that in-memory btrees always have a block size matching the system
memory page size for efficiency reasons. There are also a few things we
need to do to finalize a btree update; that's covered in the next patch.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/libxfs.h | 2
include/xfs_mount.h | 5 +
include/xfs_trace.h | 7 +
libxfs/Makefile | 2
libxfs/buf_mem.c | 13 ++
libxfs/buf_mem.h | 2
libxfs/libxfs_api_defs.h | 1
libxfs/libxfs_io.h | 10 ++
libxfs/libxfs_priv.h | 14 ++-
libxfs/xfs_btree.c | 257 +++++++++++++++++++++++++++++++++++++++-------
libxfs/xfs_btree.h | 7 +
libxfs/xfs_btree_mem.c | 227 +++++++++++++++++++++++++++++++++++++++++
libxfs/xfs_btree_mem.h | 72 +++++++++++++
13 files changed, 577 insertions(+), 42 deletions(-)
create mode 100644 libxfs/xfs_btree_mem.c
create mode 100644 libxfs/xfs_btree_mem.h
diff --git a/include/libxfs.h b/include/libxfs.h
index 60d3b7968..563c40e57 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -9,6 +9,8 @@
/* For userspace XFS_RT is always defined */
#define CONFIG_XFS_RT
+/* Ditto in-memory btrees */
+#define CONFIG_XFS_BTREE_IN_MEM
#include "libxfs_api_defs.h"
#include "platform_defs.h"
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index 98d5b199d..9c492b8f5 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -301,4 +301,9 @@ struct xfs_defer_drain { /* empty */ };
static inline void xfs_perag_intent_hold(struct xfs_perag *pag) {}
static inline void xfs_perag_intent_rele(struct xfs_perag *pag) {}
+static inline void libxfs_buftarg_drain(struct xfs_buftarg *btp)
+{
+ cache_purge(btp->bcache);
+}
+
#endif /* __XFS_MOUNT_H__ */
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index df25dc2a9..6c8eeff1e 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -6,6 +6,13 @@
#ifndef __TRACE_H__
#define __TRACE_H__
+#define trace_xfbtree_init(...) ((void) 0)
+#define trace_xfbtree_create_root_buf(...) ((void) 0)
+#define trace_xfbtree_alloc_block(...) ((void) 0)
+#define trace_xfbtree_free_block(...) ((void) 0)
+#define trace_xfbtree_trans_cancel_buf(...) ((void) 0)
+#define trace_xfbtree_trans_commit_buf(...) ((void) 0)
+
#define trace_xfs_agfl_reset(a,b,c,d) ((void) 0)
#define trace_xfs_agfl_free_defer(a,b,c,d,e) ((void) 0)
#define trace_xfs_alloc_cur_check(...) ((void) 0)
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 8dc9a7905..9baee62c0 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -37,6 +37,7 @@ HFILES = \
xfs_bmap.h \
xfs_bmap_btree.h \
xfs_btree.h \
+ xfs_btree_mem.h \
xfs_btree_staging.h \
xfs_attr_remote.h \
xfs_cksum.h \
@@ -81,6 +82,7 @@ CFILES = buf_mem.c \
xfs_bmap.c \
xfs_bmap_btree.c \
xfs_btree.c \
+ xfs_btree_mem.c \
xfs_btree_staging.c \
xfs_da_btree.c \
xfs_defer.c \
diff --git a/libxfs/buf_mem.c b/libxfs/buf_mem.c
index 7c8fa1d2c..7a30afe27 100644
--- a/libxfs/buf_mem.c
+++ b/libxfs/buf_mem.c
@@ -233,3 +233,16 @@ xmbuf_unmap_page(
munmap(bp->b_addr, BBTOB(bp->b_length));
bp->b_addr = NULL;
}
+
+/* Is this a valid daddr within the buftarg? */
+bool
+xmbuf_verify_daddr(
+ struct xfs_buftarg *btp,
+ xfs_daddr_t daddr)
+{
+ struct xfile *xf = btp->bt_xfile;
+
+ ASSERT(xfs_buftarg_is_mem(btp));
+
+ return daddr < (xf->maxbytes >> BBSHIFT);
+}
diff --git a/libxfs/buf_mem.h b/libxfs/buf_mem.h
index d2be2c424..d40f9f9df 100644
--- a/libxfs/buf_mem.h
+++ b/libxfs/buf_mem.h
@@ -23,4 +23,6 @@ void xmbuf_free(struct xfs_buftarg *btp);
int xmbuf_map_page(struct xfs_buf *bp);
void xmbuf_unmap_page(struct xfs_buf *bp);
+bool xmbuf_verify_daddr(struct xfs_buftarg *btp, xfs_daddr_t daddr);
+
#endif /* __XFS_BUF_MEM_H__ */
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 0e72944bc..fe8a0dc40 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -76,6 +76,7 @@
#define xfs_buf_read_uncached libxfs_buf_read_uncached
#define xfs_buf_relse libxfs_buf_relse
#define xfs_buf_unlock libxfs_buf_unlock
+#define xfs_buftarg_drain libxfs_buftarg_drain
#define xfs_bunmapi libxfs_bunmapi
#define xfs_bwrite libxfs_bwrite
#define xfs_calc_dquots_per_chunk libxfs_calc_dquots_per_chunk
diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index ae3c4a948..82d86f1d1 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -282,4 +282,14 @@ xfs_buf_delwri_queue_here(struct xfs_buf *bp, struct list_head *buffer_list)
int xfs_buf_delwri_submit(struct list_head *buffer_list);
void xfs_buf_delwri_cancel(struct list_head *list);
+xfs_daddr_t xfs_buftarg_nr_sectors(struct xfs_buftarg *btp);
+
+static inline bool
+xfs_buftarg_verify_daddr(
+ struct xfs_buftarg *btp,
+ xfs_daddr_t daddr)
+{
+ return daddr < xfs_buftarg_nr_sectors(btp);
+}
+
#endif /* __LIBXFS_IO_H__ */
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index aee85c155..81f641f32 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -38,6 +38,7 @@
#define __LIBXFS_INTERNAL_XFS_H__
#define CONFIG_XFS_RT
+#define CONFIG_XFS_BTREE_IN_MEM
#include "libxfs_api_defs.h"
#include "platform_defs.h"
@@ -389,11 +390,14 @@ void __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa);
#define xfs_trans_buf_copy_type(dbp, sbp)
-/* no readahead, need to avoid set-but-unused var warnings. */
-#define xfs_buf_readahead(a,d,c,ops) ({ \
- xfs_daddr_t __d = d; \
- __d = __d; /* no set-but-unused warning */ \
-})
+static inline void
+xfs_buf_readahead(
+ struct xfs_buftarg *target,
+ xfs_daddr_t blkno,
+ size_t numblks,
+ const struct xfs_buf_ops *ops)
+{
+}
#define xfs_buf_readahead_map(a,b,c,ops) ((void) 0) /* no readahead */
#define xfs_sort qsort
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 5fd966a63..a91441b46 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -25,6 +25,9 @@
#include "xfs_rmap_btree.h"
#include "xfs_refcount_btree.h"
#include "xfs_health.h"
+#include "xfile.h"
+#include "buf_mem.h"
+#include "xfs_btree_mem.h"
/*
* Btree magic numbers.
@@ -72,6 +75,25 @@ xfs_btree_check_fsblock_siblings(
return NULL;
}
+static inline xfs_failaddr_t
+xfs_btree_check_memblock_siblings(
+ struct xfs_buftarg *btp,
+ xfbno_t bno,
+ __be64 dsibling)
+{
+ xfbno_t sibling;
+
+ if (dsibling == cpu_to_be64(NULLFSBLOCK))
+ return NULL;
+
+ sibling = be64_to_cpu(dsibling);
+ if (sibling == bno)
+ return __this_address;
+ if (!xmbuf_verify_daddr(btp, xfbno_to_daddr(sibling)))
+ return __this_address;
+ return NULL;
+}
+
static inline xfs_failaddr_t
xfs_btree_check_agblock_siblings(
struct xfs_perag *pag,
@@ -161,6 +183,34 @@ __xfs_btree_check_fsblock(
return fa;
}
+/*
+ * Check an in-memory btree block header. Return the address of the failing
+ * check, or NULL if everything is ok.
+ */
+static xfs_failaddr_t
+__xfs_btree_check_memblock(
+ struct xfs_btree_cur *cur,
+ struct xfs_btree_block *block,
+ int level,
+ struct xfs_buf *bp)
+{
+ struct xfs_buftarg *btp = cur->bc_mem.xfbtree->target;
+ xfs_failaddr_t fa;
+ xfbno_t bno;
+
+ fa = __xfs_btree_check_lblock_hdr(cur, block, level, bp);
+ if (fa)
+ return fa;
+
+ bno = xfs_daddr_to_xfbno(xfs_buf_daddr(bp));
+ fa = xfs_btree_check_memblock_siblings(btp, bno,
+ block->bb_u.l.bb_leftsib);
+ if (!fa)
+ fa = xfs_btree_check_memblock_siblings(btp, bno,
+ block->bb_u.l.bb_rightsib);
+ return fa;
+}
+
/*
* Check a short btree block header. Return the address of the failing check,
* or NULL if everything is ok.
@@ -213,9 +263,17 @@ __xfs_btree_check_block(
int level,
struct xfs_buf *bp)
{
- if (cur->bc_ops->type == XFS_BTREE_TYPE_AG)
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_MEM:
+ return __xfs_btree_check_memblock(cur, block, level, bp);
+ case XFS_BTREE_TYPE_AG:
return __xfs_btree_check_agblock(cur, block, level, bp);
- return __xfs_btree_check_fsblock(cur, block, level, bp);
+ case XFS_BTREE_TYPE_INODE:
+ return __xfs_btree_check_fsblock(cur, block, level, bp);
+ default:
+ ASSERT(0);
+ return __this_address;
+ }
}
static inline unsigned int xfs_btree_block_errtag(struct xfs_btree_cur *cur)
@@ -259,14 +317,22 @@ __xfs_btree_check_ptr(
if (level <= 0)
return -EFSCORRUPTED;
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_MEM:
+ if (!xfbtree_verify_bno(cur->bc_mem.xfbtree,
+ be64_to_cpu((&ptr->l)[index])))
+ return -EFSCORRUPTED;
+ break;
+ case XFS_BTREE_TYPE_INODE:
if (!xfs_verify_fsbno(cur->bc_mp,
be64_to_cpu((&ptr->l)[index])))
return -EFSCORRUPTED;
- } else {
+ break;
+ case XFS_BTREE_TYPE_AG:
if (!xfs_verify_agbno(cur->bc_ag.pag,
be32_to_cpu((&ptr->s)[index])))
return -EFSCORRUPTED;
+ break;
}
return 0;
@@ -287,17 +353,26 @@ xfs_btree_check_ptr(
error = __xfs_btree_check_ptr(cur, ptr, index, level);
if (error) {
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_MEM:
+ xfs_err(cur->bc_mp,
+"In-memory: Corrupt %sbt flags 0x%x pointer at level %d index %d fa %pS.",
+ cur->bc_ops->name, cur->bc_flags, level, index,
+ __this_address);
+ break;
+ case XFS_BTREE_TYPE_INODE:
xfs_err(cur->bc_mp,
"Inode %llu fork %d: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ino.ip->i_ino,
cur->bc_ino.whichfork, cur->bc_ops->name,
level, index);
- } else {
+ break;
+ case XFS_BTREE_TYPE_AG:
xfs_err(cur->bc_mp,
"AG %u: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ag.pag->pag_agno, cur->bc_ops->name,
level, index);
+ break;
}
xfs_btree_mark_sick(cur);
}
@@ -454,11 +529,35 @@ xfs_btree_del_cursor(
case XFS_BTREE_TYPE_INODE:
/* nothing to do */
break;
+ case XFS_BTREE_TYPE_MEM:
+ if (cur->bc_mem.pag)
+ xfs_perag_put(cur->bc_mem.pag);
+ break;
}
kmem_cache_free(cur->bc_cache, cur);
}
+/* Return the buffer target for this btree's buffer. */
+static inline struct xfs_buftarg *
+xfs_btree_buftarg(
+ struct xfs_btree_cur *cur)
+{
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_MEM)
+ return cur->bc_mem.xfbtree->target;
+ return cur->bc_mp->m_ddev_targp;
+}
+
+/* Return the block size (in units of 512b sectors) for this btree. */
+static inline unsigned int
+xfs_btree_bbsize(
+ struct xfs_btree_cur *cur)
+{
+ if (cur->bc_ops->type == XFS_BTREE_TYPE_MEM)
+ return XFBNO_BBSIZE;
+ return cur->bc_mp->m_bsize;
+}
+
/*
* Duplicate the btree cursor.
* Allocate a new one, copy the record, re-get the buffers.
@@ -502,10 +601,11 @@ xfs_btree_dup_cursor(
new->bc_levels[i].ra = cur->bc_levels[i].ra;
bp = cur->bc_levels[i].bp;
if (bp) {
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
- xfs_buf_daddr(bp), mp->m_bsize,
- 0, &bp,
- cur->bc_ops->buf_ops);
+ error = xfs_trans_read_buf(mp, tp,
+ xfs_btree_buftarg(cur),
+ xfs_buf_daddr(bp),
+ xfs_btree_bbsize(cur), 0, &bp,
+ cur->bc_ops->buf_ops);
if (xfs_metadata_is_sick(error))
xfs_btree_mark_sick(new);
if (error) {
@@ -882,6 +982,32 @@ xfs_btree_readahead_fsblock(
return rval;
}
+STATIC int
+xfs_btree_readahead_memblock(
+ struct xfs_btree_cur *cur,
+ int lr,
+ struct xfs_btree_block *block)
+{
+ struct xfs_buftarg *btp = cur->bc_mem.xfbtree->target;
+ xfbno_t left = be64_to_cpu(block->bb_u.l.bb_leftsib);
+ xfbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib);
+ int rval = 0;
+
+ if ((lr & XFS_BTCUR_LEFTRA) && left != NULLFSBLOCK) {
+ xfs_buf_readahead(btp, xfbno_to_daddr(left), XFBNO_BBSIZE,
+ cur->bc_ops->buf_ops);
+ rval++;
+ }
+
+ if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLFSBLOCK) {
+ xfs_buf_readahead(btp, xfbno_to_daddr(right), XFBNO_BBSIZE,
+ cur->bc_ops->buf_ops);
+ rval++;
+ }
+
+ return rval;
+}
+
STATIC int
xfs_btree_readahead_agblock(
struct xfs_btree_cur *cur,
@@ -936,9 +1062,17 @@ xfs_btree_readahead(
cur->bc_levels[lev].ra |= lr;
block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp);
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_AG:
+ return xfs_btree_readahead_agblock(cur, lr, block);
+ case XFS_BTREE_TYPE_INODE:
return xfs_btree_readahead_fsblock(cur, lr, block);
- return xfs_btree_readahead_agblock(cur, lr, block);
+ case XFS_BTREE_TYPE_MEM:
+ return xfs_btree_readahead_memblock(cur, lr, block);
+ default:
+ ASSERT(0);
+ return 0;
+ }
}
STATIC int
@@ -947,23 +1081,24 @@ xfs_btree_ptr_to_daddr(
const union xfs_btree_ptr *ptr,
xfs_daddr_t *daddr)
{
- xfs_fsblock_t fsbno;
- xfs_agblock_t agbno;
int error;
error = xfs_btree_check_ptr(cur, ptr, 0, 1);
if (error)
return error;
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
- fsbno = be64_to_cpu(ptr->l);
- *daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno);
- } else {
- agbno = be32_to_cpu(ptr->s);
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_AG:
*daddr = XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_ag.pag->pag_agno,
- agbno);
+ be32_to_cpu(ptr->s));
+ break;
+ case XFS_BTREE_TYPE_INODE:
+ *daddr = XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l));
+ break;
+ case XFS_BTREE_TYPE_MEM:
+ *daddr = xfbno_to_daddr(be64_to_cpu(ptr->l));
+ break;
}
-
return 0;
}
@@ -983,8 +1118,9 @@ xfs_btree_readahead_ptr(
if (xfs_btree_ptr_to_daddr(cur, ptr, &daddr))
return;
- xfs_buf_readahead(cur->bc_mp->m_ddev_targp, daddr,
- cur->bc_mp->m_bsize * count, cur->bc_ops->buf_ops);
+ xfs_buf_readahead(xfs_btree_buftarg(cur), daddr,
+ xfs_btree_bbsize(cur) * count,
+ cur->bc_ops->buf_ops);
}
/*
@@ -1169,9 +1305,17 @@ static inline __u64
xfs_btree_owner(
struct xfs_btree_cur *cur)
{
- if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_MEM:
+ return cur->bc_mem.xfbtree->owner;
+ case XFS_BTREE_TYPE_INODE:
return cur->bc_ino.ip->i_ino;
- return cur->bc_ag.pag->pag_agno;
+ case XFS_BTREE_TYPE_AG:
+ return cur->bc_ag.pag->pag_agno;
+ default:
+ ASSERT(0);
+ return 0;
+ }
}
void
@@ -1215,12 +1359,18 @@ xfs_btree_buf_to_ptr(
struct xfs_buf *bp,
union xfs_btree_ptr *ptr)
{
- if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
- ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp,
- xfs_buf_daddr(bp)));
- else {
+ switch (cur->bc_ops->type) {
+ case XFS_BTREE_TYPE_AG:
ptr->s = cpu_to_be32(xfs_daddr_to_agbno(cur->bc_mp,
xfs_buf_daddr(bp)));
+ break;
+ case XFS_BTREE_TYPE_INODE:
+ ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp,
+ xfs_buf_daddr(bp)));
+ break;
+ case XFS_BTREE_TYPE_MEM:
+ ptr->l = cpu_to_be64(xfs_daddr_to_xfbno(xfs_buf_daddr(bp)));
+ break;
}
}
@@ -1239,15 +1389,14 @@ xfs_btree_get_buf_block(
struct xfs_btree_block **block,
struct xfs_buf **bpp)
{
- struct xfs_mount *mp = cur->bc_mp;
- xfs_daddr_t d;
- int error;
+ xfs_daddr_t d;
+ int error;
error = xfs_btree_ptr_to_daddr(cur, ptr, &d);
if (error)
return error;
- error = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize,
- 0, bpp);
+ error = xfs_trans_get_buf(cur->bc_tp, xfs_btree_buftarg(cur), d,
+ xfs_btree_bbsize(cur), 0, bpp);
if (error)
return error;
@@ -1278,9 +1427,9 @@ xfs_btree_read_buf_block(
error = xfs_btree_ptr_to_daddr(cur, ptr, &d);
if (error)
return error;
- error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
- mp->m_bsize, flags, bpp,
- cur->bc_ops->buf_ops);
+ error = xfs_trans_read_buf(mp, cur->bc_tp, xfs_btree_buftarg(cur), d,
+ xfs_btree_bbsize(cur), flags, bpp,
+ cur->bc_ops->buf_ops);
if (xfs_metadata_is_sick(error))
xfs_btree_mark_sick(cur);
if (error)
@@ -4579,6 +4728,8 @@ xfs_btree_fsblock_verify(
xfs_fsblock_t fsb;
xfs_failaddr_t fa;
+ ASSERT(!xfs_buftarg_is_mem(bp->b_target));
+
/* numrecs verification */
if (be16_to_cpu(block->bb_numrecs) > max_recs)
return __this_address;
@@ -4593,6 +4744,36 @@ xfs_btree_fsblock_verify(
return fa;
}
+/* Verify an in-memory btree block. */
+xfs_failaddr_t
+xfs_btree_memblock_verify(
+ struct xfs_buf *bp,
+ unsigned int max_recs)
+{
+ struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
+ struct xfs_buftarg *btp = bp->b_target;
+ xfs_failaddr_t fa;
+ xfbno_t bno;
+
+ ASSERT(xfs_buftarg_is_mem(bp->b_target));
+
+ /* numrecs verification */
+ if (be16_to_cpu(block->bb_numrecs) > max_recs)
+ return __this_address;
+
+ /* sibling pointer verification */
+ bno = xfs_daddr_to_xfbno(xfs_buf_daddr(bp));
+ fa = xfs_btree_check_memblock_siblings(btp, bno,
+ block->bb_u.l.bb_leftsib);
+ if (fa)
+ return fa;
+ fa = xfs_btree_check_memblock_siblings(btp, bno,
+ block->bb_u.l.bb_rightsib);
+ if (fa)
+ return fa;
+
+ return NULL;
+}
/**
* xfs_btree_agblock_v5hdr_verify() -- verify the v5 fields of a short-format
* btree block
@@ -4634,6 +4815,8 @@ xfs_btree_agblock_verify(
xfs_agblock_t agbno;
xfs_failaddr_t fa;
+ ASSERT(!xfs_buftarg_is_mem(bp->b_target));
+
/* numrecs verification */
if (be16_to_cpu(block->bb_numrecs) > max_recs)
return __this_address;
diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h
index bacd67cc8..f93374278 100644
--- a/libxfs/xfs_btree.h
+++ b/libxfs/xfs_btree.h
@@ -112,6 +112,7 @@ static inline enum xbtree_key_contig xbtree_key_contig(uint64_t x, uint64_t y)
enum xfs_btree_type {
XFS_BTREE_TYPE_AG,
XFS_BTREE_TYPE_INODE,
+ XFS_BTREE_TYPE_MEM,
};
struct xfs_btree_ops {
@@ -281,6 +282,10 @@ struct xfs_btree_cur
struct xfs_buf *agbp;
struct xbtree_afakeroot *afake; /* for staging cursor */
} bc_ag;
+ struct {
+ struct xfbtree *xfbtree;
+ struct xfs_perag *pag;
+ } bc_mem;
};
/* per-format private data */
@@ -455,6 +460,8 @@ xfs_failaddr_t xfs_btree_fsblock_v5hdr_verify(struct xfs_buf *bp,
uint64_t owner);
xfs_failaddr_t xfs_btree_fsblock_verify(struct xfs_buf *bp,
unsigned int max_recs);
+xfs_failaddr_t xfs_btree_memblock_verify(struct xfs_buf *bp,
+ unsigned int max_recs);
unsigned int xfs_btree_compute_maxlevels(const unsigned int *limits,
unsigned long long records);
diff --git a/libxfs/xfs_btree_mem.c b/libxfs/xfs_btree_mem.c
new file mode 100644
index 000000000..31835e065
--- /dev/null
+++ b/libxfs/xfs_btree_mem.c
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "libxfs_priv.h"
+#include "xfs_fs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
+#include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_mount.h"
+#include "xfs_trans.h"
+#include "xfs_btree.h"
+#include "xfile.h"
+#include "buf_mem.h"
+#include "xfs_btree_mem.h"
+#include "xfs_ag.h"
+#include "xfs_trace.h"
+
+/* Set the root of an in-memory btree. */
+void
+xfbtree_set_root(
+ struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *ptr,
+ int inc)
+{
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_MEM);
+
+ cur->bc_mem.xfbtree->root = *ptr;
+ cur->bc_mem.xfbtree->nlevels += inc;
+}
+
+/* Initialize a pointer from the in-memory btree header. */
+void
+xfbtree_init_ptr_from_cur(
+ struct xfs_btree_cur *cur,
+ union xfs_btree_ptr *ptr)
+{
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_MEM);
+
+ *ptr = cur->bc_mem.xfbtree->root;
+}
+
+/* Duplicate an in-memory btree cursor. */
+struct xfs_btree_cur *
+xfbtree_dup_cursor(
+ struct xfs_btree_cur *cur)
+{
+ struct xfs_btree_cur *ncur;
+
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_MEM);
+
+ ncur = xfs_btree_alloc_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ops,
+ cur->bc_maxlevels, cur->bc_cache);
+ ncur->bc_flags = cur->bc_flags;
+ ncur->bc_nlevels = cur->bc_nlevels;
+ ncur->bc_mem.xfbtree = cur->bc_mem.xfbtree;
+
+ if (cur->bc_mem.pag)
+ ncur->bc_mem.pag = xfs_perag_hold(cur->bc_mem.pag);
+
+ return ncur;
+}
+
+/* Close the btree xfile and release all resources. */
+void
+xfbtree_destroy(
+ struct xfbtree *xfbt)
+{
+ xfs_buftarg_drain(xfbt->target);
+}
+
+/* Compute the number of bytes available for records. */
+static inline unsigned int
+xfbtree_rec_bytes(
+ struct xfs_mount *mp,
+ const struct xfs_btree_ops *ops)
+{
+ return XMBUF_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN;
+}
+
+/* Initialize an empty leaf block as the btree root. */
+STATIC int
+xfbtree_init_leaf_block(
+ struct xfs_mount *mp,
+ struct xfbtree *xfbt,
+ const struct xfs_btree_ops *ops)
+{
+ struct xfs_buf *bp;
+ xfbno_t bno = xfbt->highest_bno++;
+ int error;
+
+ error = xfs_buf_get(xfbt->target, xfbno_to_daddr(bno), XFBNO_BBSIZE,
+ &bp);
+ if (error)
+ return error;
+
+ trace_xfbtree_create_root_buf(xfbt, bp);
+
+ bp->b_ops = ops->buf_ops;
+ xfs_btree_init_buf(mp, bp, ops, 0, 0, xfbt->owner);
+ xfs_buf_relse(bp);
+
+ xfbt->root.l = cpu_to_be64(bno);
+ return 0;
+}
+
+/*
+ * Create an in-memory btree root that can be used with the given xmbuf.
+ * Callers must set xfbt->owner.
+ */
+int
+xfbtree_init(
+ struct xfs_mount *mp,
+ struct xfbtree *xfbt,
+ struct xfs_buftarg *btp,
+ const struct xfs_btree_ops *ops)
+{
+ unsigned int blocklen = xfbtree_rec_bytes(mp, ops);
+ unsigned int keyptr_len;
+ int error;
+
+ /* Requires a long-format CRC-format btree */
+ if (!xfs_has_crc(mp)) {
+ ASSERT(xfs_has_crc(mp));
+ return -EINVAL;
+ }
+ if (ops->ptr_len != XFS_BTREE_LONG_PTR_LEN) {
+ ASSERT(ops->ptr_len == XFS_BTREE_LONG_PTR_LEN);
+ return -EINVAL;
+ }
+
+ memset(xfbt, 0, sizeof(*xfbt));
+ xfbt->target = btp;
+
+ /* Set up min/maxrecs for this btree. */
+ keyptr_len = ops->key_len + sizeof(__be64);
+ xfbt->maxrecs[0] = blocklen / ops->rec_len;
+ xfbt->maxrecs[1] = blocklen / keyptr_len;
+ xfbt->minrecs[0] = xfbt->maxrecs[0] / 2;
+ xfbt->minrecs[1] = xfbt->maxrecs[1] / 2;
+ xfbt->highest_bno = 0;
+ xfbt->nlevels = 1;
+
+ /* Initialize the empty btree. */
+ error = xfbtree_init_leaf_block(mp, xfbt, ops);
+ if (error)
+ goto err_freesp;
+
+ trace_xfbtree_init(mp, xfbt, ops);
+
+ return 0;
+
+err_freesp:
+ xfs_buftarg_drain(xfbt->target);
+ return error;
+}
+
+/* Allocate a block to our in-memory btree. */
+int
+xfbtree_alloc_block(
+ struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *start,
+ union xfs_btree_ptr *new,
+ int *stat)
+{
+ struct xfbtree *xfbt = cur->bc_mem.xfbtree;
+ xfbno_t bno = xfbt->highest_bno++;
+
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_MEM);
+
+ trace_xfbtree_alloc_block(xfbt, cur, bno);
+
+ /* Fail if the block address exceeds the maximum for the buftarg. */
+ if (!xfbtree_verify_bno(xfbt, bno)) {
+ ASSERT(xfbtree_verify_bno(xfbt, bno));
+ *stat = 0;
+ return 0;
+ }
+
+ new->l = cpu_to_be64(bno);
+ *stat = 1;
+ return 0;
+}
+
+/* Free a block from our in-memory btree. */
+int
+xfbtree_free_block(
+ struct xfs_btree_cur *cur,
+ struct xfs_buf *bp)
+{
+ struct xfbtree *xfbt = cur->bc_mem.xfbtree;
+ xfs_daddr_t daddr = xfs_buf_daddr(bp);
+ xfbno_t bno = xfs_daddr_to_xfbno(daddr);
+
+ ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_MEM);
+
+ trace_xfbtree_free_block(xfbt, cur, bno);
+
+ if (bno + 1 == xfbt->highest_bno)
+ xfbt->highest_bno--;
+
+ return 0;
+}
+
+/* Return the minimum number of records for a btree block. */
+int
+xfbtree_get_minrecs(
+ struct xfs_btree_cur *cur,
+ int level)
+{
+ struct xfbtree *xfbt = cur->bc_mem.xfbtree;
+
+ return xfbt->minrecs[level != 0];
+}
+
+/* Return the maximum number of records for a btree block. */
+int
+xfbtree_get_maxrecs(
+ struct xfs_btree_cur *cur,
+ int level)
+{
+ struct xfbtree *xfbt = cur->bc_mem.xfbtree;
+
+ return xfbt->maxrecs[level != 0];
+}
diff --git a/libxfs/xfs_btree_mem.h b/libxfs/xfs_btree_mem.h
new file mode 100644
index 000000000..ecc2ceac3
--- /dev/null
+++ b/libxfs/xfs_btree_mem.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __XFS_BTREE_MEM_H__
+#define __XFS_BTREE_MEM_H__
+
+typedef uint64_t xfbno_t;
+
+#define XFBNO_BLOCKSIZE (XMBUF_BLOCKSIZE)
+#define XFBNO_BBSHIFT (XMBUF_BLOCKSHIFT - BBSHIFT)
+#define XFBNO_BBSIZE (XFBNO_BLOCKSIZE >> BBSHIFT)
+
+static inline xfs_daddr_t xfbno_to_daddr(xfbno_t blkno)
+{
+ return blkno << XFBNO_BBSHIFT;
+}
+
+static inline xfbno_t xfs_daddr_to_xfbno(xfs_daddr_t daddr)
+{
+ return daddr >> XFBNO_BBSHIFT;
+}
+
+struct xfbtree {
+ /* buffer cache target for this in-memory btree */
+ struct xfs_buftarg *target;
+
+ /* Highest block number that has been written to. */
+ xfbno_t highest_bno;
+
+ /* Owner of this btree. */
+ unsigned long long owner;
+
+ /* Btree header */
+ union xfs_btree_ptr root;
+ unsigned int nlevels;
+
+ /* Minimum and maximum records per block. */
+ unsigned int maxrecs[2];
+ unsigned int minrecs[2];
+};
+
+#ifdef CONFIG_XFS_BTREE_IN_MEM
+static inline bool xfbtree_verify_bno(struct xfbtree *xfbt, xfbno_t bno)
+{
+ return xmbuf_verify_daddr(xfbt->target, xfbno_to_daddr(bno));
+}
+
+void xfbtree_set_root(struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *ptr, int inc);
+void xfbtree_init_ptr_from_cur(struct xfs_btree_cur *cur,
+ union xfs_btree_ptr *ptr);
+struct xfs_btree_cur *xfbtree_dup_cursor(struct xfs_btree_cur *cur);
+
+int xfbtree_get_minrecs(struct xfs_btree_cur *cur, int level);
+int xfbtree_get_maxrecs(struct xfs_btree_cur *cur, int level);
+
+int xfbtree_alloc_block(struct xfs_btree_cur *cur,
+ const union xfs_btree_ptr *start, union xfs_btree_ptr *ptr,
+ int *stat);
+int xfbtree_free_block(struct xfs_btree_cur *cur, struct xfs_buf *bp);
+
+/* Callers must set xfbt->target and xfbt->owner before calling this */
+int xfbtree_init(struct xfs_mount *mp, struct xfbtree *xfbt,
+ struct xfs_buftarg *btp, const struct xfs_btree_ops *ops);
+void xfbtree_destroy(struct xfbtree *xfbt);
+#else
+# define xfbtree_verify_bno(...) (false)
+#endif /* CONFIG_XFS_BTREE_IN_MEM */
+
+#endif /* __XFS_BTREE_MEM_H__ */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 095/111] xfs: launder in-memory btree buffers before transaction commit
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (93 preceding siblings ...)
2024-05-22 3:13 ` [PATCH 094/111] xfs: support in-memory btrees Darrick J. Wong
@ 2024-05-22 3:13 ` Darrick J. Wong
2024-05-22 3:13 ` [PATCH 096/111] xfs: create a helper to decide if a file mapping targets the rt volume Darrick J. Wong
` (16 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:13 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 0dc63c8a1ce39c1ac7da536ee9174cdc714afae2
As we've noted in various places, all current users of in-memory btrees
are online fsck. Online fsck only stages a btree long enough to rebuild
an ondisk data structure, which means that the in-memory btree is
ephemeral. Furthermore, if we encounter /any/ errors while updating an
in-memory btree, all we do is tear down all the staged data and return
an errno to userspace. In-memory btrees need not be transactional, so
their buffers should not be committed to the ondisk log, nor should they
be checkpointed by the AIL. That's just as well since the ephemeral
nature of the btree means that the buftarg and the buffers may disappear
quickly anyway.
Therefore, we need a way to launder the btree buffers that get attached
to the transaction by the generic btree code. Because the buffers are
directly mapped to backing file pages, there's no need to bwrite them
back to the tmpfs file. All we need to do is clean enough of the buffer
log item state so that the bli can be detached from the buffer, remove
the bli from the transaction's log item list, and reset the transaction
dirty state as if the laundered items had never been there.
For simplicity, create xfbtree transaction commit and cancel helpers
that launder the in-memory btree buffers for callers. Once laundered,
call the write verifier on non-stale buffers to avoid integrity issues,
or punch a hole in the backing file for stale buffers.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/xfs_trace.h | 1
include/xfs_trans.h | 1
libxfs/buf_mem.c | 65 +++++++++++++++++++++++++
libxfs/buf_mem.h | 2 +
libxfs/libxfs_api_defs.h | 1
libxfs/trans.c | 40 +++++++++++++++
libxfs/xfs_btree_mem.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++
libxfs/xfs_btree_mem.h | 3 +
8 files changed, 232 insertions(+)
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index 6c8eeff1e..6b9d3358a 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -211,6 +211,7 @@
#define trace_xfs_trans_cancel(a,b) ((void) 0)
#define trace_xfs_trans_brelse(a) ((void) 0)
#define trace_xfs_trans_binval(a) ((void) 0)
+#define trace_xfs_trans_bdetach(a) ((void) 0)
#define trace_xfs_trans_bjoin(a) ((void) 0)
#define trace_xfs_trans_bhold(a) ((void) 0)
#define trace_xfs_trans_bhold_release(a) ((void) 0)
diff --git a/include/xfs_trans.h b/include/xfs_trans.h
index ac82c3bc4..b7f01ff07 100644
--- a/include/xfs_trans.h
+++ b/include/xfs_trans.h
@@ -114,6 +114,7 @@ int libxfs_trans_roll_inode (struct xfs_trans **, struct xfs_inode *);
void libxfs_trans_brelse(struct xfs_trans *, struct xfs_buf *);
void libxfs_trans_binval(struct xfs_trans *, struct xfs_buf *);
void libxfs_trans_bjoin(struct xfs_trans *, struct xfs_buf *);
+void libxfs_trans_bdetach(struct xfs_trans *tp, struct xfs_buf *bp);
void libxfs_trans_bhold(struct xfs_trans *, struct xfs_buf *);
void libxfs_trans_bhold_release(struct xfs_trans *, struct xfs_buf *);
void libxfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *);
diff --git a/libxfs/buf_mem.c b/libxfs/buf_mem.c
index 7a30afe27..e5b91d3cf 100644
--- a/libxfs/buf_mem.c
+++ b/libxfs/buf_mem.c
@@ -246,3 +246,68 @@ xmbuf_verify_daddr(
return daddr < (xf->maxbytes >> BBSHIFT);
}
+
+/* Discard the page backing this buffer. */
+static void
+xmbuf_stale(
+ struct xfs_buf *bp)
+{
+ struct xfile *xf = bp->b_target->bt_xfile;
+ loff_t pos;
+
+ ASSERT(xfs_buftarg_is_mem(bp->b_target));
+
+ pos = BBTOB(xfs_buf_daddr(bp)) + xf->partition_pos;
+ fallocate(xf->fcb->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, pos,
+ BBTOB(bp->b_length));
+}
+
+/*
+ * Finalize a buffer -- discard the backing page if it's stale, or run the
+ * write verifier to detect problems.
+ */
+int
+xmbuf_finalize(
+ struct xfs_buf *bp)
+{
+ xfs_failaddr_t fa;
+ int error = 0;
+
+ if (bp->b_flags & LIBXFS_B_STALE) {
+ xmbuf_stale(bp);
+ return 0;
+ }
+
+ /*
+ * Although this btree is ephemeral, validate the buffer structure so
+ * that we can detect memory corruption errors and software bugs.
+ */
+ fa = bp->b_ops->verify_struct(bp);
+ if (fa) {
+ error = -EFSCORRUPTED;
+ xfs_verifier_error(bp, error, fa);
+ }
+
+ return error;
+}
+
+/*
+ * Detach this xmbuf buffer from the transaction by any means necessary.
+ * All buffers are direct-mapped, so they do not need bwrite.
+ */
+void
+xmbuf_trans_bdetach(
+ struct xfs_trans *tp,
+ struct xfs_buf *bp)
+{
+ struct xfs_buf_log_item *bli = bp->b_log_item;
+
+ ASSERT(bli != NULL);
+
+ bli->bli_flags &= ~(XFS_BLI_DIRTY | XFS_BLI_ORDERED |
+ XFS_BLI_STALE);
+ clear_bit(XFS_LI_DIRTY, &bli->bli_item.li_flags);
+
+ while (bp->b_log_item != NULL)
+ xfs_trans_bdetach(tp, bp);
+}
diff --git a/libxfs/buf_mem.h b/libxfs/buf_mem.h
index d40f9f9df..3829dd00d 100644
--- a/libxfs/buf_mem.h
+++ b/libxfs/buf_mem.h
@@ -24,5 +24,7 @@ int xmbuf_map_page(struct xfs_buf *bp);
void xmbuf_unmap_page(struct xfs_buf *bp);
bool xmbuf_verify_daddr(struct xfs_buftarg *btp, xfs_daddr_t daddr);
+void xmbuf_trans_bdetach(struct xfs_trans *tp, struct xfs_buf *bp);
+int xmbuf_finalize(struct xfs_buf *bp);
#endif /* __XFS_BUF_MEM_H__ */
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index fe8a0dc40..de37d3050 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -224,6 +224,7 @@
#define xfs_trans_alloc_empty libxfs_trans_alloc_empty
#define xfs_trans_alloc libxfs_trans_alloc
#define xfs_trans_alloc_inode libxfs_trans_alloc_inode
+#define xfs_trans_bdetach libxfs_trans_bdetach
#define xfs_trans_bhold libxfs_trans_bhold
#define xfs_trans_bhold_release libxfs_trans_bhold_release
#define xfs_trans_binval libxfs_trans_binval
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 8143a6a99..7fec2caff 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -614,6 +614,46 @@ libxfs_trans_brelse(
libxfs_buf_relse(bp);
}
+/*
+ * Forcibly detach a buffer previously joined to the transaction. The caller
+ * will retain its locked reference to the buffer after this function returns.
+ * The buffer must be completely clean and must not be held to the transaction.
+ */
+void
+libxfs_trans_bdetach(
+ struct xfs_trans *tp,
+ struct xfs_buf *bp)
+{
+ struct xfs_buf_log_item *bip = bp->b_log_item;
+
+ ASSERT(tp != NULL);
+ ASSERT(bp->b_transp == tp);
+ ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
+
+ trace_xfs_trans_bdetach(bip);
+
+ /*
+ * Erase all recursion count, since we're removing this buffer from the
+ * transaction.
+ */
+ bip->bli_recur = 0;
+
+ /*
+ * The buffer must be completely clean. Specifically, it had better
+ * not be dirty, stale, logged, ordered, or held to the transaction.
+ */
+ ASSERT(!test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
+ ASSERT(!(bip->bli_flags & XFS_BLI_DIRTY));
+ ASSERT(!(bip->bli_flags & XFS_BLI_HOLD));
+ ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
+ ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
+
+ /* Unlink the log item from the transaction and drop the log item. */
+ xfs_trans_del_item(&bip->bli_item);
+ xfs_buf_item_put(bip);
+ bp->b_transp = NULL;
+}
+
/*
* Mark the buffer as not needing to be unlocked when the buf item's
* iop_unlock() routine is called. The buffer must already be locked
diff --git a/libxfs/xfs_btree_mem.c b/libxfs/xfs_btree_mem.c
index 31835e065..ae9302b90 100644
--- a/libxfs/xfs_btree_mem.c
+++ b/libxfs/xfs_btree_mem.c
@@ -225,3 +225,122 @@ xfbtree_get_maxrecs(
return xfbt->maxrecs[level != 0];
}
+
+/* If this log item is a buffer item that came from the xfbtree, return it. */
+static inline struct xfs_buf *
+xfbtree_buf_match(
+ struct xfbtree *xfbt,
+ const struct xfs_log_item *lip)
+{
+ const struct xfs_buf_log_item *bli;
+ struct xfs_buf *bp;
+
+ if (lip->li_type != XFS_LI_BUF)
+ return NULL;
+
+ bli = container_of(lip, struct xfs_buf_log_item, bli_item);
+ bp = bli->bli_buf;
+ if (bp->b_target != xfbt->target)
+ return NULL;
+
+ return bp;
+}
+
+/*
+ * Commit changes to the incore btree immediately by writing all dirty xfbtree
+ * buffers to the backing xfile. This detaches all xfbtree buffers from the
+ * transaction, even on failure. The buffer locks are dropped between the
+ * delwri queue and submit, so the caller must synchronize btree access.
+ *
+ * Normally we'd let the buffers commit with the transaction and get written to
+ * the xfile via the log, but online repair stages ephemeral btrees in memory
+ * and uses the btree_staging functions to write new btrees to disk atomically.
+ * The in-memory btree (and its backing store) are discarded at the end of the
+ * repair phase, which means that xfbtree buffers cannot commit with the rest
+ * of a transaction.
+ *
+ * In other words, online repair only needs the transaction to collect buffer
+ * pointers and to avoid buffer deadlocks, not to guarantee consistency of
+ * updates.
+ */
+int
+xfbtree_trans_commit(
+ struct xfbtree *xfbt,
+ struct xfs_trans *tp)
+{
+ struct xfs_log_item *lip, *n;
+ bool tp_dirty = false;
+ int error = 0;
+
+ /*
+ * For each xfbtree buffer attached to the transaction, write the dirty
+ * buffers to the xfile and release them.
+ */
+ list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
+ struct xfs_buf *bp = xfbtree_buf_match(xfbt, lip);
+
+ if (!bp) {
+ if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
+ tp_dirty |= true;
+ continue;
+ }
+
+ trace_xfbtree_trans_commit_buf(xfbt, bp);
+
+ xmbuf_trans_bdetach(tp, bp);
+
+ /*
+ * If the buffer fails verification, note the failure but
+ * continue walking the transaction items so that we remove all
+ * ephemeral btree buffers.
+ */
+ if (!error)
+ error = xmbuf_finalize(bp);
+
+ xfs_buf_relse(bp);
+ }
+
+ /*
+ * Reset the transaction's dirty flag to reflect the dirty state of the
+ * log items that are still attached.
+ */
+ tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
+ (tp_dirty ? XFS_TRANS_DIRTY : 0);
+
+ return error;
+}
+
+/*
+ * Cancel changes to the incore btree by detaching all the xfbtree buffers.
+ * Changes are not undone, so callers must not access the btree ever again.
+ */
+void
+xfbtree_trans_cancel(
+ struct xfbtree *xfbt,
+ struct xfs_trans *tp)
+{
+ struct xfs_log_item *lip, *n;
+ bool tp_dirty = false;
+
+ list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
+ struct xfs_buf *bp = xfbtree_buf_match(xfbt, lip);
+
+ if (!bp) {
+ if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
+ tp_dirty |= true;
+ continue;
+ }
+
+ trace_xfbtree_trans_cancel_buf(xfbt, bp);
+
+ xmbuf_trans_bdetach(tp, bp);
+ xfs_buf_relse(bp);
+ }
+
+ /*
+ * Reset the transaction's dirty flag to reflect the dirty state of the
+ * log items that are still attached.
+ */
+ tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
+ (tp_dirty ? XFS_TRANS_DIRTY : 0);
+}
diff --git a/libxfs/xfs_btree_mem.h b/libxfs/xfs_btree_mem.h
index ecc2ceac3..1c3825786 100644
--- a/libxfs/xfs_btree_mem.h
+++ b/libxfs/xfs_btree_mem.h
@@ -65,6 +65,9 @@ int xfbtree_free_block(struct xfs_btree_cur *cur, struct xfs_buf *bp);
int xfbtree_init(struct xfs_mount *mp, struct xfbtree *xfbt,
struct xfs_buftarg *btp, const struct xfs_btree_ops *ops);
void xfbtree_destroy(struct xfbtree *xfbt);
+
+int xfbtree_trans_commit(struct xfbtree *xfbt, struct xfs_trans *tp);
+void xfbtree_trans_cancel(struct xfbtree *xfbt, struct xfs_trans *tp);
#else
# define xfbtree_verify_bno(...) (false)
#endif /* CONFIG_XFS_BTREE_IN_MEM */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 096/111] xfs: create a helper to decide if a file mapping targets the rt volume
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (94 preceding siblings ...)
2024-05-22 3:13 ` [PATCH 095/111] xfs: launder in-memory btree buffers before transaction commit Darrick J. Wong
@ 2024-05-22 3:13 ` Darrick J. Wong
2024-05-22 3:14 ` [PATCH 097/111] xfs: repair the rmapbt Darrick J. Wong
` (15 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:13 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 5049ff4d140c8f6545464811409302cab017321a
Create a helper so that we can stop open-coding this decision
everywhere.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap.c | 6 +++---
libxfs/xfs_inode_fork.c | 9 +++++++++
libxfs/xfs_inode_fork.h | 1 +
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 4790efd3d..85f1deac2 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -4907,7 +4907,7 @@ xfs_bmap_del_extent_delay(
XFS_STATS_INC(mp, xs_del_exlist);
- isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
+ isrt = xfs_ifork_is_realtime(ip, whichfork);
del_endoff = del->br_startoff + del->br_blockcount;
got_endoff = got->br_startoff + got->br_blockcount;
da_old = startblockval(got->br_startblock);
@@ -5143,7 +5143,7 @@ xfs_bmap_del_extent_real(
return -ENOSPC;
*logflagsp = XFS_ILOG_CORE;
- if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
+ if (xfs_ifork_is_realtime(ip, whichfork)) {
if (!(bflags & XFS_BMAPI_REMAP)) {
error = xfs_rtfree_blocks(tp, del->br_startblock,
del->br_blockcount);
@@ -5390,7 +5390,7 @@ __xfs_bunmapi(
return 0;
}
XFS_STATS_INC(mp, xs_blk_unmap);
- isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
+ isrt = xfs_ifork_is_realtime(ip, whichfork);
end = start + len;
if (!xfs_iext_lookup_extent_before(ip, ifp, &end, &icur, &got)) {
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 53ff82678..052748814 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -811,3 +811,12 @@ xfs_iext_count_upgrade(
return 0;
}
+
+/* Decide if a file mapping is on the realtime device or not. */
+bool
+xfs_ifork_is_realtime(
+ struct xfs_inode *ip,
+ int whichfork)
+{
+ return XFS_IS_REALTIME_INODE(ip) && whichfork != XFS_ATTR_FORK;
+}
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index 96303249d..bd53eb951 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -260,6 +260,7 @@ int xfs_iext_count_may_overflow(struct xfs_inode *ip, int whichfork,
int nr_to_add);
int xfs_iext_count_upgrade(struct xfs_trans *tp, struct xfs_inode *ip,
uint nr_to_add);
+bool xfs_ifork_is_realtime(struct xfs_inode *ip, int whichfork);
/* returns true if the fork has extents but they are not read in yet. */
static inline bool xfs_need_iread_extents(const struct xfs_ifork *ifp)
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 097/111] xfs: repair the rmapbt
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (95 preceding siblings ...)
2024-05-22 3:13 ` [PATCH 096/111] xfs: create a helper to decide if a file mapping targets the rt volume Darrick J. Wong
@ 2024-05-22 3:14 ` Darrick J. Wong
2024-05-22 3:14 ` [PATCH 098/111] xfs: create a shadow rmap btree during rmap repair Darrick J. Wong
` (14 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:14 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 32080a9b9b2ef8f4089e8e28a2c307334431757e
Rebuild the reverse mapping btree from all primary metadata. This first
patch establishes the bare mechanics of finding records and putting
together a new ondisk tree; more complex pieces are needed to make it
work properly.
Link: Documentation/filesystems/xfs-online-fsck-design.rst
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_ag.h | 1 +
libxfs/xfs_bmap.c | 43 +++++++++++++++++++++++++++++++++++++++++++
libxfs/xfs_bmap.h | 8 ++++++++
libxfs/xfs_rmap.c | 12 ++++++------
libxfs/xfs_rmap.h | 2 +-
libxfs/xfs_rmap_btree.c | 13 ++++++++++++-
6 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h
index 29bfa6273..e019b79db 100644
--- a/libxfs/xfs_ag.h
+++ b/libxfs/xfs_ag.h
@@ -90,6 +90,7 @@ struct xfs_perag {
uint8_t pagf_repair_bno_level;
uint8_t pagf_repair_cnt_level;
uint8_t pagf_repair_refcount_level;
+ uint8_t pagf_repair_rmap_level;
#endif
spinlock_t pag_state_lock;
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 85f1deac2..a82a41249 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -6373,3 +6373,46 @@ xfs_bunmapi_range(
out:
return error;
}
+
+struct xfs_bmap_query_range {
+ xfs_bmap_query_range_fn fn;
+ void *priv;
+};
+
+/* Format btree record and pass to our callback. */
+STATIC int
+xfs_bmap_query_range_helper(
+ struct xfs_btree_cur *cur,
+ const union xfs_btree_rec *rec,
+ void *priv)
+{
+ struct xfs_bmap_query_range *query = priv;
+ struct xfs_bmbt_irec irec;
+ xfs_failaddr_t fa;
+
+ xfs_bmbt_disk_get_all(&rec->bmbt, &irec);
+ fa = xfs_bmap_validate_extent(cur->bc_ino.ip, cur->bc_ino.whichfork,
+ &irec);
+ if (fa) {
+ xfs_btree_mark_sick(cur);
+ return xfs_bmap_complain_bad_rec(cur->bc_ino.ip,
+ cur->bc_ino.whichfork, fa, &irec);
+ }
+
+ return query->fn(cur, &irec, query->priv);
+}
+
+/* Find all bmaps. */
+int
+xfs_bmap_query_all(
+ struct xfs_btree_cur *cur,
+ xfs_bmap_query_range_fn fn,
+ void *priv)
+{
+ struct xfs_bmap_query_range query = {
+ .priv = priv,
+ .fn = fn,
+ };
+
+ return xfs_btree_query_all(cur, xfs_bmap_query_range_helper, &query);
+}
diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h
index f6b73f1ba..10b858652 100644
--- a/libxfs/xfs_bmap.h
+++ b/libxfs/xfs_bmap.h
@@ -280,4 +280,12 @@ extern struct kmem_cache *xfs_bmap_intent_cache;
int __init xfs_bmap_intent_init_cache(void);
void xfs_bmap_intent_destroy_cache(void);
+typedef int (*xfs_bmap_query_range_fn)(
+ struct xfs_btree_cur *cur,
+ struct xfs_bmbt_irec *rec,
+ void *priv);
+
+int xfs_bmap_query_all(struct xfs_btree_cur *cur, xfs_bmap_query_range_fn fn,
+ void *priv);
+
#endif /* __XFS_BMAP_H__ */
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index 2d96cb60c..a0b4280fe 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -214,10 +214,10 @@ xfs_rmap_btrec_to_irec(
/* Simple checks for rmap records. */
xfs_failaddr_t
xfs_rmap_check_irec(
- struct xfs_btree_cur *cur,
+ struct xfs_perag *pag,
const struct xfs_rmap_irec *irec)
{
- struct xfs_mount *mp = cur->bc_mp;
+ struct xfs_mount *mp = pag->pag_mount;
bool is_inode;
bool is_unwritten;
bool is_bmbt;
@@ -232,8 +232,8 @@ xfs_rmap_check_irec(
return __this_address;
} else {
/* check for valid extent range, including overflow */
- if (!xfs_verify_agbext(cur->bc_ag.pag, irec->rm_startblock,
- irec->rm_blockcount))
+ if (!xfs_verify_agbext(pag, irec->rm_startblock,
+ irec->rm_blockcount))
return __this_address;
}
@@ -306,7 +306,7 @@ xfs_rmap_get_rec(
fa = xfs_rmap_btrec_to_irec(rec, irec);
if (!fa)
- fa = xfs_rmap_check_irec(cur, irec);
+ fa = xfs_rmap_check_irec(cur->bc_ag.pag, irec);
if (fa)
return xfs_rmap_complain_bad_rec(cur, fa, irec);
@@ -2441,7 +2441,7 @@ xfs_rmap_query_range_helper(
fa = xfs_rmap_btrec_to_irec(rec, &irec);
if (!fa)
- fa = xfs_rmap_check_irec(cur, &irec);
+ fa = xfs_rmap_check_irec(cur->bc_ag.pag, &irec);
if (fa)
return xfs_rmap_complain_bad_rec(cur, fa, &irec);
diff --git a/libxfs/xfs_rmap.h b/libxfs/xfs_rmap.h
index 3c98d9d50..58c67896d 100644
--- a/libxfs/xfs_rmap.h
+++ b/libxfs/xfs_rmap.h
@@ -195,7 +195,7 @@ int xfs_rmap_compare(const struct xfs_rmap_irec *a,
union xfs_btree_rec;
xfs_failaddr_t xfs_rmap_btrec_to_irec(const union xfs_btree_rec *rec,
struct xfs_rmap_irec *irec);
-xfs_failaddr_t xfs_rmap_check_irec(struct xfs_btree_cur *cur,
+xfs_failaddr_t xfs_rmap_check_irec(struct xfs_perag *pag,
const struct xfs_rmap_irec *irec);
int xfs_rmap_has_records(struct xfs_btree_cur *cur, xfs_agblock_t bno,
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 2b7504f7a..956cdc2fd 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -340,7 +340,18 @@ xfs_rmapbt_verify(
level = be16_to_cpu(block->bb_level);
if (pag && xfs_perag_initialised_agf(pag)) {
- if (level >= pag->pagf_rmap_level)
+ unsigned int maxlevel = pag->pagf_rmap_level;
+
+#ifdef CONFIG_XFS_ONLINE_REPAIR
+ /*
+ * Online repair could be rewriting the free space btrees, so
+ * we'll validate against the larger of either tree while this
+ * is going on.
+ */
+ maxlevel = max_t(unsigned int, maxlevel,
+ pag->pagf_repair_rmap_level);
+#endif
+ if (level >= maxlevel)
return __this_address;
} else if (level >= mp->m_rmap_maxlevels)
return __this_address;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 098/111] xfs: create a shadow rmap btree during rmap repair
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (96 preceding siblings ...)
2024-05-22 3:14 ` [PATCH 097/111] xfs: repair the rmapbt Darrick J. Wong
@ 2024-05-22 3:14 ` Darrick J. Wong
2024-05-22 3:14 ` [PATCH 099/111] xfs: hook live rmap operations during a repair operation Darrick J. Wong
` (13 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:14 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 4787fc802752c9b73b28ff18860c0560bf4337f2
Create an in-memory btree of rmap records instead of an array. This
enables us to do live record collection instead of freezing the fs.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_rmap.c | 37 +++++++-----
libxfs/xfs_rmap_btree.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++
libxfs/xfs_rmap_btree.h | 6 ++
libxfs/xfs_shared.h | 10 +++
4 files changed, 190 insertions(+), 14 deletions(-)
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index a0b4280fe..a7be2aa92 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -268,6 +268,16 @@ xfs_rmap_check_irec(
return NULL;
}
+static inline xfs_failaddr_t
+xfs_rmap_check_btrec(
+ struct xfs_btree_cur *cur,
+ const struct xfs_rmap_irec *irec)
+{
+ if (xfs_btree_is_mem_rmap(cur->bc_ops))
+ return xfs_rmap_check_irec(cur->bc_mem.pag, irec);
+ return xfs_rmap_check_irec(cur->bc_ag.pag, irec);
+}
+
static inline int
xfs_rmap_complain_bad_rec(
struct xfs_btree_cur *cur,
@@ -276,9 +286,13 @@ xfs_rmap_complain_bad_rec(
{
struct xfs_mount *mp = cur->bc_mp;
- xfs_warn(mp,
- "Reverse Mapping BTree record corruption in AG %d detected at %pS!",
- cur->bc_ag.pag->pag_agno, fa);
+ if (xfs_btree_is_mem_rmap(cur->bc_ops))
+ xfs_warn(mp,
+ "In-Memory Reverse Mapping BTree record corruption detected at %pS!", fa);
+ else
+ xfs_warn(mp,
+ "Reverse Mapping BTree record corruption in AG %d detected at %pS!",
+ cur->bc_ag.pag->pag_agno, fa);
xfs_warn(mp,
"Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
irec->rm_owner, irec->rm_flags, irec->rm_startblock,
@@ -306,7 +320,7 @@ xfs_rmap_get_rec(
fa = xfs_rmap_btrec_to_irec(rec, irec);
if (!fa)
- fa = xfs_rmap_check_irec(cur->bc_ag.pag, irec);
+ fa = xfs_rmap_check_btrec(cur, irec);
if (fa)
return xfs_rmap_complain_bad_rec(cur, fa, irec);
@@ -2403,15 +2417,12 @@ xfs_rmap_map_raw(
{
struct xfs_owner_info oinfo;
- oinfo.oi_owner = rmap->rm_owner;
- oinfo.oi_offset = rmap->rm_offset;
- oinfo.oi_flags = 0;
- if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
- oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
- if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
- oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
+ xfs_owner_info_pack(&oinfo, rmap->rm_owner, rmap->rm_offset,
+ rmap->rm_flags);
- if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
+ if ((rmap->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK |
+ XFS_RMAP_UNWRITTEN)) ||
+ XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
return xfs_rmap_map(cur, rmap->rm_startblock,
rmap->rm_blockcount,
rmap->rm_flags & XFS_RMAP_UNWRITTEN,
@@ -2441,7 +2452,7 @@ xfs_rmap_query_range_helper(
fa = xfs_rmap_btrec_to_irec(rec, &irec);
if (!fa)
- fa = xfs_rmap_check_irec(cur->bc_ag.pag, &irec);
+ fa = xfs_rmap_check_btrec(cur, &irec);
if (fa)
return xfs_rmap_complain_bad_rec(cur, fa, &irec);
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index 956cdc2fd..a2730e29c 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -20,6 +20,9 @@
#include "xfs_ag.h"
#include "xfs_ag_resv.h"
#include "xfs_health.h"
+#include "xfile.h"
+#include "buf_mem.h"
+#include "xfs_btree_mem.h"
static struct kmem_cache *xfs_rmapbt_cur_cache;
@@ -539,6 +542,151 @@ xfs_rmapbt_init_cursor(
return cur;
}
+#ifdef CONFIG_XFS_BTREE_IN_MEM
+static inline unsigned int
+xfs_rmapbt_mem_block_maxrecs(
+ unsigned int blocklen,
+ bool leaf)
+{
+ if (leaf)
+ return blocklen / sizeof(struct xfs_rmap_rec);
+ return blocklen /
+ (2 * sizeof(struct xfs_rmap_key) + sizeof(__be64));
+}
+
+/*
+ * Validate an in-memory rmap btree block. Callers are allowed to generate an
+ * in-memory btree even if the ondisk feature is not enabled.
+ */
+static xfs_failaddr_t
+xfs_rmapbt_mem_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
+ xfs_failaddr_t fa;
+ unsigned int level;
+ unsigned int maxrecs;
+
+ if (!xfs_verify_magic(bp, block->bb_magic))
+ return __this_address;
+
+ fa = xfs_btree_fsblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN);
+ if (fa)
+ return fa;
+
+ level = be16_to_cpu(block->bb_level);
+ if (level >= xfs_rmapbt_maxlevels_ondisk())
+ return __this_address;
+
+ maxrecs = xfs_rmapbt_mem_block_maxrecs(
+ XFBNO_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN, level == 0);
+ return xfs_btree_memblock_verify(bp, maxrecs);
+}
+
+static void
+xfs_rmapbt_mem_rw_verify(
+ struct xfs_buf *bp)
+{
+ xfs_failaddr_t fa = xfs_rmapbt_mem_verify(bp);
+
+ if (fa)
+ xfs_verifier_error(bp, -EFSCORRUPTED, fa);
+}
+
+/* skip crc checks on in-memory btrees to save time */
+static const struct xfs_buf_ops xfs_rmapbt_mem_buf_ops = {
+ .name = "xfs_rmapbt_mem",
+ .magic = { 0, cpu_to_be32(XFS_RMAP_CRC_MAGIC) },
+ .verify_read = xfs_rmapbt_mem_rw_verify,
+ .verify_write = xfs_rmapbt_mem_rw_verify,
+ .verify_struct = xfs_rmapbt_mem_verify,
+};
+
+const struct xfs_btree_ops xfs_rmapbt_mem_ops = {
+ .name = "mem_rmap",
+ .type = XFS_BTREE_TYPE_MEM,
+ .geom_flags = XFS_BTGEO_OVERLAPPING,
+
+ .rec_len = sizeof(struct xfs_rmap_rec),
+ /* Overlapping btree; 2 keys per pointer. */
+ .key_len = 2 * sizeof(struct xfs_rmap_key),
+ .ptr_len = XFS_BTREE_LONG_PTR_LEN,
+
+ .lru_refs = XFS_RMAP_BTREE_REF,
+ .statoff = XFS_STATS_CALC_INDEX(xs_rmap_mem_2),
+
+ .dup_cursor = xfbtree_dup_cursor,
+ .set_root = xfbtree_set_root,
+ .alloc_block = xfbtree_alloc_block,
+ .free_block = xfbtree_free_block,
+ .get_minrecs = xfbtree_get_minrecs,
+ .get_maxrecs = xfbtree_get_maxrecs,
+ .init_key_from_rec = xfs_rmapbt_init_key_from_rec,
+ .init_high_key_from_rec = xfs_rmapbt_init_high_key_from_rec,
+ .init_rec_from_cur = xfs_rmapbt_init_rec_from_cur,
+ .init_ptr_from_cur = xfbtree_init_ptr_from_cur,
+ .key_diff = xfs_rmapbt_key_diff,
+ .buf_ops = &xfs_rmapbt_mem_buf_ops,
+ .diff_two_keys = xfs_rmapbt_diff_two_keys,
+ .keys_inorder = xfs_rmapbt_keys_inorder,
+ .recs_inorder = xfs_rmapbt_recs_inorder,
+ .keys_contiguous = xfs_rmapbt_keys_contiguous,
+};
+
+/* Create a cursor for an in-memory btree. */
+struct xfs_btree_cur *
+xfs_rmapbt_mem_cursor(
+ struct xfs_perag *pag,
+ struct xfs_trans *tp,
+ struct xfbtree *xfbt)
+{
+ struct xfs_btree_cur *cur;
+ struct xfs_mount *mp = pag->pag_mount;
+
+ cur = xfs_btree_alloc_cursor(mp, tp, &xfs_rmapbt_mem_ops,
+ xfs_rmapbt_maxlevels_ondisk(), xfs_rmapbt_cur_cache);
+ cur->bc_mem.xfbtree = xfbt;
+ cur->bc_nlevels = xfbt->nlevels;
+
+ cur->bc_mem.pag = xfs_perag_hold(pag);
+ return cur;
+}
+
+/* Create an in-memory rmap btree. */
+int
+xfs_rmapbt_mem_init(
+ struct xfs_mount *mp,
+ struct xfbtree *xfbt,
+ struct xfs_buftarg *btp,
+ xfs_agnumber_t agno)
+{
+ xfbt->owner = agno;
+ return xfbtree_init(mp, xfbt, btp, &xfs_rmapbt_mem_ops);
+}
+
+/* Compute the max possible height for reverse mapping btrees in memory. */
+static unsigned int
+xfs_rmapbt_mem_maxlevels(void)
+{
+ unsigned int minrecs[2];
+ unsigned int blocklen;
+
+ blocklen = XFBNO_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN;
+
+ minrecs[0] = xfs_rmapbt_mem_block_maxrecs(blocklen, true) / 2;
+ minrecs[1] = xfs_rmapbt_mem_block_maxrecs(blocklen, false) / 2;
+
+ /*
+ * How tall can an in-memory rmap btree become if we filled the entire
+ * AG with rmap records?
+ */
+ return xfs_btree_compute_maxlevels(minrecs,
+ XFS_MAX_AG_BYTES / sizeof(struct xfs_rmap_rec));
+}
+#else
+# define xfs_rmapbt_mem_maxlevels() (0)
+#endif /* CONFIG_XFS_BTREE_IN_MEM */
+
/*
* Install a new reverse mapping btree root. Caller is responsible for
* invalidating and freeing the old btree blocks.
@@ -609,7 +757,8 @@ xfs_rmapbt_maxlevels_ondisk(void)
* like if it consumes almost all the blocks in the AG due to maximal
* sharing factor.
*/
- return xfs_btree_space_to_height(minrecs, XFS_MAX_CRC_AG_BLOCKS);
+ return max(xfs_btree_space_to_height(minrecs, XFS_MAX_CRC_AG_BLOCKS),
+ xfs_rmapbt_mem_maxlevels());
}
/* Compute the maximum height of an rmap btree. */
diff --git a/libxfs/xfs_rmap_btree.h b/libxfs/xfs_rmap_btree.h
index 27536d7e1..eb90d89e8 100644
--- a/libxfs/xfs_rmap_btree.h
+++ b/libxfs/xfs_rmap_btree.h
@@ -10,6 +10,7 @@ struct xfs_buf;
struct xfs_btree_cur;
struct xfs_mount;
struct xbtree_afakeroot;
+struct xfbtree;
/* rmaps only exist on crc enabled filesystems */
#define XFS_RMAP_BLOCK_LEN XFS_BTREE_SBLOCK_CRC_LEN
@@ -62,4 +63,9 @@ unsigned int xfs_rmapbt_maxlevels_ondisk(void);
int __init xfs_rmapbt_init_cur_cache(void);
void xfs_rmapbt_destroy_cur_cache(void);
+struct xfs_btree_cur *xfs_rmapbt_mem_cursor(struct xfs_perag *pag,
+ struct xfs_trans *tp, struct xfbtree *xfbtree);
+int xfs_rmapbt_mem_init(struct xfs_mount *mp, struct xfbtree *xfbtree,
+ struct xfs_buftarg *btp, xfs_agnumber_t agno);
+
#endif /* __XFS_RMAP_BTREE_H__ */
diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h
index 6b8bc276d..cab49e711 100644
--- a/libxfs/xfs_shared.h
+++ b/libxfs/xfs_shared.h
@@ -51,6 +51,7 @@ extern const struct xfs_btree_ops xfs_finobt_ops;
extern const struct xfs_btree_ops xfs_bmbt_ops;
extern const struct xfs_btree_ops xfs_refcountbt_ops;
extern const struct xfs_btree_ops xfs_rmapbt_ops;
+extern const struct xfs_btree_ops xfs_rmapbt_mem_ops;
static inline bool xfs_btree_is_bno(const struct xfs_btree_ops *ops)
{
@@ -87,6 +88,15 @@ static inline bool xfs_btree_is_rmap(const struct xfs_btree_ops *ops)
return ops == &xfs_rmapbt_ops;
}
+#ifdef CONFIG_XFS_BTREE_IN_MEM
+static inline bool xfs_btree_is_mem_rmap(const struct xfs_btree_ops *ops)
+{
+ return ops == &xfs_rmapbt_mem_ops;
+}
+#else
+# define xfs_btree_is_mem_rmap(...) (false)
+#endif
+
/* log size calculation functions */
int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes);
int xfs_log_calc_minimum_size(struct xfs_mount *);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 099/111] xfs: hook live rmap operations during a repair operation
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (97 preceding siblings ...)
2024-05-22 3:14 ` [PATCH 098/111] xfs: create a shadow rmap btree during rmap repair Darrick J. Wong
@ 2024-05-22 3:14 ` Darrick J. Wong
2024-05-22 3:14 ` [PATCH 100/111] xfs: clean up bmap log intent item tracepoint callsites Darrick J. Wong
` (12 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:14 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 7e1b84b24d257700e417bc9cd724c1efdff653d7
Hook the regular rmap code when an rmapbt repair operation is running so
that we can unlock the AGF buffer to scan the filesystem and keep the
in-memory btree up to date during the scan.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_ag.c | 1
libxfs/xfs_ag.h | 3 +
libxfs/xfs_rmap.c | 154 ++++++++++++++++++++++++++++++++++++++++++-----------
libxfs/xfs_rmap.h | 29 ++++++++++
4 files changed, 154 insertions(+), 33 deletions(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 06a881285..e2fc3e882 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -415,6 +415,7 @@ xfs_initialize_perag(
init_waitqueue_head(&pag->pag_active_wq);
pag->pagb_count = 0;
pag->pagb_tree = RB_ROOT;
+ xfs_hooks_init(&pag->pag_rmap_update_hooks);
#endif /* __KERNEL__ */
error = xfs_buf_cache_init(&pag->pag_bcache);
diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h
index e019b79db..35de09a25 100644
--- a/libxfs/xfs_ag.h
+++ b/libxfs/xfs_ag.h
@@ -120,6 +120,9 @@ struct xfs_perag {
* inconsistencies.
*/
struct xfs_defer_drain pag_intents_drain;
+
+ /* Hook to feed rmapbt updates to an active online repair. */
+ struct xfs_hooks pag_rmap_update_hooks;
#endif /* __KERNEL__ */
};
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index a7be2aa92..c3195e532 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -820,6 +820,86 @@ xfs_rmap_unmap(
return error;
}
+#ifdef CONFIG_XFS_LIVE_HOOKS
+/*
+ * Use a static key here to reduce the overhead of rmapbt live updates. If
+ * the compiler supports jump labels, the static branch will be replaced by a
+ * nop sled when there are no hook users. Online fsck is currently the only
+ * caller, so this is a reasonable tradeoff.
+ *
+ * Note: Patching the kernel code requires taking the cpu hotplug lock. Other
+ * parts of the kernel allocate memory with that lock held, which means that
+ * XFS callers cannot hold any locks that might be used by memory reclaim or
+ * writeback when calling the static_branch_{inc,dec} functions.
+ */
+DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_rmap_hooks_switch);
+
+void
+xfs_rmap_hook_disable(void)
+{
+ xfs_hooks_switch_off(&xfs_rmap_hooks_switch);
+}
+
+void
+xfs_rmap_hook_enable(void)
+{
+ xfs_hooks_switch_on(&xfs_rmap_hooks_switch);
+}
+
+/* Call downstream hooks for a reverse mapping update. */
+static inline void
+xfs_rmap_update_hook(
+ struct xfs_trans *tp,
+ struct xfs_perag *pag,
+ enum xfs_rmap_intent_type op,
+ xfs_agblock_t startblock,
+ xfs_extlen_t blockcount,
+ bool unwritten,
+ const struct xfs_owner_info *oinfo)
+{
+ if (xfs_hooks_switched_on(&xfs_rmap_hooks_switch)) {
+ struct xfs_rmap_update_params p = {
+ .startblock = startblock,
+ .blockcount = blockcount,
+ .unwritten = unwritten,
+ .oinfo = *oinfo, /* struct copy */
+ };
+
+ if (pag)
+ xfs_hooks_call(&pag->pag_rmap_update_hooks, op, &p);
+ }
+}
+
+/* Call the specified function during a reverse mapping update. */
+int
+xfs_rmap_hook_add(
+ struct xfs_perag *pag,
+ struct xfs_rmap_hook *hook)
+{
+ return xfs_hooks_add(&pag->pag_rmap_update_hooks, &hook->rmap_hook);
+}
+
+/* Stop calling the specified function during a reverse mapping update. */
+void
+xfs_rmap_hook_del(
+ struct xfs_perag *pag,
+ struct xfs_rmap_hook *hook)
+{
+ xfs_hooks_del(&pag->pag_rmap_update_hooks, &hook->rmap_hook);
+}
+
+/* Configure rmap update hook functions. */
+void
+xfs_rmap_hook_setup(
+ struct xfs_rmap_hook *hook,
+ notifier_fn_t mod_fn)
+{
+ xfs_hook_setup(&hook->rmap_hook, mod_fn);
+}
+#else
+# define xfs_rmap_update_hook(t, p, o, s, b, u, oi) do { } while (0)
+#endif /* CONFIG_XFS_LIVE_HOOKS */
+
/*
* Remove a reference to an extent in the rmap btree.
*/
@@ -840,7 +920,7 @@ xfs_rmap_free(
return 0;
cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
-
+ xfs_rmap_update_hook(tp, pag, XFS_RMAP_UNMAP, bno, len, false, oinfo);
error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
xfs_btree_del_cursor(cur, error);
@@ -1092,6 +1172,7 @@ xfs_rmap_alloc(
return 0;
cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
+ xfs_rmap_update_hook(tp, pag, XFS_RMAP_MAP, bno, len, false, oinfo);
error = xfs_rmap_map(cur, bno, len, false, oinfo);
xfs_btree_del_cursor(cur, error);
@@ -2507,6 +2588,38 @@ xfs_rmap_finish_one_cleanup(
xfs_trans_brelse(tp, agbp);
}
+/* Commit an rmap operation into the ondisk tree. */
+int
+__xfs_rmap_finish_intent(
+ struct xfs_btree_cur *rcur,
+ enum xfs_rmap_intent_type op,
+ xfs_agblock_t bno,
+ xfs_extlen_t len,
+ const struct xfs_owner_info *oinfo,
+ bool unwritten)
+{
+ switch (op) {
+ case XFS_RMAP_ALLOC:
+ case XFS_RMAP_MAP:
+ return xfs_rmap_map(rcur, bno, len, unwritten, oinfo);
+ case XFS_RMAP_MAP_SHARED:
+ return xfs_rmap_map_shared(rcur, bno, len, unwritten, oinfo);
+ case XFS_RMAP_FREE:
+ case XFS_RMAP_UNMAP:
+ return xfs_rmap_unmap(rcur, bno, len, unwritten, oinfo);
+ case XFS_RMAP_UNMAP_SHARED:
+ return xfs_rmap_unmap_shared(rcur, bno, len, unwritten, oinfo);
+ case XFS_RMAP_CONVERT:
+ return xfs_rmap_convert(rcur, bno, len, !unwritten, oinfo);
+ case XFS_RMAP_CONVERT_SHARED:
+ return xfs_rmap_convert_shared(rcur, bno, len, !unwritten,
+ oinfo);
+ default:
+ ASSERT(0);
+ return -EFSCORRUPTED;
+ }
+}
+
/*
* Process one of the deferred rmap operations. We pass back the
* btree cursor to maintain our lock on the rmapbt between calls.
@@ -2573,39 +2686,14 @@ xfs_rmap_finish_one(
unwritten = ri->ri_bmap.br_state == XFS_EXT_UNWRITTEN;
bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, ri->ri_bmap.br_startblock);
- switch (ri->ri_type) {
- case XFS_RMAP_ALLOC:
- case XFS_RMAP_MAP:
- error = xfs_rmap_map(rcur, bno, ri->ri_bmap.br_blockcount,
- unwritten, &oinfo);
- break;
- case XFS_RMAP_MAP_SHARED:
- error = xfs_rmap_map_shared(rcur, bno,
- ri->ri_bmap.br_blockcount, unwritten, &oinfo);
- break;
- case XFS_RMAP_FREE:
- case XFS_RMAP_UNMAP:
- error = xfs_rmap_unmap(rcur, bno, ri->ri_bmap.br_blockcount,
- unwritten, &oinfo);
- break;
- case XFS_RMAP_UNMAP_SHARED:
- error = xfs_rmap_unmap_shared(rcur, bno,
- ri->ri_bmap.br_blockcount, unwritten, &oinfo);
- break;
- case XFS_RMAP_CONVERT:
- error = xfs_rmap_convert(rcur, bno, ri->ri_bmap.br_blockcount,
- !unwritten, &oinfo);
- break;
- case XFS_RMAP_CONVERT_SHARED:
- error = xfs_rmap_convert_shared(rcur, bno,
- ri->ri_bmap.br_blockcount, !unwritten, &oinfo);
- break;
- default:
- ASSERT(0);
- error = -EFSCORRUPTED;
- }
+ error = __xfs_rmap_finish_intent(rcur, ri->ri_type, bno,
+ ri->ri_bmap.br_blockcount, &oinfo, unwritten);
+ if (error)
+ return error;
- return error;
+ xfs_rmap_update_hook(tp, ri->ri_pag, ri->ri_type, bno,
+ ri->ri_bmap.br_blockcount, unwritten, &oinfo);
+ return 0;
}
/*
diff --git a/libxfs/xfs_rmap.h b/libxfs/xfs_rmap.h
index 58c67896d..9d01fe689 100644
--- a/libxfs/xfs_rmap.h
+++ b/libxfs/xfs_rmap.h
@@ -186,6 +186,10 @@ void xfs_rmap_finish_one_cleanup(struct xfs_trans *tp,
struct xfs_btree_cur *rcur, int error);
int xfs_rmap_finish_one(struct xfs_trans *tp, struct xfs_rmap_intent *ri,
struct xfs_btree_cur **pcur);
+int __xfs_rmap_finish_intent(struct xfs_btree_cur *rcur,
+ enum xfs_rmap_intent_type op, xfs_agblock_t bno,
+ xfs_extlen_t len, const struct xfs_owner_info *oinfo,
+ bool unwritten);
int xfs_rmap_lookup_le_range(struct xfs_btree_cur *cur, xfs_agblock_t bno,
uint64_t owner, uint64_t offset, unsigned int flags,
@@ -235,4 +239,29 @@ extern struct kmem_cache *xfs_rmap_intent_cache;
int __init xfs_rmap_intent_init_cache(void);
void xfs_rmap_intent_destroy_cache(void);
+/*
+ * Parameters for tracking reverse mapping changes. The hook function arg
+ * parameter is enum xfs_rmap_intent_type, and the rest is below.
+ */
+struct xfs_rmap_update_params {
+ xfs_agblock_t startblock;
+ xfs_extlen_t blockcount;
+ struct xfs_owner_info oinfo;
+ bool unwritten;
+};
+
+#ifdef CONFIG_XFS_LIVE_HOOKS
+
+struct xfs_rmap_hook {
+ struct xfs_hook rmap_hook;
+};
+
+void xfs_rmap_hook_disable(void);
+void xfs_rmap_hook_enable(void);
+
+int xfs_rmap_hook_add(struct xfs_perag *pag, struct xfs_rmap_hook *hook);
+void xfs_rmap_hook_del(struct xfs_perag *pag, struct xfs_rmap_hook *hook);
+void xfs_rmap_hook_setup(struct xfs_rmap_hook *hook, notifier_fn_t mod_fn);
+#endif
+
#endif /* __XFS_RMAP_H__ */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 100/111] xfs: clean up bmap log intent item tracepoint callsites
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (98 preceding siblings ...)
2024-05-22 3:14 ` [PATCH 099/111] xfs: hook live rmap operations during a repair operation Darrick J. Wong
@ 2024-05-22 3:14 ` Darrick J. Wong
2024-05-22 3:15 ` [PATCH 101/111] xfs: move xfs_bmap_defer_add to xfs_bmap_item.c Darrick J. Wong
` (11 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:14 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 2a15e7686094d1362b5026533b96f57ec989a245
Pass the incore bmap structure to the tracepoints instead of open-coding
the argument passing.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap.c | 19 +++----------------
libxfs/xfs_bmap.h | 4 ++++
2 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index a82a41249..ae4f7e699 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -6185,15 +6185,6 @@ __xfs_bmap_add(
{
struct xfs_bmap_intent *bi;
- trace_xfs_bmap_defer(tp->t_mountp,
- XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
- type,
- XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
- ip->i_ino, whichfork,
- bmap->br_startoff,
- bmap->br_blockcount,
- bmap->br_state);
-
bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&bi->bi_list);
bi->bi_type = type;
@@ -6201,6 +6192,8 @@ __xfs_bmap_add(
bi->bi_whichfork = whichfork;
bi->bi_bmap = *bmap;
+ trace_xfs_bmap_defer(bi);
+
xfs_bmap_update_get_group(tp->t_mountp, bi);
xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type);
return 0;
@@ -6246,13 +6239,7 @@ xfs_bmap_finish_one(
ASSERT(tp->t_highest_agno == NULLAGNUMBER);
- trace_xfs_bmap_deferred(tp->t_mountp,
- XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
- bi->bi_type,
- XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
- bi->bi_owner->i_ino, bi->bi_whichfork,
- bmap->br_startoff, bmap->br_blockcount,
- bmap->br_state);
+ trace_xfs_bmap_deferred(bi);
if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) {
xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h
index 10b858652..0a2fd9304 100644
--- a/libxfs/xfs_bmap.h
+++ b/libxfs/xfs_bmap.h
@@ -232,6 +232,10 @@ enum xfs_bmap_intent_type {
XFS_BMAP_UNMAP,
};
+#define XFS_BMAP_INTENT_STRINGS \
+ { XFS_BMAP_MAP, "map" }, \
+ { XFS_BMAP_UNMAP, "unmap" }
+
struct xfs_bmap_intent {
struct list_head bi_list;
enum xfs_bmap_intent_type bi_type;
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 101/111] xfs: move xfs_bmap_defer_add to xfs_bmap_item.c
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (99 preceding siblings ...)
2024-05-22 3:14 ` [PATCH 100/111] xfs: clean up bmap log intent item tracepoint callsites Darrick J. Wong
@ 2024-05-22 3:15 ` Darrick J. Wong
2024-05-22 3:15 ` [PATCH 102/111] xfs: fix xfs_bunmapi to allow unmapping of partial rt extents Darrick J. Wong
` (10 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:15 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 80284115854e60686b2e0183b31bb303ae69aa8c
Move the code that adds the incore xfs_bmap_item deferred work data to a
transaction live with the BUI log item code. This means that the file
mapping code no longer has to know about the inner workings of the BUI
log items.
As a consequence, we can hide the _get_group helper.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/Makefile | 1 +
libxfs/defer_item.c | 15 ++++++++++++++-
libxfs/defer_item.h | 13 +++++++++++++
libxfs/xfs_bmap.c | 6 ++----
libxfs/xfs_bmap.h | 3 ---
5 files changed, 30 insertions(+), 8 deletions(-)
create mode 100644 libxfs/defer_item.h
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 9baee62c0..1c88dbc2a 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -20,6 +20,7 @@ PKGHFILES = xfs_fs.h \
xfs_log_format.h
HFILES = \
+ defer_item.h \
libxfs_io.h \
libxfs_api_defs.h \
init.h \
diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c
index 014589f82..d67032c26 100644
--- a/libxfs/defer_item.c
+++ b/libxfs/defer_item.c
@@ -24,6 +24,7 @@
#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "libxfs.h"
+#include "defer_item.h"
/* Dummy defer item ops, since we don't do logging. */
@@ -479,7 +480,7 @@ xfs_bmap_update_create_done(
}
/* Take an active ref to the AG containing the space we're mapping. */
-void
+static inline void
xfs_bmap_update_get_group(
struct xfs_mount *mp,
struct xfs_bmap_intent *bi)
@@ -498,6 +499,18 @@ xfs_bmap_update_get_group(
bi->bi_pag = xfs_perag_intent_get(mp, agno);
}
+/* Add this deferred BUI to the transaction. */
+void
+xfs_bmap_defer_add(
+ struct xfs_trans *tp,
+ struct xfs_bmap_intent *bi)
+{
+ trace_xfs_bmap_defer(bi);
+
+ xfs_bmap_update_get_group(tp->t_mountp, bi);
+ xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type);
+}
+
/* Release an active AG ref after finishing mapping work. */
static inline void
xfs_bmap_update_put_group(
diff --git a/libxfs/defer_item.h b/libxfs/defer_item.h
new file mode 100644
index 000000000..6d3abf158
--- /dev/null
+++ b/libxfs/defer_item.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023-2024 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __LIBXFS_DEFER_ITEM_H_
+#define __LIBXFS_DEFER_ITEM_H_
+
+struct xfs_bmap_intent;
+
+void xfs_bmap_defer_add(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
+
+#endif /* __LIBXFS_DEFER_ITEM_H_ */
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index ae4f7e699..07bd8b346 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -31,6 +31,7 @@
#include "xfs_refcount.h"
#include "xfs_rtbitmap.h"
#include "xfs_health.h"
+#include "defer_item.h"
struct kmem_cache *xfs_bmap_intent_cache;
@@ -6192,10 +6193,7 @@ __xfs_bmap_add(
bi->bi_whichfork = whichfork;
bi->bi_bmap = *bmap;
- trace_xfs_bmap_defer(bi);
-
- xfs_bmap_update_get_group(tp->t_mountp, bi);
- xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type);
+ xfs_bmap_defer_add(tp, bi);
return 0;
}
diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h
index 0a2fd9304..325cc232a 100644
--- a/libxfs/xfs_bmap.h
+++ b/libxfs/xfs_bmap.h
@@ -245,9 +245,6 @@ struct xfs_bmap_intent {
struct xfs_bmbt_irec bi_bmap;
};
-void xfs_bmap_update_get_group(struct xfs_mount *mp,
- struct xfs_bmap_intent *bi);
-
int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
void xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
struct xfs_bmbt_irec *imap);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 102/111] xfs: fix xfs_bunmapi to allow unmapping of partial rt extents
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (100 preceding siblings ...)
2024-05-22 3:15 ` [PATCH 101/111] xfs: move xfs_bmap_defer_add to xfs_bmap_item.c Darrick J. Wong
@ 2024-05-22 3:15 ` Darrick J. Wong
2024-05-22 3:15 ` [PATCH 103/111] xfs: add a realtime flag to the bmap update log redo items Darrick J. Wong
` (9 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:15 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 2b6a5ec26887cba195022286b039f2cc0ec683b1
When XFS_BMAPI_REMAP is passed to bunmapi, that means that we want to
remove part of a block mapping without touching the allocator. For
realtime files with rtextsize > 1, that also means that we should skip
all the code that changes a partial remove request into an unwritten
extent conversion. IOWs, bunmapi in this mode should handle removing
the mapping from the rt file and nothing else.
Note that XFS_BMAPI_REMAP callers are required to decrement the
reference count and/or free the space manually.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
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 07bd8b346..388550912 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -5453,7 +5453,7 @@ __xfs_bunmapi(
if (del.br_startoff + del.br_blockcount > end + 1)
del.br_blockcount = end + 1 - del.br_startoff;
- if (!isrt)
+ if (!isrt || (flags & XFS_BMAPI_REMAP))
goto delete;
mod = xfs_rtb_to_rtxoff(mp,
@@ -5471,7 +5471,7 @@ __xfs_bunmapi(
* This piece is unwritten, or we're not
* using unwritten extents. Skip over it.
*/
- ASSERT(end >= mod);
+ ASSERT((flags & XFS_BMAPI_REMAP) || end >= mod);
end -= mod > del.br_blockcount ?
del.br_blockcount : mod;
if (end < got.br_startoff &&
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 103/111] xfs: add a realtime flag to the bmap update log redo items
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (101 preceding siblings ...)
2024-05-22 3:15 ` [PATCH 102/111] xfs: fix xfs_bunmapi to allow unmapping of partial rt extents Darrick J. Wong
@ 2024-05-22 3:15 ` Darrick J. Wong
2024-05-22 3:15 ` [PATCH 104/111] xfs: support deferred bmap updates on the attr fork Darrick J. Wong
` (8 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:15 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 7302cda7f8b08062b11d2ba9ae0b4f3871fe3d46
Extend the bmap update (BUI) log items with a new realtime flag that
indicates that the updates apply against a realtime file's data fork.
We'll wire up the actual code later.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_log_format.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 269573c82..16872972e 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -838,10 +838,12 @@ struct xfs_cud_log_format {
#define XFS_BMAP_EXTENT_ATTR_FORK (1U << 31)
#define XFS_BMAP_EXTENT_UNWRITTEN (1U << 30)
+#define XFS_BMAP_EXTENT_REALTIME (1U << 29)
#define XFS_BMAP_EXTENT_FLAGS (XFS_BMAP_EXTENT_TYPE_MASK | \
XFS_BMAP_EXTENT_ATTR_FORK | \
- XFS_BMAP_EXTENT_UNWRITTEN)
+ XFS_BMAP_EXTENT_UNWRITTEN | \
+ XFS_BMAP_EXTENT_REALTIME)
/*
* This is the structure used to lay out an bui log item in the
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 104/111] xfs: support deferred bmap updates on the attr fork
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (102 preceding siblings ...)
2024-05-22 3:15 ` [PATCH 103/111] xfs: add a realtime flag to the bmap update log redo items Darrick J. Wong
@ 2024-05-22 3:15 ` Darrick J. Wong
2024-05-22 3:16 ` [PATCH 105/111] xfs: xfs_bmap_finish_one should map unwritten extents properly Darrick J. Wong
` (7 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:15 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 52f807067ba4a122e75bf1e0e0595c78e6a3d8b6
The deferred bmap update log item has always supported the attr fork, so
plumb this in so that higher layers can access this.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap.c | 47 +++++++++++++++++++----------------------------
libxfs/xfs_bmap.h | 4 ++--
2 files changed, 21 insertions(+), 30 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 388550912..f09ec3dfe 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -6166,17 +6166,8 @@ xfs_bmap_split_extent(
return error;
}
-/* Deferred mapping is only for real extents in the data fork. */
-static bool
-xfs_bmap_is_update_needed(
- struct xfs_bmbt_irec *bmap)
-{
- return bmap->br_startblock != HOLESTARTBLOCK &&
- bmap->br_startblock != DELAYSTARTBLOCK;
-}
-
/* Record a bmap intent. */
-static int
+static inline void
__xfs_bmap_add(
struct xfs_trans *tp,
enum xfs_bmap_intent_type type,
@@ -6186,6 +6177,11 @@ __xfs_bmap_add(
{
struct xfs_bmap_intent *bi;
+ if ((whichfork != XFS_DATA_FORK && whichfork != XFS_ATTR_FORK) ||
+ bmap->br_startblock == HOLESTARTBLOCK ||
+ bmap->br_startblock == DELAYSTARTBLOCK)
+ return;
+
bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&bi->bi_list);
bi->bi_type = type;
@@ -6194,7 +6190,6 @@ __xfs_bmap_add(
bi->bi_bmap = *bmap;
xfs_bmap_defer_add(tp, bi);
- return 0;
}
/* Map an extent into a file. */
@@ -6202,12 +6197,10 @@ void
xfs_bmap_map_extent(
struct xfs_trans *tp,
struct xfs_inode *ip,
+ int whichfork,
struct xfs_bmbt_irec *PREV)
{
- if (!xfs_bmap_is_update_needed(PREV))
- return;
-
- __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV);
+ __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, whichfork, PREV);
}
/* Unmap an extent out of a file. */
@@ -6215,12 +6208,10 @@ void
xfs_bmap_unmap_extent(
struct xfs_trans *tp,
struct xfs_inode *ip,
+ int whichfork,
struct xfs_bmbt_irec *PREV)
{
- if (!xfs_bmap_is_update_needed(PREV))
- return;
-
- __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV);
+ __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, whichfork, PREV);
}
/*
@@ -6234,29 +6225,29 @@ xfs_bmap_finish_one(
{
struct xfs_bmbt_irec *bmap = &bi->bi_bmap;
int error = 0;
+ int flags = 0;
+
+ if (bi->bi_whichfork == XFS_ATTR_FORK)
+ flags |= XFS_BMAPI_ATTRFORK;
ASSERT(tp->t_highest_agno == NULLAGNUMBER);
trace_xfs_bmap_deferred(bi);
- if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) {
- xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
- return -EFSCORRUPTED;
- }
-
- if (XFS_TEST_ERROR(false, tp->t_mountp,
- XFS_ERRTAG_BMAP_FINISH_ONE))
+ if (XFS_TEST_ERROR(false, tp->t_mountp, XFS_ERRTAG_BMAP_FINISH_ONE))
return -EIO;
switch (bi->bi_type) {
case XFS_BMAP_MAP:
error = xfs_bmapi_remap(tp, bi->bi_owner, bmap->br_startoff,
- bmap->br_blockcount, bmap->br_startblock, 0);
+ bmap->br_blockcount, bmap->br_startblock,
+ flags);
bmap->br_blockcount = 0;
break;
case XFS_BMAP_UNMAP:
error = __xfs_bunmapi(tp, bi->bi_owner, bmap->br_startoff,
- &bmap->br_blockcount, XFS_BMAPI_REMAP, 1);
+ &bmap->br_blockcount, flags | XFS_BMAPI_REMAP,
+ 1);
break;
default:
ASSERT(0);
diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h
index 325cc232a..f76625953 100644
--- a/libxfs/xfs_bmap.h
+++ b/libxfs/xfs_bmap.h
@@ -247,9 +247,9 @@ struct xfs_bmap_intent {
int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
void xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
- struct xfs_bmbt_irec *imap);
+ int whichfork, struct xfs_bmbt_irec *imap);
void xfs_bmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip,
- struct xfs_bmbt_irec *imap);
+ int whichfork, struct xfs_bmbt_irec *imap);
static inline uint32_t xfs_bmap_fork_to_state(int whichfork)
{
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 105/111] xfs: xfs_bmap_finish_one should map unwritten extents properly
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (103 preceding siblings ...)
2024-05-22 3:15 ` [PATCH 104/111] xfs: support deferred bmap updates on the attr fork Darrick J. Wong
@ 2024-05-22 3:16 ` Darrick J. Wong
2024-05-22 3:16 ` [PATCH 106/111] xfs: move xfs_symlink_remote.c declarations to xfs_symlink_remote.h Darrick J. Wong
` (6 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:16 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 6c8127e93e3ac9c2cf6a13b885dd2d057b7e7d50
The deferred bmap work state and the log item can transmit unwritten
state, so the XFS_BMAP_MAP handler must map in extents with that
unwritten state.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_bmap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index f09ec3dfe..70476c549 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -6239,6 +6239,8 @@ xfs_bmap_finish_one(
switch (bi->bi_type) {
case XFS_BMAP_MAP:
+ if (bi->bi_bmap.br_state == XFS_EXT_UNWRITTEN)
+ flags |= XFS_BMAPI_PREALLOC;
error = xfs_bmapi_remap(tp, bi->bi_owner, bmap->br_startoff,
bmap->br_blockcount, bmap->br_startblock,
flags);
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 106/111] xfs: move xfs_symlink_remote.c declarations to xfs_symlink_remote.h
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (104 preceding siblings ...)
2024-05-22 3:16 ` [PATCH 105/111] xfs: xfs_bmap_finish_one should map unwritten extents properly Darrick J. Wong
@ 2024-05-22 3:16 ` Darrick J. Wong
2024-05-22 3:16 ` [PATCH 107/111] xfs: move remote symlink target read function to libxfs Darrick J. Wong
` (5 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:16 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 622d88e2ad7960b83af38dabf6b848a22a5a1c1f
Move declarations for libxfs symlink functions into a separate header
file like we do for most everything else.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
include/libxfs.h | 1 +
libxfs/xfs_bmap.c | 1 +
libxfs/xfs_inode_fork.c | 1 +
libxfs/xfs_shared.h | 13 -------------
libxfs/xfs_symlink_remote.c | 1 +
libxfs/xfs_symlink_remote.h | 22 ++++++++++++++++++++++
6 files changed, 26 insertions(+), 13 deletions(-)
create mode 100644 libxfs/xfs_symlink_remote.h
diff --git a/include/libxfs.h b/include/libxfs.h
index 563c40e57..79df8bc7c 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -86,6 +86,7 @@ struct iomap;
#include "xfs_refcount.h"
#include "xfs_btree_staging.h"
#include "xfs_rtbitmap.h"
+#include "xfs_symlink_remote.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 70476c549..b089f53e0 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -32,6 +32,7 @@
#include "xfs_rtbitmap.h"
#include "xfs_health.h"
#include "defer_item.h"
+#include "xfs_symlink_remote.h"
struct kmem_cache *xfs_bmap_intent_cache;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 052748814..d9f0a21ac 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -24,6 +24,7 @@
#include "xfs_types.h"
#include "xfs_errortag.h"
#include "xfs_health.h"
+#include "xfs_symlink_remote.h"
struct kmem_cache *xfs_ifork_cache;
diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h
index cab49e711..dfd61fa83 100644
--- a/libxfs/xfs_shared.h
+++ b/libxfs/xfs_shared.h
@@ -182,19 +182,6 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,
#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */
#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */
-
-/*
- * Symlink decoding/encoding functions
- */
-int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen);
-int xfs_symlink_hdr_set(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
- uint32_t size, struct xfs_buf *bp);
-bool xfs_symlink_hdr_ok(xfs_ino_t ino, uint32_t offset,
- uint32_t size, struct xfs_buf *bp);
-void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
- struct xfs_inode *ip, struct xfs_ifork *ifp);
-xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
-
/* Computed inode geometry for the filesystem. */
struct xfs_ino_geometry {
/* Maximum inode count in this filesystem. */
diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c
index fa90b1793..33689ba2e 100644
--- a/libxfs/xfs_symlink_remote.c
+++ b/libxfs/xfs_symlink_remote.c
@@ -13,6 +13,7 @@
#include "xfs_mount.h"
#include "xfs_inode.h"
#include "xfs_trans.h"
+#include "xfs_symlink_remote.h"
/*
diff --git a/libxfs/xfs_symlink_remote.h b/libxfs/xfs_symlink_remote.h
new file mode 100644
index 000000000..c6f621a0e
--- /dev/null
+++ b/libxfs/xfs_symlink_remote.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All Rights Reserved.
+ */
+#ifndef __XFS_SYMLINK_REMOTE_H
+#define __XFS_SYMLINK_REMOTE_H
+
+/*
+ * Symlink decoding/encoding functions
+ */
+int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen);
+int xfs_symlink_hdr_set(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
+ uint32_t size, struct xfs_buf *bp);
+bool xfs_symlink_hdr_ok(xfs_ino_t ino, uint32_t offset,
+ uint32_t size, struct xfs_buf *bp);
+void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
+ struct xfs_inode *ip, struct xfs_ifork *ifp);
+xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
+
+#endif /* __XFS_SYMLINK_REMOTE_H */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 107/111] xfs: move remote symlink target read function to libxfs
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (105 preceding siblings ...)
2024-05-22 3:16 ` [PATCH 106/111] xfs: move xfs_symlink_remote.c declarations to xfs_symlink_remote.h Darrick J. Wong
@ 2024-05-22 3:16 ` Darrick J. Wong
2024-05-22 3:16 ` [PATCH 108/111] xfs: move symlink target write " Darrick J. Wong
` (4 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:16 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 376b4f0522484f43660dab8e4e92b471863b49f9
Move xfs_readlink_bmap_ilocked to xfs_symlink_remote.c so that the
swapext code can use it to convert a remote format symlink back to
shortform format after a metadata repair. While we're at it, fix a
broken printf prefix.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_symlink_remote.c | 77 +++++++++++++++++++++++++++++++++++++++++++
libxfs/xfs_symlink_remote.h | 1 +
2 files changed, 78 insertions(+)
diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c
index 33689ba2e..f2e591ea9 100644
--- a/libxfs/xfs_symlink_remote.c
+++ b/libxfs/xfs_symlink_remote.c
@@ -14,6 +14,9 @@
#include "xfs_inode.h"
#include "xfs_trans.h"
#include "xfs_symlink_remote.h"
+#include "xfs_bit.h"
+#include "xfs_bmap.h"
+#include "xfs_health.h"
/*
@@ -225,3 +228,77 @@ xfs_symlink_shortform_verify(
return __this_address;
return NULL;
}
+
+/* Read a remote symlink target into the buffer. */
+int
+xfs_symlink_remote_read(
+ struct xfs_inode *ip,
+ char *link)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
+ struct xfs_buf *bp;
+ xfs_daddr_t d;
+ char *cur_chunk;
+ int pathlen = ip->i_disk_size;
+ int nmaps = XFS_SYMLINK_MAPS;
+ int byte_cnt;
+ int n;
+ int error = 0;
+ int fsblocks = 0;
+ int offset;
+
+ xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
+
+ fsblocks = xfs_symlink_blocks(mp, pathlen);
+ error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
+ if (error)
+ goto out;
+
+ offset = 0;
+ for (n = 0; n < nmaps; n++) {
+ d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
+ byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
+
+ error = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
+ &bp, &xfs_symlink_buf_ops);
+ if (xfs_metadata_is_sick(error))
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
+ if (error)
+ return error;
+ byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
+ if (pathlen < byte_cnt)
+ byte_cnt = pathlen;
+
+ cur_chunk = bp->b_addr;
+ if (xfs_has_crc(mp)) {
+ if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
+ byte_cnt, bp)) {
+ xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
+ error = -EFSCORRUPTED;
+ xfs_alert(mp,
+"symlink header does not match required off/len/owner (0x%x/0x%x,0x%llx)",
+ offset, byte_cnt, ip->i_ino);
+ xfs_buf_relse(bp);
+ goto out;
+
+ }
+
+ cur_chunk += sizeof(struct xfs_dsymlink_hdr);
+ }
+
+ memcpy(link + offset, cur_chunk, byte_cnt);
+
+ pathlen -= byte_cnt;
+ offset += byte_cnt;
+
+ xfs_buf_relse(bp);
+ }
+ ASSERT(pathlen == 0);
+
+ link[ip->i_disk_size] = '\0';
+ error = 0;
+
+ out:
+ return error;
+}
diff --git a/libxfs/xfs_symlink_remote.h b/libxfs/xfs_symlink_remote.h
index c6f621a0e..bb83a8b8d 100644
--- a/libxfs/xfs_symlink_remote.h
+++ b/libxfs/xfs_symlink_remote.h
@@ -18,5 +18,6 @@ bool xfs_symlink_hdr_ok(xfs_ino_t ino, uint32_t offset,
void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
struct xfs_inode *ip, struct xfs_ifork *ifp);
xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
+int xfs_symlink_remote_read(struct xfs_inode *ip, char *link);
#endif /* __XFS_SYMLINK_REMOTE_H */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 108/111] xfs: move symlink target write function to libxfs
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (106 preceding siblings ...)
2024-05-22 3:16 ` [PATCH 107/111] xfs: move remote symlink target read function to libxfs Darrick J. Wong
@ 2024-05-22 3:16 ` Darrick J. Wong
2024-05-22 3:17 ` [PATCH 109/111] xfs: xfs_btree_bload_prep_block() should use __GFP_NOFAIL Darrick J. Wong
` (3 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:16 UTC (permalink / raw)
To: djwong, cem; +Cc: Christoph Hellwig, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: b8102b61f7b8929ad8043e4574a1e26276398041
Move xfs_symlink_write_target to xfs_symlink_remote.c so that kernel and
mkfs can share the same function.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
libxfs/xfs_symlink_remote.c | 77 ++++++++++++++++++++++++++++++++++++++++++-
libxfs/xfs_symlink_remote.h | 3 ++
2 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c
index f2e591ea9..875e03bcb 100644
--- a/libxfs/xfs_symlink_remote.c
+++ b/libxfs/xfs_symlink_remote.c
@@ -18,7 +18,6 @@
#include "xfs_bmap.h"
#include "xfs_health.h"
-
/*
* Each contiguous block has a header, so it is not just a simple pathlen
* to FSB conversion.
@@ -302,3 +301,79 @@ xfs_symlink_remote_read(
out:
return error;
}
+
+/* Write the symlink target into the inode. */
+int
+xfs_symlink_write_target(
+ struct xfs_trans *tp,
+ struct xfs_inode *ip,
+ const char *target_path,
+ int pathlen,
+ xfs_fsblock_t fs_blocks,
+ uint resblks)
+{
+ struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
+ struct xfs_mount *mp = tp->t_mountp;
+ const char *cur_chunk;
+ struct xfs_buf *bp;
+ xfs_daddr_t d;
+ int byte_cnt;
+ int nmaps;
+ int offset = 0;
+ int n;
+ int error;
+
+ /*
+ * If the symlink will fit into the inode, write it inline.
+ */
+ if (pathlen <= xfs_inode_data_fork_size(ip)) {
+ xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
+
+ ip->i_disk_size = pathlen;
+ ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
+ return 0;
+ }
+
+ nmaps = XFS_SYMLINK_MAPS;
+ error = xfs_bmapi_write(tp, ip, 0, fs_blocks, XFS_BMAPI_METADATA,
+ resblks, mval, &nmaps);
+ if (error)
+ return error;
+
+ ip->i_disk_size = pathlen;
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+ cur_chunk = target_path;
+ offset = 0;
+ for (n = 0; n < nmaps; n++) {
+ char *buf;
+
+ d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
+ byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
+ error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+ BTOBB(byte_cnt), 0, &bp);
+ if (error)
+ return error;
+ bp->b_ops = &xfs_symlink_buf_ops;
+
+ byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
+ byte_cnt = min(byte_cnt, pathlen);
+
+ buf = bp->b_addr;
+ buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset, byte_cnt,
+ bp);
+
+ memcpy(buf, cur_chunk, byte_cnt);
+
+ cur_chunk += byte_cnt;
+ pathlen -= byte_cnt;
+ offset += byte_cnt;
+
+ xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
+ xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
+ (char *)bp->b_addr);
+ }
+ ASSERT(pathlen == 0);
+ return 0;
+}
diff --git a/libxfs/xfs_symlink_remote.h b/libxfs/xfs_symlink_remote.h
index bb83a8b8d..a63bd38ae 100644
--- a/libxfs/xfs_symlink_remote.h
+++ b/libxfs/xfs_symlink_remote.h
@@ -19,5 +19,8 @@ void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
struct xfs_inode *ip, struct xfs_ifork *ifp);
xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
int xfs_symlink_remote_read(struct xfs_inode *ip, char *link);
+int xfs_symlink_write_target(struct xfs_trans *tp, struct xfs_inode *ip,
+ const char *target_path, int pathlen, xfs_fsblock_t fs_blocks,
+ uint resblks);
#endif /* __XFS_SYMLINK_REMOTE_H */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 109/111] xfs: xfs_btree_bload_prep_block() should use __GFP_NOFAIL
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (107 preceding siblings ...)
2024-05-22 3:16 ` [PATCH 108/111] xfs: move symlink target write " Darrick J. Wong
@ 2024-05-22 3:17 ` Darrick J. Wong
2024-05-22 3:17 ` [PATCH 110/111] xfs: shrink failure needs to hold AGI buffer Darrick J. Wong
` (2 subsequent siblings)
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:17 UTC (permalink / raw)
To: djwong, cem
Cc: Dan Carpenter, Dave Chinner, Christoph Hellwig, Chandan Babu R,
linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 3aca0676a1141c4d198f8b3c934435941ba84244
This was missed in the conversion from KM* flags.
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Fixes: 10634530f7ba ("xfs: convert kmem_zalloc() to kzalloc()")
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_btree_staging.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index 52410fe4f..2f5b1d0b6 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -303,7 +303,7 @@ xfs_btree_bload_prep_block(
/* Allocate a new incore btree root block. */
new_size = bbl->iroot_size(cur, level, nr_this_block, priv);
- ifp->if_broot = kzalloc(new_size, GFP_KERNEL);
+ ifp->if_broot = kzalloc(new_size, GFP_KERNEL | __GFP_NOFAIL);
ifp->if_broot_bytes = (int)new_size;
/* Initialize it and send it out. */
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 110/111] xfs: shrink failure needs to hold AGI buffer
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (108 preceding siblings ...)
2024-05-22 3:17 ` [PATCH 109/111] xfs: xfs_btree_bload_prep_block() should use __GFP_NOFAIL Darrick J. Wong
@ 2024-05-22 3:17 ` Darrick J. Wong
2024-05-22 3:17 ` [PATCH 111/111] xfs: allow sunit mount option to repair bad primary sb stripe values Darrick J. Wong
2024-06-03 12:29 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Carlos Maiolino
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:17 UTC (permalink / raw)
To: djwong, cem
Cc: Chandan Babu R, Dave Chinner, Gao Xiang, Christoph Hellwig,
Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 75bcffbb9e7563259b7aed0fa77459d6a3a35627
Chandan reported a AGI/AGF lock order hang on xfs/168 during recent
testing. The cause of the problem was the task running xfs_growfs
to shrink the filesystem. A failure occurred trying to remove the
free space from the btrees that the shrink would make disappear,
and that meant it ran the error handling for a partial failure.
This error path involves restoring the per-ag block reservations,
and that requires calculating the amount of space needed to be
reserved for the free inode btree. The growfs operation hung here:
[18679.536829] down+0x71/0xa0
[18679.537657] xfs_buf_lock+0xa4/0x290 [xfs]
[18679.538731] xfs_buf_find_lock+0xf7/0x4d0 [xfs]
[18679.539920] xfs_buf_lookup.constprop.0+0x289/0x500 [xfs]
[18679.542628] xfs_buf_get_map+0x2b3/0xe40 [xfs]
[18679.547076] xfs_buf_read_map+0xbb/0x900 [xfs]
[18679.562616] xfs_trans_read_buf_map+0x449/0xb10 [xfs]
[18679.569778] xfs_read_agi+0x1cd/0x500 [xfs]
[18679.573126] xfs_ialloc_read_agi+0xc2/0x5b0 [xfs]
[18679.578708] xfs_finobt_calc_reserves+0xe7/0x4d0 [xfs]
[18679.582480] xfs_ag_resv_init+0x2c5/0x490 [xfs]
[18679.586023] xfs_ag_shrink_space+0x736/0xd30 [xfs]
[18679.590730] xfs_growfs_data_private.isra.0+0x55e/0x990 [xfs]
[18679.599764] xfs_growfs_data+0x2f1/0x410 [xfs]
[18679.602212] xfs_file_ioctl+0xd1e/0x1370 [xfs]
trying to get the AGI lock. The AGI lock was held by a fstress task
trying to do an inode allocation, and it was waiting on the AGF
lock to allocate a new inode chunk on disk. Hence deadlock.
The fix for this is for the growfs code to hold the AGI over the
transaction roll it does in the error path. It already holds the AGF
locked across this, and that is what causes the lock order inversion
in the xfs_ag_resv_init() call.
Reported-by: Chandan Babu R <chandanbabu@kernel.org>
Fixes: 46141dc891f7 ("xfs: introduce xfs_ag_shrink_space()")
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_ag.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index e2fc3e882..a9aae0990 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -973,14 +973,23 @@ xfs_ag_shrink_space(
if (error) {
/*
- * if extent allocation fails, need to roll the transaction to
+ * If extent allocation fails, need to roll the transaction to
* ensure that the AGFL fixup has been committed anyway.
+ *
+ * We need to hold the AGF across the roll to ensure nothing can
+ * access the AG for allocation until the shrink is fully
+ * cleaned up. And due to the resetting of the AG block
+ * reservation space needing to lock the AGI, we also have to
+ * hold that so we don't get AGI/AGF lock order inversions in
+ * the error handling path.
*/
xfs_trans_bhold(*tpp, agfbp);
+ xfs_trans_bhold(*tpp, agibp);
err2 = xfs_trans_roll(tpp);
if (err2)
return err2;
xfs_trans_bjoin(*tpp, agfbp);
+ xfs_trans_bjoin(*tpp, agibp);
goto resv_init_out;
}
^ permalink raw reply related [flat|nested] 154+ messages in thread* [PATCH 111/111] xfs: allow sunit mount option to repair bad primary sb stripe values
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (109 preceding siblings ...)
2024-05-22 3:17 ` [PATCH 110/111] xfs: shrink failure needs to hold AGI buffer Darrick J. Wong
@ 2024-05-22 3:17 ` Darrick J. Wong
2024-06-03 12:29 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Carlos Maiolino
111 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-05-22 3:17 UTC (permalink / raw)
To: djwong, cem; +Cc: Dave Chinner, Christoph Hellwig, Chandan Babu R, linux-xfs
From: Dave Chinner <dchinner@redhat.com>
Source kernel commit: 15922f5dbf51dad334cde888ce6835d377678dc9
If a filesystem has a busted stripe alignment configuration on disk
(e.g. because broken RAID firmware told mkfs that swidth was smaller
than sunit), then the filesystem will refuse to mount due to the
stripe validation failing. This failure is triggering during distro
upgrades from old kernels lacking this check to newer kernels with
this check, and currently the only way to fix it is with offline
xfs_db surgery.
This runtime validity checking occurs when we read the superblock
for the first time and causes the mount to fail immediately. This
prevents the rewrite of stripe unit/width via
mount options that occurs later in the mount process. Hence there is
no way to recover this situation without resorting to offline xfs_db
rewrite of the values.
However, we parse the mount options long before we read the
superblock, and we know if the mount has been asked to re-write the
stripe alignment configuration when we are reading the superblock
and verifying it for the first time. Hence we can conditionally
ignore stripe verification failures if the mount options specified
will correct the issue.
We validate that the new stripe unit/width are valid before we
overwrite the superblock values, so we can ignore the invalid config
at verification and fail the mount later if the new values are not
valid. This, at least, gives users the chance of correcting the
issue after a kernel upgrade without having to resort to xfs-db
hacks.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
---
libxfs/xfs_sb.c | 40 +++++++++++++++++++++++++++++++---------
libxfs/xfs_sb.h | 5 +++--
mkfs/xfs_mkfs.c | 6 +++---
3 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 00b0a937d..895d646bb 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -528,7 +528,8 @@ xfs_validate_sb_common(
}
if (!xfs_validate_stripe_geometry(mp, XFS_FSB_TO_B(mp, sbp->sb_unit),
- XFS_FSB_TO_B(mp, sbp->sb_width), 0, false))
+ XFS_FSB_TO_B(mp, sbp->sb_width), 0,
+ xfs_buf_daddr(bp) == XFS_SB_DADDR, false))
return -EFSCORRUPTED;
/*
@@ -1321,8 +1322,10 @@ xfs_sb_get_secondary(
}
/*
- * sunit, swidth, sectorsize(optional with 0) should be all in bytes,
- * so users won't be confused by values in error messages.
+ * sunit, swidth, sectorsize(optional with 0) should be all in bytes, so users
+ * won't be confused by values in error messages. This function returns false
+ * if the stripe geometry is invalid and the caller is unable to repair the
+ * stripe configuration later in the mount process.
*/
bool
xfs_validate_stripe_geometry(
@@ -1330,20 +1333,21 @@ xfs_validate_stripe_geometry(
__s64 sunit,
__s64 swidth,
int sectorsize,
+ bool may_repair,
bool silent)
{
if (swidth > INT_MAX) {
if (!silent)
xfs_notice(mp,
"stripe width (%lld) is too large", swidth);
- return false;
+ goto check_override;
}
if (sunit > swidth) {
if (!silent)
xfs_notice(mp,
"stripe unit (%lld) is larger than the stripe width (%lld)", sunit, swidth);
- return false;
+ goto check_override;
}
if (sectorsize && (int)sunit % sectorsize) {
@@ -1351,21 +1355,21 @@ xfs_validate_stripe_geometry(
xfs_notice(mp,
"stripe unit (%lld) must be a multiple of the sector size (%d)",
sunit, sectorsize);
- return false;
+ goto check_override;
}
if (sunit && !swidth) {
if (!silent)
xfs_notice(mp,
"invalid stripe unit (%lld) and stripe width of 0", sunit);
- return false;
+ goto check_override;
}
if (!sunit && swidth) {
if (!silent)
xfs_notice(mp,
"invalid stripe width (%lld) and stripe unit of 0", swidth);
- return false;
+ goto check_override;
}
if (sunit && (int)swidth % (int)sunit) {
@@ -1373,9 +1377,27 @@ xfs_validate_stripe_geometry(
xfs_notice(mp,
"stripe width (%lld) must be a multiple of the stripe unit (%lld)",
swidth, sunit);
- return false;
+ goto check_override;
}
return true;
+
+check_override:
+ if (!may_repair)
+ return false;
+ /*
+ * During mount, mp->m_dalign will not be set unless the sunit mount
+ * option was set. If it was set, ignore the bad stripe alignment values
+ * and allow the validation and overwrite later in the mount process to
+ * attempt to overwrite the bad stripe alignment values with the values
+ * supplied by mount options.
+ */
+ if (!mp->m_dalign)
+ return false;
+ if (!silent)
+ xfs_notice(mp,
+"Will try to correct with specified mount options sunit (%d) and swidth (%d)",
+ BBTOB(mp->m_dalign), BBTOB(mp->m_swidth));
+ return true;
}
/*
diff --git a/libxfs/xfs_sb.h b/libxfs/xfs_sb.h
index 2e8e8d63d..37b1ed1bc 100644
--- a/libxfs/xfs_sb.h
+++ b/libxfs/xfs_sb.h
@@ -35,8 +35,9 @@ extern int xfs_sb_get_secondary(struct xfs_mount *mp,
struct xfs_trans *tp, xfs_agnumber_t agno,
struct xfs_buf **bpp);
-extern bool xfs_validate_stripe_geometry(struct xfs_mount *mp,
- __s64 sunit, __s64 swidth, int sectorsize, bool silent);
+bool xfs_validate_stripe_geometry(struct xfs_mount *mp,
+ __s64 sunit, __s64 swidth, int sectorsize, bool may_repair,
+ bool silent);
uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents);
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index d6fa48ede..4f2d529aa 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2765,13 +2765,13 @@ _("data stripe width (%lld) is too large of a multiple of the data stripe unit (
}
if (!libxfs_validate_stripe_geometry(NULL, dsu, big_dswidth,
- cfg->sectorsize, false))
+ cfg->sectorsize, false, false))
usage();
dsunit = BTOBBT(dsu);
dswidth = BTOBBT(big_dswidth);
} else if (!libxfs_validate_stripe_geometry(NULL, BBTOB(dsunit),
- BBTOB(dswidth), cfg->sectorsize, false)) {
+ BBTOB(dswidth), cfg->sectorsize, false, false)) {
usage();
}
@@ -2791,7 +2791,7 @@ _("data stripe width (%lld) is too large of a multiple of the data stripe unit (
if (!dsunit) {
/* Ignore nonsense from device report. */
if (!libxfs_validate_stripe_geometry(NULL, BBTOB(ft->data.sunit),
- BBTOB(ft->data.swidth), 0, true)) {
+ BBTOB(ft->data.swidth), 0, false, true)) {
fprintf(stderr,
_("%s: Volume reports invalid stripe unit (%d) and stripe width (%d), ignoring.\n"),
progname,
^ permalink raw reply related [flat|nested] 154+ messages in thread* Re: [PATCHSET v30.4 02/10] libxfs: sync with 6.9
2024-05-22 2:45 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Darrick J. Wong
` (110 preceding siblings ...)
2024-05-22 3:17 ` [PATCH 111/111] xfs: allow sunit mount option to repair bad primary sb stripe values Darrick J. Wong
@ 2024-06-03 12:29 ` Carlos Maiolino
2024-06-03 20:22 ` Darrick J. Wong
111 siblings, 1 reply; 154+ messages in thread
From: Carlos Maiolino @ 2024-06-03 12:29 UTC (permalink / raw)
To: Darrick J. Wong
Cc: Christoph Hellwig, Chandan Babu R, Matthew Wilcox (Oracle),
Dave Chinner, Dan Carpenter, Gao Xiang, linux-xfs
On Tue, May 21, 2024 at 07:45:53PM GMT, Darrick J. Wong wrote:
> Hi all,
>
> Synchronize libxfs with the kernel.
>
> If you're going to start using this code, I strongly recommend pulling
> from my git trees, which are linked below.
>
> This has been running on the djcloud for months with no problems. Enjoy!
> Comments and questions are, as always, welcome.
The sync looks good, thanks for doing that Darrick.
You can add:
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
>
> xfsprogs git tree:
> https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=libxfs-sync-6.9
> ---
> Commits in this patchset:
> * xfs: convert kmem_zalloc() to kzalloc()
> * xfs: convert kmem_alloc() to kmalloc()
> * xfs: convert remaining kmem_free() to kfree()
> * xfs: use __GFP_NOLOCKDEP instead of GFP_NOFS
> * xfs: use GFP_KERNEL in pure transaction contexts
> * xfs: clean up remaining GFP_NOFS users
> * xfs: use xfs_defer_alloc a bit more
> * xfs: Replace xfs_isilocked with xfs_assert_ilocked
> * xfs: create a static name for the dot entry too
> * xfs: create a predicate to determine if two xfs_names are the same
> * xfs: create a macro for decoding ftypes in tracepoints
> * xfs: report the health of quota counts
> * xfs: implement live quotacheck inode scan
> * xfs: report health of inode link counts
> * xfs: teach scrub to check file nlinks
> * xfs: separate the marking of sick and checked metadata
> * xfs: report fs corruption errors to the health tracking system
> * xfs: report ag header corruption errors to the health tracking system
> * xfs: report block map corruption errors to the health tracking system
> * xfs: report btree block corruption errors to the health system
> * xfs: report dir/attr block corruption errors to the health system
> * xfs: report inode corruption errors to the health system
> * xfs: report realtime metadata corruption errors to the health system
> * xfs: report XFS_IS_CORRUPT errors to the health system
> * xfs: add secondary and indirect classes to the health tracking system
> * xfs: remember sick inodes that get inactivated
> * xfs: update health status if we get a clean bill of health
> * xfs: consolidate btree block freeing tracepoints
> * xfs: consolidate btree block allocation tracepoints
> * xfs: set the btree cursor bc_ops in xfs_btree_alloc_cursor
> * xfs: drop XFS_BTREE_CRC_BLOCKS
> * xfs: encode the btree geometry flags in the btree ops structure
> * xfs: remove bc_ino.flags
> * xfs: consolidate the xfs_alloc_lookup_* helpers
> * xfs: turn the allocbt cursor active field into a btree flag
> * xfs: extern some btree ops structures
> * xfs: initialize btree blocks using btree_ops structure
> * xfs: rename btree block/buffer init functions
> * xfs: btree convert xfs_btree_init_block to xfs_btree_init_buf calls
> * xfs: remove the unnecessary daddr paramter to _init_block
> * xfs: set btree block buffer ops in _init_buf
> * xfs: move lru refs to the btree ops structure
> * xfs: move the btree stats offset into struct btree_ops
> * xfs: factor out a xfs_btree_owner helper
> * xfs: factor out a btree block owner check
> * xfs: store the btree pointer length in struct xfs_btree_ops
> * xfs: split out a btree type from the btree ops geometry flags
> * xfs: split the per-btree union in struct xfs_btree_cur
> * xfs: create predicate to determine if cursor is at inode root level
> * xfs: move comment about two 2 keys per pointer in the rmap btree
> * xfs: add a xfs_btree_init_ptr_from_cur
> * xfs: don't override bc_ops for staging btrees
> * xfs: fold xfs_allocbt_init_common into xfs_allocbt_init_cursor
> * xfs: remove xfs_allocbt_stage_cursor
> * xfs: fold xfs_inobt_init_common into xfs_inobt_init_cursor
> * xfs: remove xfs_inobt_stage_cursor
> * xfs: fold xfs_refcountbt_init_common into xfs_refcountbt_init_cursor
> * xfs: remove xfs_refcountbt_stage_cursor
> * xfs: fold xfs_rmapbt_init_common into xfs_rmapbt_init_cursor
> * xfs: remove xfs_rmapbt_stage_cursor
> * xfs: make full use of xfs_btree_stage_ifakeroot in xfs_bmbt_stage_cursor
> * xfs: make staging file forks explicit
> * xfs: fold xfs_bmbt_init_common into xfs_bmbt_init_cursor
> * xfs: remove xfs_bmbt_stage_cursor
> * xfs: split the agf_roots and agf_levels arrays
> * xfs: add a name field to struct xfs_btree_ops
> * xfs: add a sick_mask to struct xfs_btree_ops
> * xfs: split xfs_allocbt_init_cursor
> * xfs: remove xfs_inobt_cur
> * xfs: remove the btnum argument to xfs_inobt_count_blocks
> * xfs: split xfs_inobt_insert_sprec
> * xfs: split xfs_inobt_init_cursor
> * xfs: pass a 'bool is_finobt' to xfs_inobt_insert
> * xfs: remove xfs_btnum_t
> * xfs: simplify xfs_btree_check_sblock_siblings
> * xfs: simplify xfs_btree_check_lblock_siblings
> * xfs: open code xfs_btree_check_lptr in xfs_bmap_btree_to_extents
> * xfs: consolidate btree ptr checking
> * xfs: misc cleanups for __xfs_btree_check_sblock
> * xfs: remove the crc variable in __xfs_btree_check_lblock
> * xfs: tighten up validation of root block in inode forks
> * xfs: consolidate btree block verification
> * xfs: rename btree helpers that depends on the block number representation
> * xfs: factor out a __xfs_btree_check_lblock_hdr helper
> * xfs: remove xfs_btree_reada_bufl
> * xfs: remove xfs_btree_reada_bufs
> * xfs: move and rename xfs_btree_read_bufl
> * libxfs: teach buftargs to maintain their own buffer hashtable
> * libxfs: add xfile support
> * libxfs: partition memfd files to avoid using too many fds
> * xfs: teach buftargs to maintain their own buffer hashtable
> * libxfs: support in-memory buffer cache targets
> * xfs: add a xfs_btree_ptrs_equal helper
> * xfs: support in-memory btrees
> * xfs: launder in-memory btree buffers before transaction commit
> * xfs: create a helper to decide if a file mapping targets the rt volume
> * xfs: repair the rmapbt
> * xfs: create a shadow rmap btree during rmap repair
> * xfs: hook live rmap operations during a repair operation
> * xfs: clean up bmap log intent item tracepoint callsites
> * xfs: move xfs_bmap_defer_add to xfs_bmap_item.c
> * xfs: fix xfs_bunmapi to allow unmapping of partial rt extents
> * xfs: add a realtime flag to the bmap update log redo items
> * xfs: support deferred bmap updates on the attr fork
> * xfs: xfs_bmap_finish_one should map unwritten extents properly
> * xfs: move xfs_symlink_remote.c declarations to xfs_symlink_remote.h
> * xfs: move remote symlink target read function to libxfs
> * xfs: move symlink target write function to libxfs
> * xfs: xfs_btree_bload_prep_block() should use __GFP_NOFAIL
> * xfs: shrink failure needs to hold AGI buffer
> * xfs: allow sunit mount option to repair bad primary sb stripe values
> ---
> copy/xfs_copy.c | 4
> db/agf.c | 28 -
> db/bmap_inflate.c | 8
> db/check.c | 14 -
> db/freesp.c | 8
> db/metadump.c | 12
> include/kmem.h | 5
> include/libxfs.h | 4
> include/xfs_mount.h | 5
> include/xfs_trace.h | 17 -
> include/xfs_trans.h | 1
> libxfs/Makefile | 9
> libxfs/buf_mem.c | 313 ++++++++++++
> libxfs/buf_mem.h | 30 +
> libxfs/defer_item.c | 15 +
> libxfs/defer_item.h | 13 +
> libxfs/init.c | 52 +-
> libxfs/libxfs_api_defs.h | 10
> libxfs/libxfs_io.h | 42 +-
> libxfs/libxfs_priv.h | 19 -
> libxfs/logitem.c | 2
> libxfs/rdwr.c | 86 ++-
> libxfs/trans.c | 40 ++
> libxfs/util.c | 10
> libxfs/xfile.c | 393 +++++++++++++++
> libxfs/xfile.h | 34 +
> libxfs/xfs_ag.c | 79 ++-
> libxfs/xfs_ag.h | 18 -
> libxfs/xfs_alloc.c | 258 ++++++----
> libxfs/xfs_alloc_btree.c | 191 ++++---
> libxfs/xfs_alloc_btree.h | 10
> libxfs/xfs_attr.c | 5
> libxfs/xfs_attr_leaf.c | 22 +
> libxfs/xfs_attr_remote.c | 37 +
> libxfs/xfs_bmap.c | 365 ++++++++++----
> libxfs/xfs_bmap.h | 19 +
> libxfs/xfs_bmap_btree.c | 152 ++----
> libxfs/xfs_bmap_btree.h | 5
> libxfs/xfs_btree.c | 1097 ++++++++++++++++++++++++++-----------------
> libxfs/xfs_btree.h | 274 +++++------
> libxfs/xfs_btree_mem.c | 346 ++++++++++++++
> libxfs/xfs_btree_mem.h | 75 +++
> libxfs/xfs_btree_staging.c | 133 +----
> libxfs/xfs_btree_staging.h | 10
> libxfs/xfs_da_btree.c | 59 ++
> libxfs/xfs_da_format.h | 11
> libxfs/xfs_defer.c | 25 -
> libxfs/xfs_dir2.c | 59 +-
> libxfs/xfs_dir2.h | 13 +
> libxfs/xfs_dir2_block.c | 8
> libxfs/xfs_dir2_data.c | 3
> libxfs/xfs_dir2_leaf.c | 3
> libxfs/xfs_dir2_node.c | 7
> libxfs/xfs_dir2_sf.c | 16 -
> libxfs/xfs_format.h | 21 -
> libxfs/xfs_fs.h | 8
> libxfs/xfs_health.h | 95 ++++
> libxfs/xfs_ialloc.c | 232 ++++++---
> libxfs/xfs_ialloc_btree.c | 173 +++----
> libxfs/xfs_ialloc_btree.h | 11
> libxfs/xfs_iext_tree.c | 26 +
> libxfs/xfs_inode_buf.c | 12
> libxfs/xfs_inode_fork.c | 49 +-
> libxfs/xfs_inode_fork.h | 1
> libxfs/xfs_log_format.h | 4
> libxfs/xfs_refcount.c | 69 ++-
> libxfs/xfs_refcount_btree.c | 78 +--
> libxfs/xfs_refcount_btree.h | 2
> libxfs/xfs_rmap.c | 284 +++++++++--
> libxfs/xfs_rmap.h | 31 +
> libxfs/xfs_rmap_btree.c | 240 +++++++--
> libxfs/xfs_rmap_btree.h | 8
> libxfs/xfs_rtbitmap.c | 11
> libxfs/xfs_sb.c | 42 +-
> libxfs/xfs_sb.h | 5
> libxfs/xfs_shared.h | 67 ++-
> libxfs/xfs_symlink_remote.c | 155 ++++++
> libxfs/xfs_symlink_remote.h | 26 +
> libxfs/xfs_trans_inode.c | 6
> libxfs/xfs_types.h | 26 -
> logprint/log_misc.c | 8
> logprint/log_print_all.c | 8
> mkfs/xfs_mkfs.c | 8
> repair/agbtree.c | 28 +
> repair/bmap_repair.c | 4
> repair/bulkload.c | 2
> repair/phase5.c | 28 +
> repair/phase6.c | 4
> repair/prefetch.c | 12
> repair/prefetch.h | 1
> repair/progress.c | 14 -
> repair/progress.h | 2
> repair/scan.c | 18 -
> repair/xfs_repair.c | 47 +-
> 94 files changed, 4425 insertions(+), 1915 deletions(-)
> create mode 100644 libxfs/buf_mem.c
> create mode 100644 libxfs/buf_mem.h
> create mode 100644 libxfs/defer_item.h
> create mode 100644 libxfs/xfile.c
> create mode 100644 libxfs/xfile.h
> create mode 100644 libxfs/xfs_btree_mem.c
> create mode 100644 libxfs/xfs_btree_mem.h
> create mode 100644 libxfs/xfs_symlink_remote.h
>
>
^ permalink raw reply [flat|nested] 154+ messages in thread* Re: [PATCHSET v30.4 02/10] libxfs: sync with 6.9
2024-06-03 12:29 ` [PATCHSET v30.4 02/10] libxfs: sync with 6.9 Carlos Maiolino
@ 2024-06-03 20:22 ` Darrick J. Wong
0 siblings, 0 replies; 154+ messages in thread
From: Darrick J. Wong @ 2024-06-03 20:22 UTC (permalink / raw)
To: Carlos Maiolino
Cc: Christoph Hellwig, Chandan Babu R, Matthew Wilcox (Oracle),
Dave Chinner, Dan Carpenter, Gao Xiang, linux-xfs
On Mon, Jun 03, 2024 at 02:29:14PM +0200, Carlos Maiolino wrote:
> On Tue, May 21, 2024 at 07:45:53PM GMT, Darrick J. Wong wrote:
> > Hi all,
> >
> > Synchronize libxfs with the kernel.
> >
> > If you're going to start using this code, I strongly recommend pulling
> > from my git trees, which are linked below.
> >
> > This has been running on the djcloud for months with no problems. Enjoy!
> > Comments and questions are, as always, welcome.
>
> The sync looks good, thanks for doing that Darrick.
>
> You can add:
>
> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Thanks! Final patch submission and pull requests imminent.
--D
> >
> > xfsprogs git tree:
> > https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=libxfs-sync-6.9
> > ---
> > Commits in this patchset:
> > * xfs: convert kmem_zalloc() to kzalloc()
> > * xfs: convert kmem_alloc() to kmalloc()
> > * xfs: convert remaining kmem_free() to kfree()
> > * xfs: use __GFP_NOLOCKDEP instead of GFP_NOFS
> > * xfs: use GFP_KERNEL in pure transaction contexts
> > * xfs: clean up remaining GFP_NOFS users
> > * xfs: use xfs_defer_alloc a bit more
> > * xfs: Replace xfs_isilocked with xfs_assert_ilocked
> > * xfs: create a static name for the dot entry too
> > * xfs: create a predicate to determine if two xfs_names are the same
> > * xfs: create a macro for decoding ftypes in tracepoints
> > * xfs: report the health of quota counts
> > * xfs: implement live quotacheck inode scan
> > * xfs: report health of inode link counts
> > * xfs: teach scrub to check file nlinks
> > * xfs: separate the marking of sick and checked metadata
> > * xfs: report fs corruption errors to the health tracking system
> > * xfs: report ag header corruption errors to the health tracking system
> > * xfs: report block map corruption errors to the health tracking system
> > * xfs: report btree block corruption errors to the health system
> > * xfs: report dir/attr block corruption errors to the health system
> > * xfs: report inode corruption errors to the health system
> > * xfs: report realtime metadata corruption errors to the health system
> > * xfs: report XFS_IS_CORRUPT errors to the health system
> > * xfs: add secondary and indirect classes to the health tracking system
> > * xfs: remember sick inodes that get inactivated
> > * xfs: update health status if we get a clean bill of health
> > * xfs: consolidate btree block freeing tracepoints
> > * xfs: consolidate btree block allocation tracepoints
> > * xfs: set the btree cursor bc_ops in xfs_btree_alloc_cursor
> > * xfs: drop XFS_BTREE_CRC_BLOCKS
> > * xfs: encode the btree geometry flags in the btree ops structure
> > * xfs: remove bc_ino.flags
> > * xfs: consolidate the xfs_alloc_lookup_* helpers
> > * xfs: turn the allocbt cursor active field into a btree flag
> > * xfs: extern some btree ops structures
> > * xfs: initialize btree blocks using btree_ops structure
> > * xfs: rename btree block/buffer init functions
> > * xfs: btree convert xfs_btree_init_block to xfs_btree_init_buf calls
> > * xfs: remove the unnecessary daddr paramter to _init_block
> > * xfs: set btree block buffer ops in _init_buf
> > * xfs: move lru refs to the btree ops structure
> > * xfs: move the btree stats offset into struct btree_ops
> > * xfs: factor out a xfs_btree_owner helper
> > * xfs: factor out a btree block owner check
> > * xfs: store the btree pointer length in struct xfs_btree_ops
> > * xfs: split out a btree type from the btree ops geometry flags
> > * xfs: split the per-btree union in struct xfs_btree_cur
> > * xfs: create predicate to determine if cursor is at inode root level
> > * xfs: move comment about two 2 keys per pointer in the rmap btree
> > * xfs: add a xfs_btree_init_ptr_from_cur
> > * xfs: don't override bc_ops for staging btrees
> > * xfs: fold xfs_allocbt_init_common into xfs_allocbt_init_cursor
> > * xfs: remove xfs_allocbt_stage_cursor
> > * xfs: fold xfs_inobt_init_common into xfs_inobt_init_cursor
> > * xfs: remove xfs_inobt_stage_cursor
> > * xfs: fold xfs_refcountbt_init_common into xfs_refcountbt_init_cursor
> > * xfs: remove xfs_refcountbt_stage_cursor
> > * xfs: fold xfs_rmapbt_init_common into xfs_rmapbt_init_cursor
> > * xfs: remove xfs_rmapbt_stage_cursor
> > * xfs: make full use of xfs_btree_stage_ifakeroot in xfs_bmbt_stage_cursor
> > * xfs: make staging file forks explicit
> > * xfs: fold xfs_bmbt_init_common into xfs_bmbt_init_cursor
> > * xfs: remove xfs_bmbt_stage_cursor
> > * xfs: split the agf_roots and agf_levels arrays
> > * xfs: add a name field to struct xfs_btree_ops
> > * xfs: add a sick_mask to struct xfs_btree_ops
> > * xfs: split xfs_allocbt_init_cursor
> > * xfs: remove xfs_inobt_cur
> > * xfs: remove the btnum argument to xfs_inobt_count_blocks
> > * xfs: split xfs_inobt_insert_sprec
> > * xfs: split xfs_inobt_init_cursor
> > * xfs: pass a 'bool is_finobt' to xfs_inobt_insert
> > * xfs: remove xfs_btnum_t
> > * xfs: simplify xfs_btree_check_sblock_siblings
> > * xfs: simplify xfs_btree_check_lblock_siblings
> > * xfs: open code xfs_btree_check_lptr in xfs_bmap_btree_to_extents
> > * xfs: consolidate btree ptr checking
> > * xfs: misc cleanups for __xfs_btree_check_sblock
> > * xfs: remove the crc variable in __xfs_btree_check_lblock
> > * xfs: tighten up validation of root block in inode forks
> > * xfs: consolidate btree block verification
> > * xfs: rename btree helpers that depends on the block number representation
> > * xfs: factor out a __xfs_btree_check_lblock_hdr helper
> > * xfs: remove xfs_btree_reada_bufl
> > * xfs: remove xfs_btree_reada_bufs
> > * xfs: move and rename xfs_btree_read_bufl
> > * libxfs: teach buftargs to maintain their own buffer hashtable
> > * libxfs: add xfile support
> > * libxfs: partition memfd files to avoid using too many fds
> > * xfs: teach buftargs to maintain their own buffer hashtable
> > * libxfs: support in-memory buffer cache targets
> > * xfs: add a xfs_btree_ptrs_equal helper
> > * xfs: support in-memory btrees
> > * xfs: launder in-memory btree buffers before transaction commit
> > * xfs: create a helper to decide if a file mapping targets the rt volume
> > * xfs: repair the rmapbt
> > * xfs: create a shadow rmap btree during rmap repair
> > * xfs: hook live rmap operations during a repair operation
> > * xfs: clean up bmap log intent item tracepoint callsites
> > * xfs: move xfs_bmap_defer_add to xfs_bmap_item.c
> > * xfs: fix xfs_bunmapi to allow unmapping of partial rt extents
> > * xfs: add a realtime flag to the bmap update log redo items
> > * xfs: support deferred bmap updates on the attr fork
> > * xfs: xfs_bmap_finish_one should map unwritten extents properly
> > * xfs: move xfs_symlink_remote.c declarations to xfs_symlink_remote.h
> > * xfs: move remote symlink target read function to libxfs
> > * xfs: move symlink target write function to libxfs
> > * xfs: xfs_btree_bload_prep_block() should use __GFP_NOFAIL
> > * xfs: shrink failure needs to hold AGI buffer
> > * xfs: allow sunit mount option to repair bad primary sb stripe values
> > ---
> > copy/xfs_copy.c | 4
> > db/agf.c | 28 -
> > db/bmap_inflate.c | 8
> > db/check.c | 14 -
> > db/freesp.c | 8
> > db/metadump.c | 12
> > include/kmem.h | 5
> > include/libxfs.h | 4
> > include/xfs_mount.h | 5
> > include/xfs_trace.h | 17 -
> > include/xfs_trans.h | 1
> > libxfs/Makefile | 9
> > libxfs/buf_mem.c | 313 ++++++++++++
> > libxfs/buf_mem.h | 30 +
> > libxfs/defer_item.c | 15 +
> > libxfs/defer_item.h | 13 +
> > libxfs/init.c | 52 +-
> > libxfs/libxfs_api_defs.h | 10
> > libxfs/libxfs_io.h | 42 +-
> > libxfs/libxfs_priv.h | 19 -
> > libxfs/logitem.c | 2
> > libxfs/rdwr.c | 86 ++-
> > libxfs/trans.c | 40 ++
> > libxfs/util.c | 10
> > libxfs/xfile.c | 393 +++++++++++++++
> > libxfs/xfile.h | 34 +
> > libxfs/xfs_ag.c | 79 ++-
> > libxfs/xfs_ag.h | 18 -
> > libxfs/xfs_alloc.c | 258 ++++++----
> > libxfs/xfs_alloc_btree.c | 191 ++++---
> > libxfs/xfs_alloc_btree.h | 10
> > libxfs/xfs_attr.c | 5
> > libxfs/xfs_attr_leaf.c | 22 +
> > libxfs/xfs_attr_remote.c | 37 +
> > libxfs/xfs_bmap.c | 365 ++++++++++----
> > libxfs/xfs_bmap.h | 19 +
> > libxfs/xfs_bmap_btree.c | 152 ++----
> > libxfs/xfs_bmap_btree.h | 5
> > libxfs/xfs_btree.c | 1097 ++++++++++++++++++++++++++-----------------
> > libxfs/xfs_btree.h | 274 +++++------
> > libxfs/xfs_btree_mem.c | 346 ++++++++++++++
> > libxfs/xfs_btree_mem.h | 75 +++
> > libxfs/xfs_btree_staging.c | 133 +----
> > libxfs/xfs_btree_staging.h | 10
> > libxfs/xfs_da_btree.c | 59 ++
> > libxfs/xfs_da_format.h | 11
> > libxfs/xfs_defer.c | 25 -
> > libxfs/xfs_dir2.c | 59 +-
> > libxfs/xfs_dir2.h | 13 +
> > libxfs/xfs_dir2_block.c | 8
> > libxfs/xfs_dir2_data.c | 3
> > libxfs/xfs_dir2_leaf.c | 3
> > libxfs/xfs_dir2_node.c | 7
> > libxfs/xfs_dir2_sf.c | 16 -
> > libxfs/xfs_format.h | 21 -
> > libxfs/xfs_fs.h | 8
> > libxfs/xfs_health.h | 95 ++++
> > libxfs/xfs_ialloc.c | 232 ++++++---
> > libxfs/xfs_ialloc_btree.c | 173 +++----
> > libxfs/xfs_ialloc_btree.h | 11
> > libxfs/xfs_iext_tree.c | 26 +
> > libxfs/xfs_inode_buf.c | 12
> > libxfs/xfs_inode_fork.c | 49 +-
> > libxfs/xfs_inode_fork.h | 1
> > libxfs/xfs_log_format.h | 4
> > libxfs/xfs_refcount.c | 69 ++-
> > libxfs/xfs_refcount_btree.c | 78 +--
> > libxfs/xfs_refcount_btree.h | 2
> > libxfs/xfs_rmap.c | 284 +++++++++--
> > libxfs/xfs_rmap.h | 31 +
> > libxfs/xfs_rmap_btree.c | 240 +++++++--
> > libxfs/xfs_rmap_btree.h | 8
> > libxfs/xfs_rtbitmap.c | 11
> > libxfs/xfs_sb.c | 42 +-
> > libxfs/xfs_sb.h | 5
> > libxfs/xfs_shared.h | 67 ++-
> > libxfs/xfs_symlink_remote.c | 155 ++++++
> > libxfs/xfs_symlink_remote.h | 26 +
> > libxfs/xfs_trans_inode.c | 6
> > libxfs/xfs_types.h | 26 -
> > logprint/log_misc.c | 8
> > logprint/log_print_all.c | 8
> > mkfs/xfs_mkfs.c | 8
> > repair/agbtree.c | 28 +
> > repair/bmap_repair.c | 4
> > repair/bulkload.c | 2
> > repair/phase5.c | 28 +
> > repair/phase6.c | 4
> > repair/prefetch.c | 12
> > repair/prefetch.h | 1
> > repair/progress.c | 14 -
> > repair/progress.h | 2
> > repair/scan.c | 18 -
> > repair/xfs_repair.c | 47 +-
> > 94 files changed, 4425 insertions(+), 1915 deletions(-)
> > create mode 100644 libxfs/buf_mem.c
> > create mode 100644 libxfs/buf_mem.h
> > create mode 100644 libxfs/defer_item.h
> > create mode 100644 libxfs/xfile.c
> > create mode 100644 libxfs/xfile.h
> > create mode 100644 libxfs/xfs_btree_mem.c
> > create mode 100644 libxfs/xfs_btree_mem.h
> > create mode 100644 libxfs/xfs_symlink_remote.h
> >
> >
^ permalink raw reply [flat|nested] 154+ messages in thread