Skip to content

feat(devfs): Improve the devfs of PulseOS#1

Merged
muou000 merged 2 commits into
mainfrom
devfs
Apr 22, 2026
Merged

feat(devfs): Improve the devfs of PulseOS#1
muou000 merged 2 commits into
mainfrom
devfs

Conversation

@muou000
Copy link
Copy Markdown
Owner

@muou000 muou000 commented Apr 22, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added block device support in /dev for direct disk I/O access.
    • Introduced umask syscall to control default file permission masks per-process.
    • Enhanced mounted filesystem tracking for improved mount/unmount operations.
  • Refactor

    • Generalized filesystem architecture to support flexible block device implementations.

Copilot AI review requested due to automatic review settings April 22, 2026 07:04
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR introduces process-level umask support for POSIX file creation, generalizes block device handling via generic BlockDriverOps traits and SharedBlockDevice wrapper, adds block device support to devfs, implements mounted mountpoint tracking, and refactors mount/umount logic.

Changes

Cohort / File(s) Summary
Process Umask Support
pulse_core/src/task/process.rs, pulse_syscalls/src/handler.rs, pulse_syscalls/src/impls/misc.rs
Added atomic umask field (initialized to 0o022) with getter/setter methods and syscall dispatcher mapping for umask operations.
Block Device Abstraction
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/fs/fat/fs.rs
Introduced SharedBlockDevice clonable wrapper and generalized SeekableDisk/Ext4Disk to accept generic BlockDriverOps trait implementations; removed public position() method from SeekableDisk.
DevFS Block Device Support
arceos/modules/axfs/src/fs/devfs.rs, arceos/modules/axfs/src/fs/mod.rs
Added block device node support via BlockDeviceSpec, NodeContent::BlockDevice, and offset-based disk I/O; updated constructor to accept and register device list.
POSIX API and Mkdir
arceos/api/arceos_posix_api/src/imp/fs.rs, pulse_syscalls/src/impls/fs/path.rs
Updated mkdir logic to check path existence, compute effective permissions via process umask, and apply NodePermission mappings; refactored permission helpers.
Mount and Mountpoint Management
arceos/modules/axfs/src/lib.rs, pulse_syscalls/src/impls/fs/path.rs
Introduced global MOUNTED_MOUNTPOINTS registry with registration/lookup/unregistration APIs; refactored sys_mount/sys_umount2 to query registry and validate mount sources via candidate list.
File I/O and Type Handling
arceos/modules/axfs/src/highlevel/file.rs, arceos/modules/axfs/src/fs/ext4/inode.rs, pulse_core/src/fd_table.rs
Extended non-cacheable device types to include BlockDevice; removed debug logging statements; applied formatting consolidations.
Documentation and Configuration
records/ai-logs/Reviewer/2026-04-22_..._review.md, records/logs/2026.4.21.md, records/logs/2026.4.22.md, src/testcode_cmd.sh
Added devfs/procfs/tmpfs review documentation, changelog entries, and updated test script with filesystem mount setup.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant VFS as VFS/Mountpoint
    participant Registry as MOUNTED_MOUNTPOINTS
    participant Filesystem as Target Filesystem

    Client->>VFS: sys_mount(source, target, type)
    VFS->>Registry: lookup_mounted_mountpoint(target)
    alt already mounted
        Registry-->>VFS: Some(mountpoint)
        VFS-->>Client: EBUSY
    else not mounted
        Registry-->>VFS: None
        VFS->>Filesystem: lookup_mountable_filesystem(source_candidates)
        Filesystem-->>VFS: filesystem handle
        VFS->>VFS: mount operation
        VFS->>Registry: register_mounted_mountpoint(target, mp)
        Registry-->>VFS: ok
        VFS-->>Client: success
    end

    Client->>VFS: sys_umount2(target)
    VFS->>Registry: lookup_mounted_mountpoint(target)
    alt mounted
        Registry-->>VFS: Some(mountpoint)
        VFS->>VFS: perform unmount
        VFS->>Registry: unregister_mounted_mountpoint(target)
        Registry-->>VFS: true
        VFS-->>Client: success
    else not mounted
        Registry-->>VFS: None
        VFS-->>Client: EINVAL
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 With whiskers held high and a umask in paw,
Block devices now dance through the devfs's law,
Mountpoints are tracked, no more lost in the fray,
Generic and shared, they all find their way! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main purpose of this PR: comprehensive improvements to the devfs (device filesystem) implementation in PulseOS, including new block device support, shared device wrappers, generic block driver interfaces, and related filesystem infrastructure updates.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devfs

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

@muou000
Copy link
Copy Markdown
Owner Author

muou000 commented Apr 22, 2026

@codex[agent]

@Codex
Copy link
Copy Markdown

Codex AI commented Apr 22, 2026

@codex[agent]

Hi—could you clarify what you’d like me to adjust here or any specific concerns with the devfs changes? I’ll address them right away once I have details.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@muou000 muou000 merged commit 43745a1 into main Apr 22, 2026
3 of 4 checks passed
@chatgpt-codex-connector
Copy link
Copy Markdown

Summary

  • I checked the trigger (@codex[agent]), PR metadata, and comments, and there are currently no concrete requested code changes (no reviewer change request or specific fix task to implement).
  • I verified the working tree is clean on the current branch (work), so there was nothing to commit and no follow-up PR to create.

Testing

  • git status --short --branch (shows clean branch: ## work)

View task →

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves PulseOS’s devfs/mount plumbing by exposing block devices under /dev/vd*, tracking mounted mountpoints more explicitly in axfs, and wiring process umask into mkdir behavior.

Changes:

  • Add /dev/vd* block device nodes in devfs and allow direct non-cached block I/O to them.
  • Rework mount bookkeeping by storing mounted mountpoints in axfs and enhancing mount source matching (e.g., /dev/vda1 → candidate lookup).
  • Add umask(2) syscall support and apply umask when creating directories.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/testcode_cmd.sh Ensure /fs exists before mounting test filesystem.
records/logs/2026.4.22.md Add development log entry for /dev/vdx + mount logic changes.
records/logs/2026.4.21.md Add development log entry (formatting + task stack size note).
records/ai-logs/Reviewer/2026-04-22_axfs_devfs_procfs_tmpfs_review.md Add AI review log document for fs work.
pulse_syscalls/src/impls/misc.rs Add sys_umask syscall implementation.
pulse_syscalls/src/impls/fs/path.rs Apply umask to mkdirat, revise mount/umount logic and source resolution.
pulse_syscalls/src/handler.rs Dispatch Sysno::umask to implementation.
pulse_core/src/task/process.rs Add per-process umask storage + accessors and inheritance on fork.
pulse_core/src/fd_table.rs Remove verbose read_dirents64 logging.
arceos/modules/axfs/src/lib.rs Register mounted mountpoints; register mountable devices under both deviceN and /dev/vdX; pass block devices into devfs.
arceos/modules/axfs/src/highlevel/file.rs Treat block devices as non-cacheable for open options.
arceos/modules/axfs/src/fs/mod.rs Generalize block-device filesystem creation over BlockDriverOps; pass block device specs to devfs.
arceos/modules/axfs/src/fs/fat/fs.rs Update FAT fs constructor to accept generic BlockDriverOps.
arceos/modules/axfs/src/fs/ext4/mod.rs Generic-ize ext4 disk wrapper over BlockDriverOps.
arceos/modules/axfs/src/fs/ext4/inode.rs Formatting/cleanup; no functional change intended.
arceos/modules/axfs/src/fs/ext4/fs.rs Update ext4 fs constructor to accept generic BlockDriverOps.
arceos/modules/axfs/src/fs/devfs.rs Add block-device nodes + I/O handling for them; refactor device content types.
arceos/modules/axfs/src/disk.rs Introduce SharedBlockDevice wrapper and generic SeekableDisk.
arceos/api/arceos_posix_api/src/imp/fs.rs Apply umask and EEXIST handling to sys_mkdir.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

let len = min(buf.len() as u64, size - offset) as usize;
let mut disk = block.disk.lock();
disk.set_position(offset).map_err(map_dev_err)?;
disk.write(&buf[..len]).map_err(map_dev_err)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

Writes to block-device nodes can remain buffered in SeekableDisk (write_buffer_dirty stays true when the write ends mid-block). Since this write_at path does not flush after the write, and DevNode::sync() is currently a no-op, data written to /dev/vd* may not reach the underlying device until a later reposition/read/write happens. Consider flushing the SeekableDisk after completing a block-device write_at (or implementing sync() to flush for block devices and ensuring it is invoked on close/fsync).

Suggested change
disk.write(&buf[..len]).map_err(map_dev_err)
let written = disk.write(&buf[..len]).map_err(map_dev_err)?;
disk.flush().map_err(map_dev_err)?;
Ok(written)

Copilot uses AI. Check for mistakes.
Comment on lines +263 to +267
Ok(mountpoint) => {
MOUNTED_TARGETS.lock().insert(target_path.clone());
axfs::register_mounted_mountpoint(&target_path, mountpoint);
axfs::register_mount(&source, &target_path, &fstype, "rw,relatime");
let _ = pulse_core::task::current_process().map(|process| process.save_fs_context());
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

sys_mount/sys_umount2 now use axfs::register_mounted_mountpoint()/lookup_mounted_mountpoint() as the source of truth for mounted targets, but this code still updates the separate MOUNTED_TARGETS set. Keeping two independent registries risks divergence over time and makes mount state harder to reason about. Consider removing MOUNTED_TARGETS here (or clearly defining which registry is authoritative and deriving the other from it).

Copilot uses AI. Check for mistakes.
Comment on lines +718 to +727
NodeContent::BlockDevice(block) => {
let size = inode.metadata.lock().size;
if offset >= size {
return Ok(0);
}
let len = min(buf.len() as u64, size - offset) as usize;
let mut disk = block.disk.lock();
disk.set_position(offset).map_err(map_dev_err)?;
disk.read(&mut buf[..len]).map_err(map_dev_err)
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

This change adds new externally visible behavior (auto-populating /dev with block device nodes and supporting reads/writes via devfs). There are existing axfs tests under arceos/modules/axfs/tests, but nothing here exercises the new devfs block-device semantics (e.g., read/write correctness and flush/sync behavior). Adding a focused regression test would help prevent silent data-loss bugs and ensure /dev/vd* nodes behave consistently.

Copilot uses AI. Check for mistakes.
@muou000 muou000 deleted the devfs branch April 22, 2026 07:10
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94b29dbb0a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let len = min(buf.len() as u64, size - offset) as usize;
let mut disk = block.disk.lock();
disk.set_position(offset).map_err(map_dev_err)?;
disk.write(&buf[..len]).map_err(map_dev_err)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Flush block-device writes before returning

In DevNode::write_at's NodeContent::BlockDevice arm, the code returns after disk.write(...) without a flush. SeekableDisk keeps partial-block writes buffered (write_buffer_dirty) until a later set_position/flush, and DevNode::sync is currently a no-op, so a single unaligned write to /dev/vd* can be lost or remain invisible to other consumers until unrelated later I/O touches that node. This is a real data-integrity issue for short writes (e.g., metadata/superblock updates).

Useful? React with 👍 / 👎.

}

if MOUNTED_TARGETS.lock().contains(&target_path) {
if axfs::lookup_mounted_mountpoint(&target_path).is_some() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep root mountpoint marked busy in mount checks

sys_mount now rejects busy targets only via axfs::lookup_mounted_mountpoint, but root (/) is never inserted into that map during filesystem init (only register_mount is called for /). This allows mount(..., "/", ...) to over-mount the root unexpectedly; combined with sys_umount2 hard-rejecting "/", the original root becomes inaccessible for the remainder of the session.

Useful? React with 👍 / 👎.

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.

3 participants