arnavsharma990 opened a new pull request, #20101:
URL: https://github.com/apache/nuttx/pull/20101
## Summary
Implements POSIX-style unlink semantics for FAT: when an open file is
unlinked, its directory entry is removed but its FAT cluster chain is kept
until the last open reference is closed (fixes #20037).
- Adds a FAT-local canonical/shared open-file object (`struct fat_shared_s`).
- Shared state contains reference count, pending-delete state, file size,
starting cluster, and directory-entry location.
- Multiple open handles and `dup()` share this canonical state.
- Directory-entry location is used for identity rather than relying only on
the starting cluster.
- Correctly handles empty files, multiple opens, `dup()`, rename,
directory/cluster reuse, and operations after unlink.
- Pending deleted files do not write metadata back to deleted or reused
directory entries.
- `fstat()`, truncate, sync, and subsequent writes continue using shared
in-memory state.
- The implementation is intentionally scoped to `fs/fat` and does NOT
introduce a generic VFS inode mechanism.
- Fixes #20037.
## Impact
Changes FAT unlink behavior for files that are still open:
`unlink()`/`rmdir()` now remove the name immediately but defer cluster
reclamation until the final open reference is closed. Files that are not open
are removed exactly as before (immediate chain free). Open handles keep working
across unlink/rename via the shared in-memory state, and a directory-entry slot
reused by a new file can never alias the unlinked file. No VFS API changes; all
changes are confined to `fs/fat/fs_fat32.c`, `fs/fat/fs_fat32.h`,
`fs/fat/fs_fat32dirent.c`, and `fs/fat/fs_fat32util.c`.
## Testing
Host:
- macOS
- NuttX simulator with `sim:nsh`
- GCC 15 / G++ 15
- CMake + Ninja
- Real VFAT filesystem mounted/used through `/tmp`
Build:
CC=gcc-15 CXX=g++-15 cmake -B build -DBOARD_CONFIG=sim:nsh \
-DNUTTX_APPS_DIR=../nuttx-apps -GNinja
cmake --build build -j8
Build result: 1228/1228 targets compiled and linked successfully.
Regression test:
fat_unlink_test /tmp
All 9 tests passed:
PASS test_baseline
PASS test_open_unlink_read_close
PASS test_empty_unlink_write
PASS test_twice_open_shared
PASS test_dup_unlink
PASS test_rename_open_unlink
PASS test_reuse_after_unlink
PASS test_unlink_truncate
PASS test_unlink_fstat
ALL TESTS PASSED
Verified `/tmp` was empty after the tests, and `df` showed 985/985 blocks
free afterward. Deferred reclamation was explicitly checked by comparing free
space while handles remained open and after the last close. `nxstyle` showed
only pre-existing violations, and `git show --check HEAD` passed. The final
commit contains only these four files: `fs/fat/fs_fat32.c`,
`fs/fat/fs_fat32.h`, `fs/fat/fs_fat32dirent.c`, `fs/fat/fs_fat32util.c`.
Note: running the simulator on this host required a temporary local-only
workaround in `fs/vfs/fs_dup2.c` (unrelated pre-existing boot issue); it was
reverted before the final commit and is not part of this PR. Testing was done
on the simulator only, not on hardware targets.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]