#424·3FS

read_file masks setup failures and leaks partial resources

Author: OllieinCanadaCreated Aug 24, 2026Updated Sep 13, 2026

Summary

hf3fs_fuse.io.read_file() assumes every setup step completed when its finally block runs. If setup fails early, cleanup raises UnboundLocalError, 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:

  1. Make os.open() raise FileNotFoundError.
  2. Call read_file().
  3. Observe UnboundLocalError for the unassigned local fd instead of the original file error.

The same masking happens when register_fd(), SharedMemory(), make_iovec(), or make_ioring() fails. In the make_iovec() case, del ior raises before shm.close() and shm.unlink() run, so the partially created shared memory is not released by this function.

This is separate from #291's underlying os.symlink() failure: a failure from that 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 the file 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.