Skip to content

feat: replace ext4 driver ext4_rs with ext4plus - #42

Merged
muou000 merged 37 commits into
mainfrom
feat-replace-ext4_rs-with
Jun 27, 2026
Merged

feat: replace ext4 driver ext4_rs with ext4plus#42
muou000 merged 37 commits into
mainfrom
feat-replace-ext4_rs-with

Conversation

@muou000

@muou000 muou000 commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • 基于新版 ext4 实现增强文件系统能力:目录遍历与查找、符号链接、扩展属性(xattr)与路径解析更完善,支持目录校验与 htree 相关能力。
  • Bug Fixes
    • 优化刷新与删除流程:减少锁占用,完善失败处理与延迟删除,提升块缓存读写一致性;同步修正 tmpfs 的 unlink/rename 语义与目录非空校验,并改进共享文件缓存失效。
  • Chores
    • 调整构建与依赖:切换底层 ext4 实现,清理旧实现与 workspace 配置,并更新 ext4 镜像格式化参数(禁用 journal/metadata checksum)。

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

新增 ext4plus crate 并将 axfs 的 ext4 后端切换到它;同时实现新的同步原语、块/目录/journal 路径、Ext4 核心 API、测试支撑,以及 axmm、futex、挂载状态和日志调整。

ext4plus 文件系统栈重建

Layer / File(s) Summary
crate 表面与基础契约
crates/ext4plus/Cargo.toml, crates/ext4plus/LICENSE-APACHE, crates/ext4plus/LICENSE-MIT, crates/ext4plus/README.md, crates/ext4plus/.cargo_vcs_info.json, crates/ext4plus/src/{lib.rs,prelude.rs,error.rs,sync.rs,reader.rs,writer.rs,mem_io_error.rs,path.rs,label.rs,uuid.rs,metadata.rs,features.rs,util.rs,block_index.rs,block_size.rs,checksum.rs}
新增 crate 元数据、公共错误与同步契约、读写接口、路径/标签/UUID/元数据/特性位和基础工具类型。
超级块、块组、extent、位图与 journal
crates/ext4plus/src/{superblock.rs,block_group.rs,extent.rs,bitmap.rs,mmp.rs,journal/*}
实现超级块、块组描述符、extent、位图、MMP 与 journal 的解析、序列化、校验和块映射。
目录项、htree、文件块与路径
crates/ext4plus/src/{dir_entry.rs,dir_block.rs,dir_entry_hash.rs,dir_htree.rs,dir.rs,iters/mod.rs,iters/file_blocks/*,iters/read_dir.rs,file.rs,resolve.rs,xattr.rs}
实现目录项、目录块校验、htree 查找/分裂、目录 API、文件块迭代、文件读写、路径解析和 xattr 读写。
Ext4 主类型与测试支撑
crates/ext4plus/src/{lib.rs,test_util.rs} , build_img.sh, records/logs/2026.6.23.md
实现 Ext4 的加载、块读写、分配释放、符号链接、std 包装与测试支撑,并更新镜像构建参数与迁移记录。
legacy ext4_rs 与构建记录清理
Cargo.toml, arceos/Cargo.toml, crates/ext4_rs/*, build_img.sh, records/logs/2026.6.23.md
移除旧 ext4_rs 的 crate 入口、实现、脚本与文档,并更新 workspace 与镜像构建参数。

axfs ext4 后端迁移

Layer / File(s) Summary
workspace 与类型映射
Cargo.toml, arceos/Cargo.toml, arceos/modules/axfs/Cargo.toml, arceos/modules/axfs/src/fs/ext4/util.rs
更新 workspace 排除与 patch 配置,切换 axfs 的 ext4 feature 依赖,并改写 ext4 错误和文件类型转换。
ext4 磁盘缓存与文件系统状态
arceos/modules/axfs/src/disk.rs, arceos/modules/axfs/src/fs/ext4/mod.rs, arceos/modules/axfs/src/fs/ext4/fs.rs, arceos/modules/axfs/src/highlevel/file.rs
Ext4Disk 缓存条目加入 dirty/flushing 状态,读写改为分块回填与合并写回,文件系统加载、统计和缓存失效改用 ext4plus。
inode 与 tmpfs 生命周期
arceos/modules/axfs/src/fs/ext4/inode.rs, arceos/modules/axfs/src/fs/tmpfs.rs
inode 元数据、读写、link/unlink、rename、延迟删除和 tmpfs 根目录生命周期改为 ext4plus/weak 引用。

同步原语与运行时修复

Layer / File(s) Summary
同步原语与导出
arceos/modules/axsync/Cargo.toml, arceos/modules/axsync/src/lib.rs, arceos/modules/axsync/src/rwlock.rs
axsync 增加 RwLock 实现、导出与依赖,并切换到 workspace spin。
页表锁 IRQ 保护与 frame-table 边界检查
arceos/modules/axmm/src/backend/{alloc.rs,cow.rs,file.rs}
COW 和页故障路径在引用帧前增加 frame table 存在性检查,未知帧按共享页处理或直接复制映射。
挂载状态与文件缓存清理
arceos/modules/axfs/src/lib.rs, crates/axfs-ng-vfs/src/mount.rs
挂载点清理改为锁外执行,mountpoint 祖先判定修正,文件缓存失效入口新增。
futex 等待语义修复与日志调整
pulse_core/src/{flock.rs,mm/loader.rs,trap.rs,task/process.rs}, pulse_syscalls/src/impls/fs/{fd.rs,path.rs}
futex wait/waitv 增加预读、首次检查和 mismatch 处理,并调整 loader、trap、syscall 与 task 退出日志级别。

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~180 minutes

Possibly related PRs

  • muou000/PulseOS#1: SeekableDisk 的读写与块推进/回滚逻辑和本 PR 的 arceos/modules/axfs/src/disk.rs 重写直接相关。
  • muou000/PulseOS#2: 目录快照与缓存失效逻辑和本 PR 的 arceos/modules/axfs/src/fs/ext4/inode.rs 变更处于同一代码区域。

Poem

小兔跳过块与叶,
journal 轻声记新题。
RwLock 护着月光路,
cache 与 inode 同步栖。
🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了本次 PR 的核心变更:将 ext4 驱动从 ext4_rs 替换为 ext4plus。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the ext4_rs dependency with ext4plus to introduce write and async support, updating the filesystem and inode implementations accordingly. It also replaces spin::Mutex with kspin::SpinNoIrq across several virtual filesystem modules, introduces a custom preemption-disabling Mutex in axfs-ng-vfs, and adds interrupt-saving guards to page fault handlers. A critical concurrency race condition was identified in the flush_disk cache write-back mechanism, where dirty blocks are cloned and marked clean but written to disk outside the cache lock, which could lead to lost writes during concurrent evictions or updates.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs
@muou000

muou000 commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
arceos/modules/axmm/src/aspace.rs (1)

619-662: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

缩小 IRQ 关闭范围,避免覆盖缺页后端处理。

PageTableLockManager 已经用 SpinNoIrq 保护页表锁;这里的函数级 IrqSave 会把 backend().handle_page_fault(...)map_with_backend(...) 等可能分配内存或进入文件缓存锁的路径都放在 IRQ 关闭状态下,容易放大中断延迟并引入死锁风险。建议移除这两个外层 IrqSave,只在确实需要的页表临界区依赖 SpinNoIrq

建议修改
-use kernel_guard::IrqSave;
@@
     pub fn handle_page_fault(&self, vaddr: VirtAddr, access_flags: PageFaultFlags) -> PageFaultResult {
-        let _irq = IrqSave::new();
         let page = vaddr.align_down_4k();
@@
     pub fn handle_page_fault_write(&mut self, vaddr: VirtAddr, access_flags: PageFaultFlags) -> bool {
-        let _irq = IrqSave::new();
         let page = vaddr.align_down_4k();

Also applies to: 712-749

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axmm/src/aspace.rs` around lines 619 - 662, Remove the
function-level IrqSave guard in handle_page_fault so IRQs are not held across
backend fault handling and mapping paths. Keep protection only around the actual
page-table critical sections that already rely on
PageTableLockManager/SpinNoIrq, and ensure backend().handle_page_fault(...) and
map_with_backend(...) run outside the outer IRQ-off scope. Update the logic
around pte_before, pt.lock_for_addr(page), and the area/backend handling so only
the minimal remap/query window is protected.
arceos/modules/axfs/src/highlevel/file.rs (1)

936-969: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

截断到同一页时也要清零页缓存尾部。

当前只有 old_last_page > new_last_page 时才清理缓存页;例如从 100 字节截断到 50 字节后,再通过 write_at 扩展到 101 字节,缓存中 50..99 的旧数据仍可能重新可见。请在所有 old_len > len 的截断路径中清零 EOF 后的页内字节,并丢弃所有起始偏移不小于新长度的缓存页。

建议修改
-        } else if old_last_page > new_last_page {
-            // For truncating, we need to remove all pages that are beyond the
-            // new length
-            // TODO(mivik): can this be more efficient?
+        } else if old_len > len {
             let mut guard = self.shared.page_cache.lock();
-            if let Some(page) = guard.get_mut(&new_last_page) {
-                let page_start = new_last_page as u64 * PAGE_SIZE as u64;
-                let new_page_offset = (len - page_start) as usize;
-                page.data()[new_page_offset..].fill(0);
+            let pages_to_keep = len.div_ceil(PAGE_SIZE as u64) as u32;
+            if len % PAGE_SIZE as u64 != 0 {
+                let last_kept_page = pages_to_keep - 1;
+                if let Some(page) = guard.get_mut(&last_kept_page) {
+                    let new_page_offset = (len % PAGE_SIZE as u64) as usize;
+                    page.data()[new_page_offset..].fill(0);
+                }
             }
             let keys = guard
                 .iter()
                 .map(|(k, _)| *k)
-                .filter(|it| *it > new_last_page)
+                .filter(|it| *it >= pages_to_keep)
                 .collect::<Vec<_>>();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/highlevel/file.rs` around lines 936 - 969, In
`File::set_len`, the truncation cleanup only runs when `old_last_page >
new_last_page`, so shrinking within the same page leaves stale bytes in
`page_cache`. Update the `old_len > len` path to always zero the bytes after EOF
in the affected cached page, even when the truncation stays on the same page,
and then discard every cached page whose starting offset is at or beyond the new
length. Use the existing `set_len`, `page_cache`, and `discard_pages` flow to
keep the cache consistent after any shrink.
crates/ext4plus/Cargo.toml.orig (1)

9-67: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

请移除误提交的 .orig 清单文件。

Cargo.toml.orig 看起来是备份/冲突产物;保留完整 manifest 容易误导依赖审计、打包脚本或维护者阅读。若不是构建输入,建议直接删除。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/Cargo.toml.orig` around lines 9 - 67, Remove the accidentally
committed Cargo manifest backup file by deleting the ext4plus Cargo.toml.orig
artifact from the repository; it appears to be a merge/backup leftover rather
than a real build input, so the fix is to exclude it entirely and keep only the
actual Cargo.toml manifest used by ext4plus.
🟠 Major comments (31)
crates/ext4plus/src/iters/read_dir.rs-118-125 (1)

118-125: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

跨块目录会在第一块后提前结束遍历。

这里在当前块读完时直接返回 Ok(None)。对 Iterator/AsyncIterator 的消费方来说,第一次 None 就是结束信号,collectfor 等都会立刻停止;目录一旦超过一个 block,后续条目就永远读不到。这里需要在切到下一块后继续拉取,而不是把块边界暴露成迭代结束。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/iters/read_dir.rs` around lines 118 - 125, The read_dir
iteration stops too early at a block boundary because the logic in ReadDir::next
returns Ok(None) as soon as offset_within_block reaches block_size. Update this
branch so it advances state to the next block and continues fetching entries
instead of signaling iterator end; keep iterating through subsequent blocks
until the directory is actually exhausted. Focus on the ReadDir iterator state
fields like offset_within_block, is_first_block, and block_index when adjusting
the control flow.
crates/ext4plus/src/lib.rs-242-264 (1)

242-264: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

可写加载没有拦住带 journal 的 ext4。

这里在 writer.is_some() 时只处理了 superblock.read_only(),但仓库自带 README 已明确说明 journal 仅支持读取、不支持写入。现在把 ext4plus 接到 PulseOS 的 ext4 驱动后,普通启用 has_journal 的 ext4 分区仍会进入写路径,崩溃时就失去日志一致性保证。建议在可写模式下显式拒绝带 journal/recover 的文件系统,或只允许在确认禁用日志后挂载。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/lib.rs` around lines 242 - 264, In the Ext4 loading path
inside Self::open (where Ext4Inner is built and Journal::load is called),
writable mounts still allow filesystems with journal features to proceed. Add an
explicit guard before constructing fs or before loading the journal that rejects
writable ext4 volumes when the superblock indicates has_journal/recovery
support, and only allow write access when journaling is confirmed disabled. Keep
the existing read-only handling intact and make the new check fail fast with a
clear error.
crates/ext4plus/src/lib.rs-1009-1015 (1)

1009-1015: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

inode 位图先落盘会留下未初始化 inode 的崩溃窗口。

alloc_inode 会先把位图、组描述符和 superblock 计数写回,Inode::create 才开始初始化 inode。本机掉电或 I/O 失败如果发生在两者之间,磁盘上就会留下一个“已分配但内容未完成”的 inode,fsck 只能事后修复。这里需要调整提交顺序,或者在失败路径做完整回滚。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/lib.rs` around lines 1009 - 1015, The create_inode flow
in create_inode currently calls alloc_inode before Inode::create, which can
leave a reserved inode on disk if initialization fails in between. Change the
commit order so inode contents are fully initialized before the inode is marked
allocated, or add a rollback path that clears the inode bitmap and restores the
related counters if Inode::create returns an error. Use the existing
create_inode, alloc_inode, and Inode::create paths to ensure no partially
initialized inode can be persisted.
crates/ext4plus/src/lib.rs-281-288 (1)

281-288: 🎯 Functional Correctness | 🟠 Major

load_from_path_rw 打开文件时缺少写权限。

std::fs::File::open 默认为只读模式,而函数名为 load_from_path_rw,且该句柄被传给写操作处理器(load_with_writer)。首次写入时将因权限不足报错。请使用 OpenOptions 显式启用读写权限。

-        let file = std::fs::File::open(path)
+        let file = std::fs::OpenOptions::new()
+            .read(true)
+            .write(true)
+            .open(path)
+            .map_err(|err| Ext4Error::Io(Box::new(err)))?;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/lib.rs` around lines 281 - 288, `load_from_path_rw` is
opening the path with read-only access even though it passes the handle into
`load_with_writer`, so change the file opening logic in `load_from_path_rw` to
use `OpenOptions` with both read and write enabled. Keep the existing error
mapping to `Ext4Error::Io`, and preserve the current `PtrPrimitive` and
`Self::load_with_writer` flow after the handle is opened with the correct
permissions.
pulse_core/src/task/process.rs-2621-2621 (1)

2621-2621: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

把 futex 热路径日志降回 debug! 或加采样。

futex_keyfutex_waitfutex_wake 都在每次调用时输出 info!,而 futex 正好是同步热点。这里会把高争用场景直接变成日志热点,显著放大 syscall 延迟并刷爆常规日志。

Also applies to: 2800-2808, 2899-2907

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pulse_core/src/task/process.rs` at line 2621, The futex hot-path logging in
process::futex_key, process::futex_wait, and process::futex_wake is currently at
info level on every call, which makes high-contention paths overly chatty.
Change these logs to debug level or add sampling/guarding so they do not emit on
every syscall, and keep the log context aligned with the existing axlog calls in
these functions.
crates/ext4plus/src/journal/revocation_block.rs-57-74 (1)

57-74: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

r_count 的语义读错了。

Line 58 这里把 revocation block 里的长度字段当成“纯表项字节数”来用了,但 JBD2 的这个字段表示的是整块里已使用的字节数。按当前实现,合法块在 Line 61 就会因为把 header(以及启用校验和时的尾部 checksum)算进来了而被误判为损坏,journal recovery 会直接失败。这里应先按 on-disk 语义扣掉 revoke header/size 字段/尾部 checksum,再校验剩余 entry bytes;对应测试里的长度值也要一起调整。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/journal/revocation_block.rs` around lines 57 - 74, In
revocation_block.rs, the length field read in the revocation block parser is
being treated as pure table-entry bytes, but JBD2’s r_count represents total
used bytes in the block. Update the parsing logic in the revocation block
handling around the size read and the subsequent bounds check to subtract the
on-disk overhead (revocation header/size field and any trailing checksum when
enabled) before validating and slicing the entry data. Also adjust the related
revocation-block tests so their length values match the corrected JBD2
semantics.
pulse_core/src/task/process.rs-2663-2665 (1)

2663-2665: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

不要在 wait 路径里先写回 futex 字值。

Line 2663-2665 和 Line 2770-2775 把原本只需读取的比较变成了真实写访问。这样即使值本来就不匹配,也会先触发 COW/脏页;遇到只读映射或共享文件映射时,还可能把本该返回 WouldBlock 的路径变成 BadAddress。应先完成只读比较,再只在确实需要且确认可写的私有路径上做预触发。

Also applies to: 2770-2775

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pulse_core/src/task/process.rs` around lines 2663 - 2665, In the futex wait
path, stop writing the futex word back before the comparison in the code around
self.read_user_u32 and self.write_user_bytes, including the corresponding logic
in the later wait branch. Perform the value check using a read-only access
first, and only trigger any write/COW behavior on the confirmed private-writable
path when it is actually needed; keep the WouldBlock vs BadAddress behavior
unchanged for read-only or shared mappings.
crates/ext4plus/src/block_group.rs-287-312 (1)

287-312: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

不要让 GROUP_DESCRIPTOR_CHECKSUMS 到写路径再 panic。

读取路径这里只留了 TODO,但写入路径会在 Line 308 直接 unimplemented!()。这意味着带该 feature 的旧 ext4 镜像可能先挂载成功,第一次修改块组描述符时再把内核打崩。至少应在挂载/读取阶段显式拒绝这个 feature,直到校验与写回逻辑补齐。

Also applies to: 440-447

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/block_group.rs` around lines 287 - 312, The
update_checksum logic in block_group::update_checksum still panics on
GROUP_DESCRIPTOR_CHECKSUMS during writeback, so the unsupported feature must be
rejected earlier instead of reaching unimplemented!(). Update the mount/read
path in the block group handling code to detect
ReadOnlyCompatibleFeatures::GROUP_DESCRIPTOR_CHECKSUMS and fail the filesystem
open or feature negotiation immediately, and keep update_checksum limited to
supported checksum modes only.
crates/ext4plus/src/bitmap.rs-49-66 (1)

49-66: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

set() 的读改写在并发下会丢失位图更新。

这里是“读 1 字节 → 改 1 bit → 回写整字节”的流程;而 arceos/modules/axfs/Cargo.toml 的 Line 44 已启用 multi-threaded。两个线程如果同时修改同一字节内的不同 bit,后一次写回会覆盖前一次结果,直接破坏块/inode 分配状态。建议把位图修改放到组级/块级锁内,或提供原子化的整字节更新路径。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/bitmap.rs` around lines 49 - 66, The bitmap update in
set() is a read-modify-write on a single byte and can lose concurrent changes
when multiple threads update different bits in the same byte. Fix this by making
the byte update atomic with respect to other bitmap mutations, such as guarding
the Ext4::read_from_block/write_to_block sequence with a group/block-level lock
or adding an atomic byte-update path in Bitmap::set that prevents overlapping
writes.
crates/ext4plus/src/block_group.rs-107-216 (1)

107-216: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

请先拒绝非当前实现支持尺寸的块组描述符。

from_bytes()/to_bytes() 只实现了 32/64 字节布局,但 read() 直接信任 s_desc_size。这会产生两个坏结果:过小的描述符会在 read_u16le/read_u32le 上 panic;超过 64 字节的描述符会在 update_checksum()/write() 时被截断,重算出来的校验和不再覆盖原始尾部。若本 PR 暂不支持其它尺寸,最小修复应该是在读取阶段直接拒绝它们。

建议的最小防护
         let block_group_descriptor_size =
             usize::from(sb.block_group_descriptor_size());
+        let expected_size = if sb
+            .incompatible_features()
+            .contains(IncompatibleFeatures::IS_64BIT)
+        {
+            Self::SIZE_IN_BYTES_ON_DISK_64
+        } else {
+            Self::SIZE_IN_BYTES_ON_DISK_32
+        };
+        if block_group_descriptor_size != expected_size {
+            return Err(CorruptKind::BlockGroupDescriptor(bgd_index).into());
+        }
         let mut data = vec![0; block_group_descriptor_size];

Also applies to: 219-312, 399-464

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/block_group.rs` around lines 107 - 216, The block group
descriptor parsing in read()/from_bytes() currently trusts s_desc_size even
though only the 32-byte and 64-byte layouts are implemented by
from_bytes()/to_bytes(). Add an explicit size check in the read path before
decoding a BlockGroup so unsupported descriptor sizes are rejected early instead
of causing read_u16le/read_u32le panics or later checksum/write truncation; keep
the guard close to the existing BlockGroup::from_bytes, update_checksum, and
write flow so only supported sizes proceed.
crates/ext4plus/src/dir_block.rs-155-166 (1)

155-166: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

损坏的 count 字段会在校验和路径上直接 panic。

这里先根据块内 count 算出 num_bytes,再直接做 &block[..num_bytes]。如果目录块被破坏到让 count 超过尾部偏移,代码会在返回 CorruptKind 之前先 panic。建议把这个函数改成 Result<Checksum, Ext4Error>,并在切片前显式校验 num_bytes <= tail_entry_offset

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/dir_block.rs` around lines 155 - 166, The checksum path
in `dir_block.rs` can panic because `num_bytes` derived from `count` is used
directly to slice `block` before validating it against `tail_entry_offset`.
Update the relevant checksum calculation in this code path to return
`Result<Checksum, Ext4Error>` instead of unwrapping, and add an explicit bounds
check that `num_bytes <= tail_entry_offset` before any `&block[..num_bytes]`
access so corrupted directory blocks are reported as `CorruptKind` rather than
panicking.
crates/ext4plus/src/extent.rs-66-81 (1)

66-81: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

区分“逻辑块数”和磁盘上的 ee_len 编码。

allocate() 传进来的 tried_blocks 是真实块数,但 Extent::new() 会把 > 32768 的值解释成已经编码过的 on-disk ee_len。一旦上层请求超过 32,768 个块,这里会静默截断长度并把新 extent 标成未初始化。建议把反序列化逻辑拆到单独构造函数,或者至少在这里显式拒绝超过 ext4 initialized extent 上限的长度。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/extent.rs` around lines 66 - 81, `Extent::new` is mixing
logical block counts with the on-disk `ee_len` encoding, so `allocate()`’s real
`tried_blocks` can be misinterpreted and silently truncated when it exceeds the
initialized extent limit. Update the `Extent::new` path to treat its input as a
plain count and either reject values above the ext4 initialized extent maximum
or move the `ee_len` decoding/encoding logic into a separate constructor/helper,
keeping the `allocate()` call site and `Extent::new` semantics unambiguous.
crates/ext4plus/src/dir_htree.rs-759-761 (1)

759-761: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

这里把多层 htree 目录错误地当成 NoSpace

find_leaf_lookup() 已经支持按 depth 构建任意深度的路径,但这里除了 path.len() == 2 之外全部直接返回 Ext4Error::NoSpace。一旦目录索引深度超过一层,内部节点分裂会在仍有可用空间时失败。这里需要继续向上递归/迭代分裂父节点,而不是把深层目录硬编码成不支持。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/dir_htree.rs` around lines 759 - 761,
`find_leaf_lookup()` currently rejects any htree path deeper than two levels by
returning `Ext4Error::NoSpace`, which incorrectly blocks multi-level directory
splits. Update the logic around the `lookup.path.len()` check in `dir_htree` so
it can continue propagating splits upward through parent nodes instead of
hardcoding a depth-2 limit; use the existing `lookup.path`/`depth` handling to
iterate or recurse until the root is reached.
crates/ext4plus/src/extent.rs-41-64 (1)

41-64: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

不要把所有分配失败都降级成 NoSpace

这里的 Err(_) 会把只读、I/O、损坏等失败都当成“缩小 extent 再试一次”,最后很容易错误地返回 Ext4Error::NoSpace。这里只应对真正的空间不足退避,其他错误需要立即透传。

建议修改
         let start_fs_block = loop {
             match fs
                 .alloc_contiguous_blocks(
                     inode_index,
                     NonZeroU32::new(u32::from(tried_blocks)).unwrap(),
                 )
                 .await
             {
                 Ok(start_fs) => break start_fs,
-                Err(_) => {
-                    if tried_blocks == 0 {
-                        return Err(Ext4Error::NoSpace);
-                    }
+                Err(Ext4Error::NoSpace) => {
                     #[expect(
                         clippy::arithmetic_side_effects,
                         reason = "We check for tried_blocks == 0 above"
                     )]
                     {
                         tried_blocks -= 1
                     }
                     if tried_blocks == 0 {
                         return Err(Ext4Error::NoSpace);
                     }
                 }
+                Err(e) => return Err(e),
             }
         };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/extent.rs` around lines 41 - 64, The retry logic in the
extent allocation path is too broad: the `match` around
`alloc_contiguous_blocks` in `extent.rs` currently treats every `Err(_)` as a
space shortage and keeps shrinking `tried_blocks`, which can hide read-only,
I/O, or corruption failures as `Ext4Error::NoSpace`. Update the handling in the
`alloc_contiguous_blocks` call site to only retry on the specific “out of space”
case, and immediately propagate all other errors unchanged; keep the
`tried_blocks` decrement and `NoSpace` fallback only for genuine space
exhaustion.
arceos/modules/axfs/src/fs/ext4/inode.rs-550-554 (1)

550-554: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

在硬链接入口显式拒绝目录。

link() 当前没有检查 child_inode.file_type();目录硬链接会破坏目录树不变量。即使底层可能拒绝,也建议在这里先返回 OperationNotSupported,避免依赖后端实现细节。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/ext4/inode.rs` around lines 550 - 554, The
hardlink path in inode::link currently allows any inode type through without
checking whether the target is a directory. Update this flow to inspect
child_inode.file_type() immediately after reading the inode and, if it is a
directory, return VfsError::OperationNotSupported before calling dir.link; keep
the existing child_idx, Inode::read, and DirEntryName::try_from logic otherwise
unchanged.
arceos/modules/axfs/src/fs/ext4/inode.rs-204-211 (1)

204-211: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

不要把缺失的目录项类型默认成普通文件。

unwrap_or(FileType::Regular) 会把缺少 file type 的目录、符号链接或设备节点错误缓存为普通文件,后续 lookup/read_dir/unlink 都会基于错误类型运行。请在 file_type() 为空时读取目标 inode 并用真实 inode.file_type() 回填。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/ext4/inode.rs` around lines 204 - 211, In the ext4
inode directory-entry handling, the current fallback in the code that sets
de_type from entry.file_type() is incorrectly defaulting missing types to
FileType::Regular, which can cache directories, symlinks, or device nodes as
regular files. Update the logic in the inode directory-entry processing path to
detect when file_type() returns None, load the target inode for that entry, and
use the real inode.file_type() to populate de_type before deriving node_type and
is_dir. Ensure the fix is applied in the same lookup/read_dir flow where
entry.file_name() and entry.file_type() are already being used.
arceos/modules/axfs/src/fs/ext4/inode.rs-521-532 (1)

521-532: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

dir.link 失败时回收刚创建的 inode。

这里已经分配了 new_inode;如果后面的 dir.link 失败,当前路径直接返回错误,会留下未链接 inode,占用空间并污染文件系统状态。请在返回错误前调用删除/回滚路径清理新 inode。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/ext4/inode.rs` around lines 521 - 532, Handle
cleanup for the newly created inode in the ext4 inode creation flow: in the code
path around fs.create_inode, Dir::init, and dir.link, if dir.link fails after
new_inode has been allocated (and possibly initialized as a directory),
explicitly roll back by deleting or otherwise releasing that inode before
returning the error. Update the create/link logic so the failure path in
inode.rs does not leave an unlinked inode behind, and make sure the cleanup is
applied in the same function that performs the allocation and linking.
arceos/modules/axfs/src/fs/ext4/inode.rs-631-642 (1)

631-642: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

覆盖已有目标前校验源/目标类型兼容。

如果 src_inode 是普通文件而 dst_inode 是空目录,当前会 unlink 目标目录并继续 link 源文件;反向场景也没有被拒绝。请在 unlink 目标前检查 src_is_dir != dst_is_dir 并返回对应错误。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/ext4/inode.rs` around lines 631 - 642, In the
rename/move flow inside ext4 inode handling, the current overwrite path in the
logic around dst_dir_obj.get_entry and unlink only checks same inode and
non-empty destination directories, but does not reject type mismatches between
src_inode and dst_inode. Add a compatibility check before calling
dst_dir_obj.unlink so that src_is_dir and dst_is_dir must match, and return the
appropriate VfsError when a regular file would overwrite a directory or vice
versa; keep the existing same-inode and non-empty-directory checks in place.
arceos/modules/axfs/src/disk.rs-132-134 (1)

132-134: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

不要吞掉磁盘 flush 失败。

flush_all_disks() 返回 DevResult<()>,但现在忽略每个 flush_disk() 的错误并始终 Ok(()),上层会误判脏数据已经持久化。

建议修复
     for flusher in flushers {
-        let _ = flusher.flush_disk();
+        flusher.flush_disk()?;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/disk.rs` around lines 132 - 134, flush_all_disks
currently ignores each flusher.flush_disk() result and can return Ok(()) even
when a disk flush fails. Update flush_all_disks in disk.rs to propagate errors
from flush_disk instead of discarding them, so callers receive DevResult<()>
failures correctly; use the existing flushers loop and ensure any error from a
flusher causes the function to return that error rather than continuing
silently.
crates/ext4plus/src/reader.rs-271-318 (1)

271-318: 🎯 Functional Correctness | 🟠 Major

为 Arc 测试添加 multi-threaded feature 限定

test_arc_read_delegates_to_inner_reader 调用了 Arc<T>read 方法。代码库中 impl Ext4Read for alloc::sync::Arc<...> 的实现仅在 feature = "multi-threaded" 下生效。当前的测试函数未添加对应的 #[cfg(feature = "multi-threaded")] 防护,导致在非 multi-threaded 组合(如仅启用 sync 或默认配置)下编译失败。

建议在 use alloc::sync::Arc; 语句和 test_arc_read_delegates_to_inner_reader 函数前添加 #[cfg(feature = "multi-threaded")]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/reader.rs` around lines 271 - 318, The Arc-specific test
and import are not gated by the same feature as the Arc Ext4Read impl, so they
can fail to compile when multi-threaded is disabled. Add #[cfg(feature =
"multi-threaded")] to the use alloc::sync::Arc import and to
test_arc_read_delegates_to_inner_reader so the test only builds when the Arc
reader implementation is available.
crates/ext4plus/src/dir.rs-735-740 (1)

735-740: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

用错误返回替代 inode 不匹配时的 panic。

Dir::unlink 是公开 API,调用方传入的 inode 与目录项不一致时不应 assert_eq! 触发 panic;这里应返回可处理的错误。

建议修复
-        assert_eq!(
-            linked_inode.index, inode.index,
-            "unlink called with inode that does not match directory entry"
-        );
+        if linked_inode.index != inode.index {
+            return Err(Ext4Error::NotFound);
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/dir.rs` around lines 735 - 740, In Dir::unlink, replace
the assert_eq! on linked_inode.index versus inode.index with a proper error
return so the public API does not panic when the passed inode does not match the
directory entry. Use the existing async lookup result from
get_dir_entry_inode_by_name and, on mismatch, return a descriptive error that
callers can handle instead of aborting execution; keep the success path
unchanged for matching inodes.
crates/ext4plus/src/reader.rs-200-208 (1)

200-208: 🩺 Stability & Availability | 🟠 Major

不要将单次 read_at 调用视为完整读取。

std::os::unix::fs::FileExt::read_at 允许返回少于请求长度的字节(短读)。当前实现在非 EOF 的合法短读情况下直接抛出 MemIoError,违反了 Ext4Read “填满缓冲区”的契约。

请修改逻辑,循环调用 read_at 直到填满缓冲区或确认 EOF:

  1. 在循环中累加读取的字节数并更新目标缓冲区偏移量。
  2. 仅在返回值 0 且缓冲区仍未填满时,返回 MemIoError

建议提取辅助函数(如 read_exact_at)以同时修复第 200-208、228-236 及 246-254 行的类似问题。

建议修复方向
-        let total = self.read_at(dst, start_byte).map_err(Box::new)?;
-        if total != dst.len() {
+        let mut read_len = 0;
+        let mut offset = 0;
+        while read_len < dst.len() {
+            let n = self.read_at(&mut dst[offset..], start_byte + read_len as u64)
+                .map_err(Box::new)?;
+            if n == 0 {
                 return Err(Box::new(MemIoError {
                     start: start_byte,
                     read_len: dst.len(),
-                    src_len: total,
+                    src_len: read_len,
                 })
                 .into());
+            }
+            read_len += n;
+            offset += n;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/reader.rs` around lines 200 - 208, The current Ext4Read
path treats a single FileExt::read_at result as a full buffer fill, which can
incorrectly fail on合法短读. Update the read-at logic in the reader implementation
(for the affected methods such as read_exact_at/read_at-style helpers in
reader.rs) to loop until the destination buffer is completely filled or read_at
returns 0, advancing the buffer slice and byte offset on each iteration. Only
raise MemIoError when a 0-length read occurs before the buffer is full, and
consider extracting a shared helper so the same fix applies consistently to the
repeated read_at call sites in the reader methods.
crates/ext4plus/src/block_size.rs-23-28 (1)

23-28: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

限制 superblock 声明的最大 block size。

当前只检查 u32 幂运算溢出,log_block_size = 21 会被接受为 2GiB;后续按 block size 分配缓冲区时可能直接 OOM。请在这里拒绝超出驱动支持范围的值,并同步更新 Line 121-125 的测试期望。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/block_size.rs` around lines 23 - 28, Clamp the accepted
superblock block size in from_superblock_value so values above the
driver-supported maximum are rejected instead of only relying on checked_pow
overflow; specifically, add an explicit upper-bound check on log_block_size
before constructing BlockSize, and make sure the existing
BlockSize::from_superblock_value path returns None for oversized values like the
2GiB case. Also update the tests around the BlockSize parsing expectations to
assert that out-of-range superblock values are rejected, while keeping the valid
range behavior unchanged.
crates/ext4plus/src/xattr.rs-468-474 (1)

468-474: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

不要无条件释放 external xattr block。

ext4 的 external xattr block 可能通过 header refcount 被多个 inode 共享;这里直接 free_block(file_acl) 会让其他 inode 悬挂引用。另外释放发生在 inode 清除 file_acl 并写回之前,写回失败也会留下已释放但仍被引用的 block。请按 refcount decrement/free,并把 inode 更新与 block 释放放入安全顺序或 journal 事务。

Also applies to: 518-524

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/xattr.rs` around lines 468 - 474, The xattr cleanup logic
in the file_acl handling path is freeing the external xattr block
unconditionally, which breaks shared refcounted blocks and can leave inode/block
state inconsistent. Update the file_acl removal flow to use the ext4 xattr block
header refcount so the block is only freed when the refcount reaches zero, and
make sure the inode’s file_acl/fs_blocks updates in the relevant xattr cleanup
routines are applied before or atomically with block release. Use the existing
file_acl, set_file_acl, fs_blocks, and ext4.free_block paths to locate and fix
both affected cleanup sites.
crates/ext4plus/src/iters/file_blocks/block_map.rs-134-137 (1)

134-137: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

不要把为 0 的间接块指针当成真实 block 读取。

注释已说明 block index 0 表示 hole,但这些路径会对 0 调用 IndirectBlockIter::new(...),从而读取 block 0 并把元数据解析成文件数据映射。稀疏文件的 indirect/double/triple subtree 应按覆盖范围产出 hole,而不是读取磁盘 block 0。

Also applies to: 151-154, 169-172, 260-264, 302-306

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/iters/file_blocks/block_map.rs` around lines 134 - 137, 在
BlockMap 的间接块遍历逻辑中,不能把 block index 为 0 的指针交给 IndirectBlockIter::new
当作真实磁盘块读取;这会把 hole 误解析成文件数据。请在 block_map.rs 中涉及 level_1、level_2、level_3
以及相关递归/分支路径的处理里,先检查间接指针是否为 0,若为 0 就按该子树覆盖范围直接产出 hole 或跳过读取,而不是继续构造
IndirectBlockIter。把所有受影响的路径(包括 block_0、block_1、block_2、block_3 的分支)统一改成保持稀疏文件语义。
crates/ext4plus/src/superblock.rs-262-268 (1)

262-268: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

遵守 ro-compat READ_ONLY 标志。

ReadOnlyCompatibleFeatures::READ_ONLY 当前不会让 read_only() 返回 true,因此带只读标志的 ext4 仍可能被写入。请把该 bit 纳入只读判定。

建议修改
     pub(crate) fn read_only(&self) -> bool {
-        self.incompatible_features()
+        self.read_only_compatible_features()
+            .contains(ReadOnlyCompatibleFeatures::READ_ONLY)
+            || self.incompatible_features()
             .contains(IncompatibleFeatures::RECOVERY)
             || !check_read_only_compat_features(
                 self.read_only_compatible_features().bits(),
             )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/superblock.rs` around lines 262 - 268, The read_only()
check in Superblock currently ignores ReadOnlyCompatibleFeatures::READ_ONLY, so
ext4 volumes marked read-only may still be treated as writable. Update
read_only() to include the READ_ONLY bit in the final decision alongside the
existing RECOVERY and check_read_only_compat_features() checks, using the
existing incompatible_features() and read_only_compatible_features() accessors
to locate the logic.
crates/ext4plus/src/writer.rs-196-204 (1)

196-204: 🗄️ Data Integrity & Integration | 🟠 Major

修复 write_at 短写处理逻辑。

当前实现在写入字节数小于请求长度时立即返回错误,这可能导致数据不一致。std::os::unix::fs::FileExt 仅提供 write_at,不支持直接调用 write_all_at,需要手动实现循环写入以确保数据完整性。

-        let total = self.write_at(src, start_byte).map_err(Box::new)?;
-        if total != src.len() {
-            return Err(Box::new(crate::MemIoError {
-                start: start_byte,
-                read_len: src.len(),
-                src_len: total,
-            })
-            .into());
-        }
+        let mut written = 0;
+        while written < src.len() {
+            let n = self.write_at(&src[written..], start_byte + written as u64)
+                .map_err(Box::new)?;
+            if n == 0 {
+                return Err(Box::new(crate::MemIoError {
+                    start: start_byte,
+                    read_len: src.len(),
+                    src_len: total,
+                })
+                .into());
+            }
+            written += n;
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/writer.rs` around lines 196 - 204, The short-write
handling in write_at_or equivalent logic is incomplete because it treats any
partial write from write_at as an error instead of retrying until all bytes are
written. Update the writer logic in writer.rs to loop on write_at using the
current offset and remaining buffer until the full src slice is persisted, and
only return an error if progress stops or write_at fails; keep the fix localized
to the write_at call site and the surrounding write-at-all flow.
crates/ext4plus/src/journal/block_map.rs-130-132 (1)

130-132: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

按环形 journal 语义处理 start_block

这里仅 skip(start_block) 会只扫描 start_block..EOF;如果有效 transaction 从 journal 尾部回绕到前半段,1..start_block 的已提交块映射会被漏掉,replay 后可能丢失元数据更新。也请确认 start_block == 0 的 clean journal 是否已在上层直接跳过。

#!/bin/bash
# 描述:核对当前 replay 路径是否已经处理 clean journal 和环形回绕扫描。
rg -n -C4 'start_block|load_block_map|FileBlocks::new|skip\(' crates/ext4plus/src
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/journal/block_map.rs` around lines 130 - 132, The journal
scan in load_block_map currently uses start_block only as a linear skip, which
misses wrapped committed blocks in the ring-buffer layout. Update the
journal_block_iter logic in block_map.rs to treat start_block as the wrap point
and scan both the tail segment from start_block to EOF and the head segment from
1 to start_block when needed, while preserving the existing clean-journal
handling path for start_block == 0. Refer to load_block_map, journal_block_iter,
and superblock.start_block when making the change.
crates/ext4plus/src/writer.rs-258-258 (1)

258-258: 🎯 Functional Correctness | 🟠 Major

让委托写入测试适配 multi-threaded 特性限制。

测试模块 tests 开启于 feature = "std",但 Ext4Write 的特质实现仅在 feature = "multi-threaded" 时针对 Arc 生效,非 multi-threaded 模式下仅 Rc 实现了该特质。因此,当仅启用 std 而未启用 multi-threaded 构建时,测试代码因缺少 Arc 的特质实现而编译失败。建议引入条件编译,根据功能标志在 ArcRc 之间切换。

建议修复
-    use std::sync::Arc;
+    #[cfg(feature = "multi-threaded")]
+    use std::sync::Arc as TestPtr;
+    #[cfg(not(feature = "multi-threaded"))]
+    use std::rc::Rc as TestPtr;
@@
-        let storage = Arc::new(Mutex::new(vec![0, 0, 0, 0]));
+        let storage = TestPtr::new(Mutex::new(vec![0, 0, 0, 0]));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/writer.rs` at line 258, `tests` 模块在仅启用 `std`、未启用
`multi-threaded` 时直接使用 `Arc`,但 `Ext4Write` 只在 `multi-threaded` 下为 `Arc`
实现、非该特性下仅支持 `Rc`,导致测试编译失败。请在 `writer.rs` 的测试相关代码中根据功能标志做条件编译,在 `Arc` 和 `Rc`
之间切换,并确保使用到 `Ext4Write` 的测试辅助类型/初始化逻辑也同步适配这两个引用类型。
crates/ext4plus/src/dir_entry.rs-262-297 (1)

262-297: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

rec_len 校验目录项边界。

当前只检查名字是否落在 bytes 内,没有确保 rec_len <= bytes.len()name_end <= rec_len;损坏目录项可以让名称跨过当前记录边界并污染后续解析。

建议修改
         if rec_len < NAME_OFFSET {
             return Err(
                 CorruptKind::DirEntryRecordTooSmall(inode, rec_len).into()
             );
         }
         // OK to unwrap: above check ensures that `rec_len >= NAME_OFFSET`.
         let rec_len = NonZero::new(rec_len).unwrap();
+        if rec_len.get() > bytes.len() {
+            return Err(CorruptKind::DirEntry(inode).into());
+        }
 
         // As described above, an inode of zero is used for special
         // entries. Return early since the rest of the fields won't be
         // valid.
@@
         let name_end: usize = NAME_OFFSET.checked_add(name_len_usize).unwrap();
+        if name_end > rec_len.get() {
+            return Err(CorruptKind::DirEntryNameTooLarge(inode, name_len).into());
+        }
 
         // Get the entry's name.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/dir_entry.rs` around lines 262 - 297, The directory entry
parsing in dir_entry.rs only validates the name slice against bytes, but it
still allows malformed records to read past the current rec_len boundary. In the
parser that computes rec_len, name_len, and name_end, add explicit checks that
rec_len does not exceed the available input buffer and that name_end stays
within rec_len before slicing the name. Use the existing dir entry parsing logic
and CorruptKind errors in this function to reject truncated or overlong entries
early.
arceos/modules/axfs/src/fs/tmpfs.rs-351-355 (1)

351-355: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

把空目录检查和清空放在同一个子目录锁内。

当前先 len() 后重新加锁 clear();并发创建可以在两次加锁之间插入新条目,随后被 clear() 静默删除。

建议修改
         if let NodeContent::Dir(dir_content) = &entry.get().content {
-            if dir_content.entries.lock().len() > 2 {
+            let mut child_entries = dir_content.entries.lock();
+            if child_entries.len() > 2 {
                 return Err(VfsError::DirectoryNotEmpty);
             }
-            dir_content.entries.lock().clear();
+            child_entries.clear();
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/tmpfs.rs` around lines 351 - 355, The
empty-directory check and the clear operation in tmpfs removal are using
separate lock acquisitions on dir_content.entries, which allows a race where new
entries can be inserted between len() and clear(). Update the logic in the
NodeContent::Dir handling path to hold the same entries lock across both the
DirectoryNotEmpty check and the clearing step, so the validation and mutation
are performed atomically under one lock.
🟡 Minor comments (4)
crates/ext4plus/src/test_util.rs-226-229 (1)

226-229: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Drop 里直接跑 fsck 会把普通测试失败升级成 abort。

如果测试本身已经在 unwinding,fsck_ext4_arc_image 再 panic 一次就会触发双重 panic,整个测试进程直接 abort。这里至少应在 std::thread::panicking() 时跳过,或者改成显式校验 API。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/test_util.rs` around lines 226 - 229, The Ext4Wrapper
Drop implementation currently calls fsck_ext4_arc_image unconditionally, which
can trigger a second panic during unwinding and abort the test process. Update
Ext4Wrapper::drop to avoid running fsck_ext4_arc_image when
std::thread::panicking() is true, or move the filesystem check into an explicit
validation method instead of Drop.
crates/ext4plus/src/error.rs-197-198 (1)

197-198: 🗄️ Data Integrity & Integration | 🟡 Minor

Ext4Error::NoSpace 映射为 std::io::ErrorKind::StorageFull

当前 Ext4Error::NoSpace 使用 Self::other(e) 会丢失“磁盘空间不足”的具体错误语义,导致上层无法通过 ErrorKind 区分该错误与通用 I/O 错误。应将其显式映射为 std::io::ErrorKind::StorageFull(Rust 1.76+ 支持,当前 MSRV 1.86 完全兼容),以便正确传递 ENOSPC 语义。

            Ext4Error::NoSpace => Self::other(e),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/error.rs` around lines 197 - 198, The Ext4 error-to-io
conversion currently treats Ext4Error::NoSpace as a generic error, which loses
the ENOSPC meaning. Update the matching logic in the error mapping
implementation for Ext4Error so that Ext4Error::NoSpace is converted to
std::io::ErrorKind::StorageFull instead of using Self::other(e), while leaving
the other variants unchanged.
crates/ext4plus/src/features.rs-64-64 (1)

64-64: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

修正 ro-compat 0x20 的 feature 名称。

Line 64 的 0x20 不是 incompat LARGE_DIRECTORIES,这里应表示目录链接数扩展语义;当前公开 API 会把两个不同 ext4 feature 混成同名概念。

建议修改
-        const LARGE_DIRECTORIES = 0x20;
+        const DIR_NLINK = 0x20;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/features.rs` at line 64, The feature constant for the
ro-compat bit at 0x20 is misnamed as LARGE_DIRECTORIES, which conflates two
different ext4 feature meanings in the public API. Update the identifier in
features.rs to the correct ro-compat semantic name for directory link-count
extension, and make sure any matching feature-mapping logic or display/parse
helpers that reference this constant use the same distinct symbol so
incompatible features are no longer exposed as one concept.
crates/ext4plus/src/metadata.rs-36-46 (1)

36-46: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

修正 ctime 的字段说明。

Line 36 的 ctime 与 Line 45 的 crtime 都写成了“Creation time”;这里 ctime 应描述为状态变更时间,避免公开 API 文档误导调用方。

建议修改
-    /// Creation time.
+    /// Status change time.
     pub ctime: Duration,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/metadata.rs` around lines 36 - 46, Fix the
duplicated/incorrect documentation on Metadata’s time fields by updating the doc
comment for ctime to describe it as the status change time rather than “Creation
time,” while leaving crtime as creation time; locate this in the Metadata struct
alongside dtime, mtime, and crtime so the public API docs accurately distinguish
ctime from crtime.
🧹 Nitpick comments (1)
crates/ext4plus/src/dir_entry_hash.rs (1)

55-62: 🎯 Functional Correctness | 🔵 Trivial

建议补充支持的哈希算法说明

当前的 HashAlg::from_u8 仅接受算法 ID 1 (HalfMD4) 和 2 (TEA)。由于标准的 ext4 htree 目录索引主要使用 HalfMD4,现有逻辑已覆盖主流场景。遇到非标准哈希算法时,代码已正确返回包含具体 ID 的不兼容错误。建议在 HashAlg 定义或 from_u8 函数附近添加注释,明确列出支持的算法 ID 列表,以便开发者清楚该实现针对的 ext4 格式范围,减少对非标准文件系统镜像的兼容性困惑。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/dir_entry_hash.rs` around lines 55 - 62,
`HashAlg::from_u8` currently handles only the supported algorithm IDs and
returns an incompatibility error for others; add a nearby comment on `HashAlg`
or in `from_u8` listing the accepted IDs and their meanings (HalfMd4 and Tea) so
the supported ext4 htree hash range is explicit. Keep the note close to the
`from_u8` match/branch logic in `dir_entry_hash.rs` so future readers can
immediately see which hash algorithms this implementation supports.

Comment thread arceos/modules/axfs/src/fs/ext4/fs.rs Outdated
Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs Outdated
Comment thread arceos/modules/axfs/src/fs/tmpfs.rs Outdated
Comment thread crates/ext4plus/src/dir.rs
Comment thread crates/ext4plus/src/dir.rs
Comment thread crates/ext4plus/src/lib.rs
Comment thread crates/ext4plus/src/resolve.rs Outdated
Comment thread crates/ext4plus/src/superblock.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/ext4plus/src/extent.rs (1)

39-45: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

在分配前限制 extent 块数,避免大写入或零长度请求触发 panic。

amount == 0 会在 NonZeroU32::new(...).unwrap() 处崩溃;amount > 32768 若分配成功,会在 Extent::new 的断言处崩溃。请先拒绝 0,并把初始化 extent 的尝试长度限制到 32768。

建议修复
-        let mut tried_blocks = amount;
+        if amount == 0 {
+            return Err(Ext4Error::NoSpace);
+        }
+        let mut tried_blocks = amount.min(32768);

Also applies to: 69-78

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/ext4plus/src/extent.rs` around lines 39 - 45, In extent allocation,
guard the requested block count before calling alloc_contiguous_blocks and
constructing Extent::new: reject amount == 0 up front to avoid the
NonZeroU32::new(...).unwrap() panic, and cap the initial extent attempt length
at 32768 so successful large allocations do not trip the Extent::new assertion.
Update the logic in extent.rs around the allocation loop and any related extent
creation paths referenced by the same symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/ext4plus/src/journal/block_map.rs`:
- Around line 295-303: The skip-to-start-block logic in the block-map iterator
is swallowing underlying `FileBlocks` errors and treating premature `None` as a
normal wrap, so update the `current_iter`/`skip_count` handling in the iterator
used around `next().await` to propagate any `Err` immediately and treat `None`
before reaching `start_block` as truncation that stops iteration instead of
continuing. Make the same branch behavior change in the synchronous path that
mirrors this logic, using the existing `current_iter`, `skip_count`, and
`start_block` flow to locate the fix.

In `@crates/ext4plus/src/writer.rs`:
- Around line 202-205: The write path in Ext4Write is reusing MemIoError fields
and the resulting error message is misleadingly reported as a read failure.
Update the error handling in the write-at flow so failures are represented as
write errors, either by adding an operation type to MemIoError or by introducing
a separate write-specific error used by Ext4Write::write_at and the related
write branches, and make sure the message emitted when write_at returns 0
describes a failed write rather than a failed read.

---

Outside diff comments:
In `@crates/ext4plus/src/extent.rs`:
- Around line 39-45: In extent allocation, guard the requested block count
before calling alloc_contiguous_blocks and constructing Extent::new: reject
amount == 0 up front to avoid the NonZeroU32::new(...).unwrap() panic, and cap
the initial extent attempt length at 32768 so successful large allocations do
not trip the Extent::new assertion. Update the logic in extent.rs around the
allocation loop and any related extent creation paths referenced by the same
symbols.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d5facf1-f6a0-4f3a-91ae-c8406c8a20d8

📥 Commits

Reviewing files that changed from the base of the PR and between 5f07866 and 539e694.

📒 Files selected for processing (30)
  • Cargo.toml
  • arceos/modules/axfs/src/disk.rs
  • arceos/modules/axfs/src/fs/ext4/fs.rs
  • arceos/modules/axfs/src/fs/ext4/inode.rs
  • arceos/modules/axfs/src/fs/tmpfs.rs
  • crates/ext4plus/src/block_group.rs
  • crates/ext4plus/src/block_size.rs
  • crates/ext4plus/src/dir.rs
  • crates/ext4plus/src/dir_block.rs
  • crates/ext4plus/src/dir_entry.rs
  • crates/ext4plus/src/dir_entry_hash.rs
  • crates/ext4plus/src/dir_htree.rs
  • crates/ext4plus/src/error.rs
  • crates/ext4plus/src/extent.rs
  • crates/ext4plus/src/features.rs
  • crates/ext4plus/src/inode.rs
  • crates/ext4plus/src/iters/file_blocks/block_map.rs
  • crates/ext4plus/src/iters/read_dir.rs
  • crates/ext4plus/src/journal/block_map.rs
  • crates/ext4plus/src/journal/revocation_block.rs
  • crates/ext4plus/src/lib.rs
  • crates/ext4plus/src/metadata.rs
  • crates/ext4plus/src/reader.rs
  • crates/ext4plus/src/resolve.rs
  • crates/ext4plus/src/superblock.rs
  • crates/ext4plus/src/sync.rs
  • crates/ext4plus/src/test_util.rs
  • crates/ext4plus/src/writer.rs
  • crates/ext4plus/src/xattr.rs
  • pulse_core/src/task/process.rs
🚧 Files skipped from review as they are similar to previous changes (23)
  • crates/ext4plus/src/features.rs
  • arceos/modules/axfs/src/fs/ext4/fs.rs
  • crates/ext4plus/src/metadata.rs
  • crates/ext4plus/src/resolve.rs
  • crates/ext4plus/src/block_size.rs
  • crates/ext4plus/src/iters/read_dir.rs
  • crates/ext4plus/src/dir_block.rs
  • crates/ext4plus/src/sync.rs
  • crates/ext4plus/src/test_util.rs
  • crates/ext4plus/src/dir_entry_hash.rs
  • arceos/modules/axfs/src/fs/tmpfs.rs
  • arceos/modules/axfs/src/disk.rs
  • crates/ext4plus/src/journal/revocation_block.rs
  • crates/ext4plus/src/superblock.rs
  • crates/ext4plus/src/error.rs
  • crates/ext4plus/src/dir_entry.rs
  • pulse_core/src/task/process.rs
  • crates/ext4plus/src/dir_htree.rs
  • crates/ext4plus/src/xattr.rs
  • arceos/modules/axfs/src/fs/ext4/inode.rs
  • crates/ext4plus/src/dir.rs
  • crates/ext4plus/src/lib.rs
  • crates/ext4plus/src/block_group.rs

Comment thread crates/ext4plus/src/journal/block_map.rs
Comment thread crates/ext4plus/src/writer.rs Outdated
@muou000

muou000 commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume and full review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

No description provided.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

@muou000 Resuming automatic reviews and re-running a full review on PR #42.

✅ Action performed

Reviews resumed.


Full review finished.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@muou000

muou000 commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@muou000

muou000 commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume and full review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

@muou000 Resuming automatic reviews and re-running a full review on PR #42.

✅ Action performed

Reviews resumed.


Full review finished.

@muou000

muou000 commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

@gemini-code-assist full review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the ext4_rs crate with ext4plus across the workspace and refactors the ext4 filesystem implementation to adapt to the new API, including updates to block caching, directory traversal, and inode management. It also replaces standard spinlocks with interrupt-safe spinlocks in several modules and refactors the VFS in-memory mutex to disable preemption. The code review identified several critical issues, including a deadlock risk in Inode::drop when acquiring the filesystem lock, a potential integer truncation on 32-bit platforms during symlink offset checks, redundant weak pointer traversals in flush_all_disks, and high lock contention in read_offset and write_offset due to repeated lock acquisition in loops. Additionally, the review advised explicitly implementing Drop for MutexGuard to avoid relying on fragile implicit field drop order.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread arceos/modules/axfs/src/fs/ext4/inode.rs
Comment thread arceos/modules/axfs/src/fs/ext4/inode.rs
Comment thread arceos/modules/axfs/src/disk.rs
Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs Outdated
Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs
Comment thread crates/axfs-ng-vfs/src/inmem.rs Outdated
@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

@gemini-code-assist full review

…nel_guard dependency

- Revert PageTableLockManager in `aspace.rs` to use `spin::Mutex` instead of `kspin::SpinNoIrq`.
- Remove `IrqSave` usage in `handle_page_fault` and `handle_page_fault_write` as system calls now run with interrupts disabled.
- Remove `kernel_guard` dependency from `arceos/modules/axmm/Cargo.toml`.

中译:
fix(axmm): 将页表锁还原为 spin::Mutex 并移除了 kernel_guard 依赖

- 将 `aspace.rs` 中的 `PageTableLockManager` 还原为使用 `spin::Mutex` 替换 `kspin::SpinNoIrq`。
- 因为系统调用目前已经关中断执行,移除了 `handle_page_fault` 和 `handle_page_fault_write` 中对 `IrqSave` 的使用。
- 移除了 `arceos/modules/axmm/Cargo.toml` 中引入的 `kernel_guard` 依赖。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
arceos/modules/axfs/src/fs/tmpfs.rs (2)

359-371: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

先拒绝 ... 再检查目录内容。

当前 unlink(".") 会在已持有当前目录 entries 锁后再次锁同一个目录的 entries,容易自旋死锁;同时也不应允许删除特殊目录项。请在 Line 359 入口处直接拒绝 . / ..

建议修复
     fn unlink(&self, name: &str) -> VfsResult<()> {
+        if name == "." || name == ".." {
+            return Err(VfsError::InvalidInput);
+        }
         let dir = inode_as_dir(&self.inode)?;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/tmpfs.rs` around lines 359 - 371, The tmpfs unlink
path in `unlink` must reject special directory entries before taking the
directory locks, because `unlink(".")` can recurse into the current directory’s
own `entries` lock and deadlock. Add an early guard at the start of `unlink` to
immediately return an error for `.` and `..`, then keep the existing
`inode_as_dir`, `entries`, and `NodeContent::Dir` handling unchanged for normal
names.

386-440: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

覆盖目标前校验源/目标类型一致。

rename 现在只对旧目标目录做非空检查;rename(file, empty_dir) 会清空目录并用文件覆盖,rename(dir, file) 也会把文件替换成目录。请在每个覆盖分支中比较 src_entryold_entry 的目录/非目录类型,不一致时返回 IsADirectory / NotADirectory

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/tmpfs.rs` around lines 386 - 440, In tmpfs rename
handling, the overwrite paths in the rename logic inside the tmpfs.rs rename
implementation only check whether the existing destination is a non-empty
directory, but they do not verify that the source and destination entry types
match. Update each branch that replaces an existing `old_entry` with `src_entry`
to compare the source and target node kinds first, and return
`VfsError::IsADirectory` or `VfsError::NotADirectory` when a file would
overwrite a directory or a directory would overwrite a file; keep the existing
non-empty directory check for valid directory-to-directory renames.
arceos/modules/axmm/src/backend/file.rs (1)

404-414: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

未跟踪页缓存帧不能走零拷贝 COW 路径。

contains(frame) == false 时这里把 ref_count 当作 0,但后续 cow_mark_frame_used() / cow_inc_frame_ref() 对未跟踪帧都是 no-op;这样会映射一个无法引用计数的共享页缓存帧,并在失败/回滚路径中交给 dealloc_frame(frame)。请对未跟踪帧改为复制到新分配帧,或返回失败,避免把它纳入 COW 引用管理。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axmm/src/backend/file.rs` around lines 404 - 414, The
zero-copy COW path in the file-backed mapping logic treats untracked frames as
ref_count 0, but `cow_mark_frame_used()` and `cow_inc_frame_ref()` are no-ops
for frames not present in `frame_table()`, so these frames must not be shared
through COW. Update the handling in this `file.rs` path so that when
`frame_table().contains(frame)` is false, the code either allocates a new frame
and copies the contents into it or returns an error instead of proceeding with
COW bookkeeping. Keep the fix localized around the existing `frame_table()`,
`cow_mark_frame_used()`, and `cow_inc_frame_ref()` logic to avoid putting
untracked page-cache frames under reference-count management.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@arceos/modules/axfs/src/fs/tmpfs.rs`:
- Around line 418-420: Prevent directory cycles in tmpfs rename/move by checking
that the destination node is not inside the source directory’s subtree before
updating the ".." entry. In tmpfs::rename (and the related block around
src_entry, dst_node, and the NodeContent::Dir branch), add an ancestor/subtree
validation for directory moves so cases like rename(a, a/b/c) are rejected or
handled like the ext4 backend by refusing cross-parent directory moves, then
only rewrite ".." after that guard passes.

In `@arceos/modules/axmm/src/backend/alloc.rs`:
- Around line 15-20: cow_dec_frame_ref() currently returns true for frames not
present in frame_table(), which can make callers treat unmanaged frames as
safely releasable; change the non-tracked branch to return false so only frames
actually handled by drop_frame_mapping_ref() can be reported as eligible for
release.

In `@arceos/modules/axmm/src/backend/cow.rs`:
- Around line 39-43: The refcount handling in the COW write path is unsafe
because `Cow::`’s old-frame lookup treats an untracked `old_frame` as ref_count
1, which can wrongly take the exclusive upgrade path. Update the logic in
`cow.rs` around the `frame_table().contains(old_frame)` / `get_ref` check so
unknown frames are treated as shared or rejected, and ensure the branch that
upgrades in place only runs when the frame is definitely tracked with a single
reference.

---

Outside diff comments:
In `@arceos/modules/axfs/src/fs/tmpfs.rs`:
- Around line 359-371: The tmpfs unlink path in `unlink` must reject special
directory entries before taking the directory locks, because `unlink(".")` can
recurse into the current directory’s own `entries` lock and deadlock. Add an
early guard at the start of `unlink` to immediately return an error for `.` and
`..`, then keep the existing `inode_as_dir`, `entries`, and `NodeContent::Dir`
handling unchanged for normal names.
- Around line 386-440: In tmpfs rename handling, the overwrite paths in the
rename logic inside the tmpfs.rs rename implementation only check whether the
existing destination is a non-empty directory, but they do not verify that the
source and destination entry types match. Update each branch that replaces an
existing `old_entry` with `src_entry` to compare the source and target node
kinds first, and return `VfsError::IsADirectory` or `VfsError::NotADirectory`
when a file would overwrite a directory or a directory would overwrite a file;
keep the existing non-empty directory check for valid directory-to-directory
renames.

In `@arceos/modules/axmm/src/backend/file.rs`:
- Around line 404-414: The zero-copy COW path in the file-backed mapping logic
treats untracked frames as ref_count 0, but `cow_mark_frame_used()` and
`cow_inc_frame_ref()` are no-ops for frames not present in `frame_table()`, so
these frames must not be shared through COW. Update the handling in this
`file.rs` path so that when `frame_table().contains(frame)` is false, the code
either allocates a new frame and copies the contents into it or returns an error
instead of proceeding with COW bookkeeping. Keep the fix localized around the
existing `frame_table()`, `cow_mark_frame_used()`, and `cow_inc_frame_ref()`
logic to avoid putting untracked page-cache frames under reference-count
management.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 234cd2a9-6447-4505-a75f-779e05565ba9

📥 Commits

Reviewing files that changed from the base of the PR and between 1314486 and 2993624.

📒 Files selected for processing (12)
  • arceos/modules/axfs/src/disk.rs
  • arceos/modules/axfs/src/fs/ext4/fs.rs
  • arceos/modules/axfs/src/fs/ext4/inode.rs
  • arceos/modules/axfs/src/fs/ext4/mod.rs
  • arceos/modules/axfs/src/fs/tmpfs.rs
  • arceos/modules/axmm/src/backend/alloc.rs
  • arceos/modules/axmm/src/backend/cow.rs
  • arceos/modules/axmm/src/backend/file.rs
  • crates/axfs-ng-vfs/src/inmem.rs
  • pulse_core/src/flock.rs
  • pulse_core/src/net/mod.rs
  • pulse_core/src/task/process.rs
✅ Files skipped from review due to trivial changes (1)
  • pulse_core/src/flock.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • arceos/modules/axfs/src/fs/ext4/fs.rs
  • pulse_core/src/task/process.rs
  • arceos/modules/axfs/src/fs/ext4/inode.rs
  • arceos/modules/axfs/src/fs/ext4/mod.rs

Comment thread arceos/modules/axfs/src/fs/tmpfs.rs
Comment thread arceos/modules/axmm/src/backend/alloc.rs
Comment thread arceos/modules/axmm/src/backend/cow.rs
- Revert Mutex in `axfs/disk.rs`, `fs/devfs.rs`, `fs/loop_dev.rs`, `fs/procfs.rs`, and `fs/tmpfs.rs` from `kspin::SpinNoIrq` back to `spin::Mutex`.
- Revert custom preemption-disabling Mutex wrapper in `axfs-ng-vfs` back to standard `spin::Mutex`.
- Remove `kernel_guard` dependency from `crates/axfs-ng-vfs/Cargo.toml`.

中译:
fix(fs, vfs): 将文件系统和 VFS 层所有的不必要锁还原为 spin::Mutex

- 将 `axfs/disk.rs`、`fs/devfs.rs`、`fs/loop_dev.rs`、`fs/procfs.rs` 和 `fs/tmpfs.rs` 中的 `kspin::SpinNoIrq` 还原回原生的 `spin::Mutex`。
- 将 `axfs-ng-vfs` 中的自定义关闭抢占 Mutex 包装器还原回标准的 `spin::Mutex`。
- 移除了 `crates/axfs-ng-vfs/Cargo.toml` 中引入的 `kernel_guard` 依赖。
@muou000
muou000 force-pushed the feat-replace-ext4_rs-with branch from 1da1b9a to b1a745a Compare June 27, 2026 05:39
…tmpfs and memory backend

- axfs/tmpfs: Prevent self-lock deadlock in `unlink` by rejecting `.` and `..` early.
- axfs/tmpfs: Prevent directory cycles in `rename` for directory moves by checking the ancestor chain.
- axfs/tmpfs: Add type-matching check in `rename` when replacing/overwriting destination entries.
- axmm/alloc: Return `false` in `cow_dec_frame_ref` for untracked frames to prevent incorrect deallocation.
- axmm/cow: Restrict in-place COW upgrade to definitely tracked pages with reference count 1; treat untracked pages as shared.
- axmm/file: Allocate a new frame and copy content in zero-copy COW fault path for untracked page cache frames to avoid incorrect refcount management.

中文摘要:
- axfs/tmpfs: 在 `unlink` 开始时,早期拒绝 `.` 和 `..` 操作以避免自锁引发死锁。
- axfs/tmpfs: 在 `rename` 移动目录前增加祖先校验,防止移动父目录到其子目录下产生目录环。
- axfs/tmpfs: 在 `rename` 覆盖目标条目时增加节点类型校验,防止不匹配覆盖(如文件覆盖目录)。
- axmm/alloc: `cow_dec_frame_ref` 针对非跟踪物理帧返回 `false`,以避免调用方错误释放这些帧。
- axmm/cow: 原地写权限升级时严格要求物理帧在分配器中被跟踪且引用计数为1,未被跟踪帧均视作共享状态。
- axmm/file: 在文件映射 COW 的读/执行故障路径中,如物理帧未被分配器跟踪,则分配新帧、拷贝数据并映射,防止将未被跟踪的 page cache 帧置于引用计数管理下。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
arceos/modules/axfs/src/fs/tmpfs.rs (2)

380-389: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

在 rename 入口拒绝 "."".."

unlink 已阻止特殊目录项,但 rename(".", x)rename("..", x) 或覆盖 ".." 仍会改写目录结构,破坏 tmpfs 的父子关系不变量。建议在 rename 开头统一返回 InvalidInput

建议修复
 fn rename(&self, src_name: &str, dst_dir: &DirNode, dst_name: &str) -> VfsResult<()> {
+    if src_name == "." || src_name == ".." || dst_name == "." || dst_name == ".." {
+        return Err(VfsError::InvalidInput);
+    }
     let dst_node = dst_dir.downcast::<Self>()?;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/tmpfs.rs` around lines 380 - 389, The tmpfs rename
path in fn rename currently allows special entries like "." and ".." to be
renamed or overwritten, which can break directory parent/child invariants. Add
an early guard at the start of rename (before dst_dir.downcast::<Self>() and
lookup logic) to reject src_name or dst_name being "." or ".." and return
InvalidInput consistently, matching the protection already applied in unlink.

35-40: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

arceos/modules/axfs/src/fs/tmpfs.rs:380-528rename() 里拒绝 . / ..
src_namedst_name 还没排除这两个保留名;这会破坏目录项和 .. 父指针,后续遍历/删除可能进入不一致状态。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/tmpfs.rs` around lines 35 - 40, The tmpfs rename
path needs to explicitly reject the reserved names “.” and “..” for both
src_name and dst_name, since allowing them can corrupt directory entries and
parent links. Update the rename() logic in Tmpfs to validate these names before
proceeding, using the existing src_name/dst_name handling in the rename flow,
and return an appropriate error when either side matches a reserved entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@arceos/modules/axfs/src/fs/tmpfs.rs`:
- Around line 380-389: The tmpfs rename path in fn rename currently allows
special entries like "." and ".." to be renamed or overwritten, which can break
directory parent/child invariants. Add an early guard at the start of rename
(before dst_dir.downcast::<Self>() and lookup logic) to reject src_name or
dst_name being "." or ".." and return InvalidInput consistently, matching the
protection already applied in unlink.
- Around line 35-40: The tmpfs rename path needs to explicitly reject the
reserved names “.” and “..” for both src_name and dst_name, since allowing them
can corrupt directory entries and parent links. Update the rename() logic in
Tmpfs to validate these names before proceeding, using the existing
src_name/dst_name handling in the rename flow, and return an appropriate error
when either side matches a reserved entry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: af538935-7de9-4da3-904b-3c93929a52d8

📥 Commits

Reviewing files that changed from the base of the PR and between 2993624 and af12dbb.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • arceos/modules/axfs/src/disk.rs
  • arceos/modules/axfs/src/fs/tmpfs.rs
  • arceos/modules/axmm/src/backend/alloc.rs
  • arceos/modules/axmm/src/backend/cow.rs
  • arceos/modules/axmm/src/backend/file.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • arceos/modules/axfs/src/disk.rs

@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

@gemini-code-assist review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the ext4_rs crate with ext4plus to support write operations and async execution, alongside introducing a new RwLock implementation in axsync and updating TmpFilesystem and axmm memory mapping. The code review feedback highlights critical concurrency issues in SeekableDisk::read and write where releasing the lock before I/O operations can lead to race conditions and inconsistent cursor states. Additionally, performance optimizations are suggested in Ext4Disk's read/write offset methods to check the flushing_evicted map, avoiding redundant disk reads for blocks currently being flushed.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread arceos/modules/axfs/src/disk.rs Outdated
Comment thread arceos/modules/axfs/src/disk.rs Outdated
Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs
Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs
@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

@gemini-code-assist review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the ext4_rs crate with ext4plus across the workspace, updating the filesystem implementation to support asynchronous operations, block caching, and deferred deletions. It also introduces a new task-yielding RwLock in axsync, refactors TmpFilesystem to prevent reference cycles, and resolves memory mapping bugs in axmm. A critical feedback comment points out a potential race condition and data corruption bug in the newly introduced Ext4Disk cache eviction and flushing logic, where concurrent reads and writes can cause dirty blocks to be prematurely removed from the flushing_evicted map.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs Outdated
Retrieve and remove the block from flushing_evicted immediately on cache miss hit to avoid redundant retention and heap copy allocations.

Verify the cache block content matches the written block before removing it from flushing_evicted after disk write completes, preventing newer evicted block versions from being mistakenly deleted by older write-back threads.
@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

@gemini-code-assist review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the ext4_rs crate with ext4plus to add async and multi-threaded ext4 filesystem support, introducing features like deferred unlinked file deletion, active inode tracking, and a new block cache mechanism with block merging. It also adds a multitasking-friendly RwLock implementation to axsync, refactors tmpfs for safer reference handling, and updates memory management reference counting. The review feedback suggests implementing try_read and try_write on the new RwLock for API compatibility and non-blocking contexts, and limiting the maximum number of merged blocks per write in the ext4 block cache to prevent exceeding block device driver transfer limits.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread arceos/modules/axsync/src/rwlock.rs
Comment thread arceos/modules/axfs/src/fs/ext4/mod.rs Outdated
…t4 block cache limits

- Implement try_read and try_write on axsync::RwLock for API compatibility with spin::RwLock.

- Limit the maximum number of merged dirty blocks to 32 (128 KiB) in ext4 flush_disk to avoid exceeding block device driver transfer limits.
@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

@gemini-code-assist reiview

@gemini-code-assist

Copy link
Copy Markdown

It looks like you've been trying to invoke a review command multiple times. If you are looking for a full review of the current state of the pull request, please use the command /gemini review instead of @gemini-code-assist review or variations like reiview.

If you have already received a review and are looking for specific feedback on a change, please ensure you are tagging me in a comment on the specific line or file you would like me to look at.

For a full list of available commands, you can always use /gemini help.

@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@muou000

muou000 commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
arceos/modules/axfs/src/fs/tmpfs.rs (1)

35-40: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

保留根目录的强引用,避免 root_dir() 首次访问崩溃。

Line 39 只保存 root_dir.downgrade()root_dir 局部强引用在 new() 返回后释放,Line 59 的 upgrade() 可能失败并触发 Line 60 的 expect。建议让 TmpFilesystem::rootDirEntry 强引用,或由 Filesystem::new 明确接管根目录强引用。

建议修复方向
- root: OnceCell<WeakDirEntry>,
+ root: OnceCell<DirEntry>,

- let _ = fs.root.set(root_dir.downgrade());
+ let _ = fs.root.set(root_dir);

  fn root_dir(&self) -> DirEntry {
      self.root
          .get()
-         .and_then(WeakDirEntry::upgrade)
+         .cloned()
          .expect("tmpfs root directory should be alive while filesystem is mounted")
  }

Also applies to: 56-60

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/fs/tmpfs.rs` around lines 35 - 40, TmpFilesystem::new
currently stores only a downgraded weak reference for the root directory, so the
root DirEntry can be dropped after construction and make TmpFilesystem::root_dir
fail on first use. Update the ownership flow around TmpFilesystem::root,
DirEntry::new_dir, and Filesystem::new so the filesystem keeps a strong root
DirEntry alive for the lifetime of the tmpfs. If you keep the weak reference
internally, ensure Filesystem::new or the root field also retains the strong
reference before root_dir() calls upgrade() and expect().
arceos/modules/axfs/src/disk.rs (1)

127-147: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

收集 flusher 时继续清理失效的 Weak

flush_all_disks() 释放全局锁后再执行 flush 是好的,但如果新实现只 upgrade/收集存活项而不 retainDISK_FLUSHERS 会在磁盘反复创建/销毁后持续累积 dead Weak,后续全局 flush 会越来越慢。建议在锁内同时 retain 存活项并收集强引用。

建议修复方向
+ let flushers = {
+     let mut registered = DISK_FLUSHERS.lock();
+     let mut flushers = alloc::vec::Vec::new();
+     registered.retain(|weak| {
+         if let Some(flusher) = weak.upgrade() {
+             flushers.push(flusher);
+             true
+         } else {
+             false
+         }
+     });
+     flushers
+ };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@arceos/modules/axfs/src/disk.rs` around lines 127 - 147, `flush_all_disks()`
still needs to prune dead entries while collecting live flushers: the current
`DISK_FLUSHERS` handling should both `retain` only upgradeable `Weak` values and
gather strong `Arc<dyn DiskFlushable>` references in the same locked section.
Update the collection logic around `DISK_FLUSHERS.lock()`, `retain`, and
`flush_disk()` so stale weak references are removed before releasing the lock,
preventing the global flusher list from growing with dead entries over time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@arceos/modules/axfs/src/disk.rs`:
- Around line 127-147: `flush_all_disks()` still needs to prune dead entries
while collecting live flushers: the current `DISK_FLUSHERS` handling should both
`retain` only upgradeable `Weak` values and gather strong `Arc<dyn
DiskFlushable>` references in the same locked section. Update the collection
logic around `DISK_FLUSHERS.lock()`, `retain`, and `flush_disk()` so stale weak
references are removed before releasing the lock, preventing the global flusher
list from growing with dead entries over time.

In `@arceos/modules/axfs/src/fs/tmpfs.rs`:
- Around line 35-40: TmpFilesystem::new currently stores only a downgraded weak
reference for the root directory, so the root DirEntry can be dropped after
construction and make TmpFilesystem::root_dir fail on first use. Update the
ownership flow around TmpFilesystem::root, DirEntry::new_dir, and
Filesystem::new so the filesystem keeps a strong root DirEntry alive for the
lifetime of the tmpfs. If you keep the weak reference internally, ensure
Filesystem::new or the root field also retains the strong reference before
root_dir() calls upgrade() and expect().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 180ca281-972d-4646-8863-8c0c7cf6ae77

📥 Commits

Reviewing files that changed from the base of the PR and between af12dbb and d8e63eb.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • .cargo/config.toml
  • arceos/modules/axfs/src/disk.rs
  • arceos/modules/axfs/src/fs/ext4/mod.rs
  • arceos/modules/axfs/src/fs/tmpfs.rs
  • arceos/modules/axsync/src/rwlock.rs
  • cargo/config.toml
  • crates/ext4plus/Cargo.toml
✅ Files skipped from review due to trivial changes (1)
  • crates/ext4plus/Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • arceos/modules/axfs/src/fs/ext4/mod.rs

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the ext4_rs crate with the newer ext4plus library, updating the ext4 filesystem driver in ArceOS to support read-write operations, block size detection, and deferred deletion of unlinked files. It also introduces a multitask-aware RwLock in axsync, refactors disk flushing and filesystem caching to avoid lock contention, fixes reference cycle issues in tmpfs, and improves memory management safety in axmm by validating frame table membership. I have no further feedback to provide as there are no review comments to assess.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@muou000
muou000 merged commit 6c4a33a into main Jun 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant