MCPcopy Create free account
hub / github.com/MemNixFS/MemNixFS / walk_xarray

Function walk_xarray

src/os/linux/pagecache.cpp:360–394  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

358};
359
360void walk_xarray(const Engine& eng, const Offsets& o,
361 VAddr entry, u64 base_index,
362 std::vector<CachedPage>& out, int depth, std::size_t& budget)
363{
364 if (entry == 0 || depth > 16) return;
365 // Total-node budget: a depth cap alone doesn't stop a CRAFTED xarray whose
366 // node slots form a cycle / DAG — with 64-way fanout that re-visits a few
367 // nodes ~64^depth times (effective hang). The budget bounds total visits.
368 if (budget == 0) return;
369 --budget;
370 if (xa_is_value(entry)) return; // not a pointer entry
371
372 if (!xa_is_internal(entry)) {
373 // Leaf — folio*.
374 // For leaves at the root of a small tree, base_index is the slot
375 // index from the parent. Caller does base_index assembly.
376 out.push_back({ base_index, entry });
377 return;
378 }
379
380 VAddr node_va = xa_to_node(entry);
381 u8 shift = 0;
382 if (!kva_read_pod(eng, node_va + o.xn_shift, shift)) return;
383
384 constexpr u64 kSlots = 64;
385 std::vector<VAddr> slots(kSlots, 0);
386 if (!kva_read(eng, node_va + o.xn_slots, slots.data(),
387 kSlots * sizeof(VAddr))) return;
388
389 for (u64 i = 0; i < kSlots; ++i) {
390 if (slots[i] == 0) continue;
391 u64 child_base = base_index | (i << shift);
392 walk_xarray(eng, o, slots[i], child_base, out, depth + 1, budget);
393 }
394}
395
396std::vector<CachedPage>
397collect_cached_pages(const Engine& eng, const Offsets& o, VAddr inode_va)

Callers 1

collect_cached_pagesFunction · 0.70

Calls 5

kva_read_podFunction · 0.85
kva_readFunction · 0.85
xa_is_valueFunction · 0.70
xa_is_internalFunction · 0.70
xa_to_nodeFunction · 0.70

Tested by

no test coverage detected