vfs: names up to 255 bytes and paths up to 4096, like Linux

Every path component was copied into a DIRSIZ buffer and every path
into a MAXPATH one, so names were cut at 29 bytes and paths at 127
without an error. Two names sharing their first 29 bytes opened the
same file, on SchFS and FAT alike, though both hold 255.

VFS_NAME_MAX (255) and VFS_PATH_MAX (4096) are the limits now, and
anything longer is ENAMETOOLONG. namex_from() takes its path buffers
from kalloc(), a page each, rather than putting two of them on an 8 KB
kernel stack. The v1 format still stores DIRSIZ bytes, and refuses a
longer name instead of matching on its first 30.

Checked: 255-byte names on SchFS and FAT (fsck.fat clean, and the FAT
name answers to its uppercase form), 256 refused, a 200-byte path and a
link to it, and no pages lost over 700 lookups through links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-23 11:17:28 +02:00
commit 67db42b460
7 changed files with 121 additions and 38 deletions

View file

@ -92,9 +92,6 @@ directory ends at the first entry whose first byte is zero.
## What it does not do
- **Names longer than 29 bytes.** FAT allows 255 UTF-16 units, but the VFS's
`DIRSIZ` caps a path component, so a longer name is cut short on the way in.
Lifting that is a VFS change.
- **Permissions and owners.** Every file shows as `0755 root:root`, like Linux
vfat with its defaults. The read-only attribute is kept but not enforced.
- **exFAT.** Large SD cards (SDXC, over 32 GB) ship with it. It is a different

View file

@ -288,6 +288,20 @@ held alive by an `nlink` bump.
Renaming a *directory* is still refused with `EISDIR`, and so is replacing one:
both need the `..` fixup and the ancestor-loop check that are not written.
## Names and paths
A name is at most 255 bytes and a path 4096 including its NUL, Linux's
`NAME_MAX` and `PATH_MAX` (`VFS_NAME_MAX` and `VFS_PATH_MAX` in
`include/file.h`). Longer is `ENAMETOOLONG`. A filesystem may hold less: the v1
format stores `DIRSIZ` bytes and refuses longer names rather than matching on
their first 30.
Both limits used to be the copy buffers: every component went through a
`DIRSIZ` array and every path through a `MAXPATH` one, so a name was cut at 29
bytes and a path at 127, silently. Two files sharing their first 29 bytes were
one file. The path buffers are a page each now, from `kalloc()`, since two of
them would be most of a kernel stack.
## Symlinks
Followed the way Linux follows them, in `namex_from()`. A link in the middle of

View file

@ -176,7 +176,9 @@ mount. It is set where it is because the page-pointer vector lives inside
These are VFS and driver limits rather than SchFS ones:
- `MAXPATH` caps a path at **128 bytes**.
- A path is at most **4096 bytes** and a name **255**, Linux's `PATH_MAX` and
`NAME_MAX` (`VFS_PATH_MAX`, `VFS_NAME_MAX`). Longer is `ENAMETOOLONG`. Both
used to be cut short without a word, at 128 and 29.
- `NMOUNT` allows **8** mounts.
- The IDE driver handles the primary channel only: **2** ATA devices.
- The IDE driver uses LBA48 past 128 GiB, so the disk is not the limit there.