mirror of
https://github.com/deepseek-ai/3FS.git
synced 2026-11-05 00:47:47 +00:00
[GH-ISSUE #424] read_file masks setup failures and leaks partial resources #243
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
deepseek-ai/3FS#243
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @OllieinCanada on GitHub (Aug 24, 2026).
Original GitHub issue: https://github.com/deepseek-ai/3FS/issues/424
Summary
hf3fs_fuse.io.read_file()assumes every setup step completed when itsfinallyblock runs. If setup fails early, cleanup raisesUnboundLocalError,replaces the useful original exception, and can skip releasing resources that
were already acquired.
Reproduction
The behavior is deterministic without a 3FS mount by replacing the native
binding with a stub:
os.open()raiseFileNotFoundError.read_file().UnboundLocalErrorfor the unassigned localfdinstead of theoriginal file error.
The same masking happens when
register_fd(),SharedMemory(),make_iovec(),or
make_ioring()fails. In themake_iovec()case,del iorraises beforeshm.close()andshm.unlink()run, so the partially created shared memory isnot released by this function.
This is separate from #291's underlying
os.symlink()failure: a failure fromthat call currently enters this broken cleanup path and can be replaced by an
unrelated
UnboundLocalError.Expected behavior
read_file()should preserve the original setup error and release only thefile descriptor, native registration, iovec/ioring, and shared-memory resources
that were successfully acquired.
The regression can be covered with a host-only Python test using stubbed native
bindings; no 3FS mount, RDMA device, or external service is required.
@PerryLink commented on GitHub (Sep 13, 2026):
Confirmed on main (hf3fs_fuse/io.py): read_file's finally block unconditionally references fd, ior, iov and shm (deregister_fd(fd) / os.close(fd) / del ior / del iov / shm.close() / shm.unlink()), but all four are assigned only inside the try. If os.open() raises, the finally runs with fd unassigned - UnboundLocalError replaces the original error; if make_iovec() fails,
del iorraises before shm.close()/shm.unlink() run, leaking the SharedMemory segment. Your stub-based repro is the right shape and a host-only test needs no mount. The fix is to track each acquired resource (or default them upfront) and release only what was actually acquired. The regression also connects to #291: its os.symlink() failure enters this same broken cleanup path.