On Mon, May 18, 2026 at 03:00:25PM +0800, Huang Shijie wrote:
On Mon, May 18, 2026 at 02:44:10PM +1200, Tao Liu wrote:
> Hi Huang,
>
> I made some modification upon your v7, could you please check if this
> works for you?
I test this code, it does not work.
I met the error log like this:
-------------------------------------------
crash> files -p ffff8de2bbc36f38
INODE NRPAGES
ffff8de2bbc36f38 103356
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
fffffa7284983ac0 61260eb000 ffff8de2bbc370a8 0 1 197ffffc000092c
referenced,uptodate,lru,active,owner_2
fffffa7284983b00 61260ec000 ffff8de2bbc370a8 1 1 197ffffc000092c
referenced,uptodate,lru,active,owner_2
fffffa7284983b40 61260ed000 ffff8de2bbc370a8 2 1 197ffffc000092c
referenced,uptodate,lru,active,owner_2
fffffa7284983b80 61260ee000 ffff8de2bbc370a8 3 1 197ffffc000092c
referenced,uptodate,lru,active,owner_2
fffffa728382e000 60e0b80000 ffff8de2bbc370a8 4 4 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa728382e100 60e0b84000 ffff8de2bbc370a8 8 4 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa728382e200 60e0b88000 ffff8de2bbc370a8 c 4 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa728382e300 60e0b8c000 ffff8de2bbc370a8 10 4 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa728382e400 60e0b90000 ffff8de2bbc370a8 14 4 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa7282ffd200 60bff48000 ffff8de2bbc370a8 18 8 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa7283a1a000 60e8680000 ffff8de2bbc370a8 20 16 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa7283a1a400 60e8690000 ffff8de2bbc370a8 30 16 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa7283d8b800 60f62e0000 ffff8de2bbc370a8 40 16 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa7283d8bc00 60f62f0000 ffff8de2bbc370a8 50 16 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa72839fe000 60e7f80000 ffff8de2bbc370a8 60 32 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
fffffa7283598000 60d6600000 ffff8de2bbc370a8 80 64 197ffffc000096c
referenced,uptodate,lru,active,owner_2,head
files: invalid kernel virtual address: 40ffffffff type: "folio.page.flags"
crash>
-------------------------------------------
Thanks for the feedback.
>
> I guess this will make folio_xarray_update_off() cleaner, and
> less-code-change on do_xarray_iter().
>
> Thanks,
> Tao Liu
>
> diff --git a/filesys.c b/filesys.c
> index fc672ad..2f2e872 100644
> --- a/filesys.c
> +++ b/filesys.c
> @@ -4277,22 +4277,22 @@ folio_update_count(ulong slot)
> }
>
> static uint folio_xarray_update_off(ulong node, uint height, char *path, ulong
index,
> - ulong slot, uint off, ulong shift, struct xarray_ops *ops)
> + ulong slot, uint off, ulong shift, struct xarray_ops
*ops)
> {
> - uint order;
> -
> - if (height > 1) {
> - if ((slot & XARRAY_TAG_MASK) == 0) {
> - ops->entry(node, slot, path, index | off,
ops->private);
> - order = folio_order(slot) % XA_CHUNK_SHIFT;
> - return 1 << order;
> - }
> - return 0;
> - }
> -
> - /* The height == 1 */
> - order = folio_order(slot) % XA_CHUNK_SHIFT;
> - return 1 << order;
> + uint order;
> +
> + if (height == 1) {
> + order = folio_order(slot) % XA_CHUNK_SHIFT;
> + return 1 << order;
> + }
> +
> + if ((slot & XARRAY_TAG_MASK) == 0) {
> + ops->entry(node, slot, path, index | off, ops->private);
> + order = folio_order(slot) % XA_CHUNK_SHIFT;
> + return 1 << order;
> + }
> +
> + return 1;
> }
>
> static void do_xarray_count(ulong node, ulong slot, const char *path,
> diff --git a/tools.c b/tools.c
> index 0302cec..4558e58 100644
> --- a/tools.c
> +++ b/tools.c
> @@ -4755,21 +4755,16 @@ do_xarray_iter(ulong node, uint height, char *path,
> if (!slot)
> continue;
>
> + if (ops->update_off)
> + update_off = ops->update_off(node, height, path, index,
> + slot, off, shift, ops);
> +
The issue is here:
If the "height > 1" and we meet a large folio, we should not do the
do_xarray_iter()
later.
I created a patch based on your code:
---
filesys.c | 2 +-
tools.c | 8 +++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/filesys.c b/filesys.c
index a361596..de3cdf4 100644
--- a/filesys.c
+++ b/filesys.c
@@ -4292,7 +4292,7 @@ static uint folio_xarray_update_off(ulong node, uint height, char
*path, ulong i
return 1 << order;
}
- return 1;
+ return 0;
}
static void do_xarray_count(ulong node, ulong slot, const char *path,
diff --git a/tools.c b/tools.c
index b3650c0..fc55c99 100644
--- a/tools.c
+++ b/tools.c
@@ -4755,9 +4755,15 @@ do_xarray_iter(ulong node, uint height, char *path,
if (!slot)
continue;
- if (ops->update_off)
+ if (ops->update_off) {
update_off = ops->update_off(node, height, path, index,
slot, off, shift, ops);
+ if (height > 1) {
+ if (update_off)
+ continue;
+ update_off = 1;
+ }
+ }
Sorry to be picky, I still think the height > 1 and continue thing is folio's
stuff.
Please checkout my updated modification on your v7.
if ((slot & XARRAY_TAG_MASK) == XARRAY_TAG_INTERNAL) {
slot &= ~XARRAY_TAG_INTERNAL;
--
If you think it is okay, I can create a formal patch.
Thanks
Huang Shijie
> if ((slot & XARRAY_TAG_MASK) == XARRAY_TAG_INTERNAL) {
> slot &= ~XARRAY_TAG_INTERNAL;
> - } else if (ops->update_off && height > 1) {
> - update_off = ops->update_off(node, height, path, index,
> - slot, off, shift, ops);
> - if (update_off)
> - continue;
> - update_off = 1;
> }
>
> if (height == 1) {
> ops->entry(node, slot, path, index | off,
ops->private);
> - if (ops->update_off)
> - update_off = ops->update_off(node, height, path,
index,
> - slot, off, shift,
ops);
> } else {
> ulong child_index = index | (off << shift);
> char child_path[BUFSIZE];
>
>
diff --git a/defs.h b/defs.h
index 52f8ce9..ccc2d93 100644
--- a/defs.h
+++ b/defs.h
@@ -5690,7 +5690,8 @@ struct xarray_ops {
void (*entry)(ulong node, ulong slot, const char *path,
ulong index, void *private);
uint (*update_off)(ulong node, uint height, char *path, ulong index,
- ulong slot, uint off, ulong shift, struct xarray_ops *ops);
+ ulong slot, uint off, ulong shift, struct xarray_ops *ops,
+ bool *should_continue);
uint radix;
void *private;
};
diff --git a/filesys.c b/filesys.c
index fc672ad..8a073e0 100644
--- a/filesys.c
+++ b/filesys.c
@@ -4277,22 +4277,25 @@ folio_update_count(ulong slot)
}
static uint folio_xarray_update_off(ulong node, uint height, char *path, ulong index,
- ulong slot, uint off, ulong shift, struct xarray_ops *ops)
+ ulong slot, uint off, ulong shift, struct xarray_ops
*ops,
+ bool *should_continue)
{
- uint order;
-
- if (height > 1) {
- if ((slot & XARRAY_TAG_MASK) == 0) {
- ops->entry(node, slot, path, index | off, ops->private);
- order = folio_order(slot) % XA_CHUNK_SHIFT;
- return 1 << order;
- }
- return 0;
- }
-
- /* The height == 1 */
- order = folio_order(slot) % XA_CHUNK_SHIFT;
- return 1 << order;
+ uint order;
+
+ if (height == 1) {
+ order = folio_order(slot) % XA_CHUNK_SHIFT;
+ return 1 << order;
+ }
+
+ if ((slot & XARRAY_TAG_MASK) == 0) {
+ if (height > 1)
+ *should_continue = true;
+ ops->entry(node, slot, path, index | off, ops->private);
+ order = folio_order(slot) % XA_CHUNK_SHIFT;
+ return 1 << order;
+ }
+
+ return 1;
}
static void do_xarray_count(ulong node, ulong slot, const char *path,
diff --git a/tools.c b/tools.c
index 0302cec..3729648 100644
--- a/tools.c
+++ b/tools.c
@@ -4738,6 +4738,7 @@ do_xarray_iter(ulong node, uint height, char *path,
{
uint off;
uint update_off;
+ bool should_continue;
if (!hq_enter(node))
error(FATAL,
@@ -4748,6 +4749,7 @@ do_xarray_iter(ulong node, uint height, char *path,
if (!slot)
continue;
- if ((slot & XARRAY_TAG_MASK) == XARRAY_TAG_INTERNAL) {
- slot &= ~XARRAY_TAG_INTERNAL;
- } else if (ops->update_off && height > 1) {
+ if (ops->update_off) {
update_off = ops->update_off(node, height, path, index,
- slot, off, shift, ops);
- if (update_off)
+ slot, off, shift, ops, &should_continue);
+ if (should_continue)
continue;
- update_off = 1;
+ }
+
+ if ((slot & XARRAY_TAG_MASK) == XARRAY_TAG_INTERNAL) {
+ slot &= ~XARRAY_TAG_INTERNAL;
}
if (height == 1) {
ops->entry(node, slot, path, index | off, ops->private);
- if (ops->update_off)
- update_off = ops->update_off(node, height, path,
index,
- slot, off, shift, ops);
} else {
ulong child_index = index | (off << shift);
char child_path[BUFSIZE];