fat_path2dirname() marks a parsed name as needing long file name
entries by clearing the first byte of the short name buffer, and
fat_dirnamewrite() writes the long name entries only while that marker
survives. Since commit bc9e1ffb01, a name short enough to fit the 8.3
form is speculatively re-parsed as a short name, and the re-parse
fills the short name buffer with spaces before it examines a single
character. When it then rejects the name (lower case, for example) the
spaces stay behind, the marker is gone, and the file is created with
eleven spaces for a name: no long name entries, a blank alias.
Every such file aliases to every other, since every rejected name
converts to the same blank entry. Create a.txt, then create big1, and
both names now open one file; a directory of them lists as a single
nameless entry. Any application that writes two lowercase short-named
files and reads the first back gets the second's contents.
Restore the marker when the speculative parse fails.
Tested on FAT32 with CONFIG_FAT_LFN: lower case, upper case, mixed
case and over-length names now create distinct, correctly named
entries that survive unmount and reboot; upper case 8.3 names still
produce plain short entries with no long name chain.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
Align the NuttX open(2) flag constants with the Linux asm-generic
values so that the FUSE wire protocol and other cross-platform
interfaces work without conversion.
All code that used '(flags & O_RDONLY)' as a bitmask check (always 0
now that O_RDONLY=0) has been updated to use '(flags & O_ACCMODE)'
comparisons.
The NUTTX_O_* constants in include/nuttx/fs/hostfs.h are updated to
match, and the sim hostfs open flag mapping is fixed.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
O_RDOK and O_WROK are non-standard aliases for O_RDONLY and O_WRONLY
respectively. Having two names for the same flag creates confusion,
especially when aligning the flag values with Linux. Remove the
aliases and replace all uses with the standard O_RDONLY/O_WRONLY.
No functional change — O_RDOK was defined as O_RDONLY and O_WROK as
O_WRONLY, so the replacement is a pure text substitution.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Now that time_t is unconditionally 64-bit (signed int64_t) and the
struct timespec fields tv_sec / tv_nsec are wide enough on their own,
the explicit (uint64_t)/(int64_t)/(int) casts that used to guard the
multiplications and subtractions in *_us / *_ms / *_ns helpers are no
longer needed. Drop them to keep the timekeeping math readable and
consistent with the previous sclock_t/time_t cleanup.
In the same spirit, this commit also:
* Normalises the printf-style format specifiers and casts used to
print tv_sec / tv_nsec / tv_usec values across arch/, drivers/,
fs/, sched/ and libs/. The prior code was a mix of
"%d"/"%u"/"%ld"/"%lu"/"%lld"/PRIu32/PRIu64 with matching
(int)/(unsigned long)/(long long)/PRIu* casts; some formats
truncated time_t on 32-bit hosts, others mismatched signedness or
width. Replace all such cases with the portable POSIX-recommended
forms:
- tv_sec (time_t, signed, impl-defined width) -> %jd + (intmax_t)
- tv_nsec (long, signed) -> %ld (no cast)
- tv_usec (suseconds_t / long) -> %ld (no cast)
Add #include <stdint.h> where required.
* Drops a few stale `(FAR const time_t *)&ts.tv_sec` casts and
related `(FAR struct tm *)` / `(const time_t *)` casts in
gmtime_r() / localtime_r() / gmtime() callers; ts.tv_sec is plain
time_t now and the casts only obscured the type.
* Fixes one overflow in fs/procfs/fs_procfscritmon.c where
all_time.tv_sec * 1000000 could overflow on 32-bit time_t before
being multiplied again; cast to uint64_t at the start.
No behavioural change.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Linux creates all files as long file name entries even if they
fit short 8.3 format. This caused issues when deleting or renaming
files as the long file name entry was not recognized and only deleted
it's short file name entry. This basically kept breaking the file
system as subsequent long file name files were not correctly stored.
The typical representation of this issue was long file name being
represented as it's short name alias.
This commit adjusts the LFN/SFN logic a bit - the code now always
fills in long file name and then checks if this could possibly be
a short file entry (we still have to do that because Windows stores
8.3 files as short file entry). This ensures compatibility with
files created both on Linux and Windows.
Signed-off-by: Michal Lenc <michallenc@seznam.cz>
debug.h is a NuttX-specific, non-POSIX header. Placing it in the
top-level include/ directory creates naming conflicts with external
projects that define their own debug.h.
This commit moves the canonical header to include/nuttx/debug.h,
following the NuttX convention for non-POSIX/non-standard headers,
and updates all in-tree references.
A backward-compatibility shim is left at include/debug.h that
emits a deprecation #warning and re-includes <nuttx/debug.h>,
allowing out-of-tree code to continue building while migrating.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
This patch adds support for the FIOC_FILEPATH ioctl command in the
FAT filesystem, allowing applications to retrieve the full path of
an open file descriptor.
Key features:
- Implements fat_getfilepath() to construct file paths by traversing
parent directories using ".." entries
- Adds fat_findlfnstart() helper to locate the start of LFN sequences
- Supports both FAT12/16 and FAT32 filesystem types
- Handles both regular directories and root directory traversal
This functionality is useful for debugging, logging, and applications
that need to track file paths at runtime.
Signed-off-by: yinshengkai <yinshengkai@bytedance.com>
Fat_zero_cluster() use fs_heap_malloc() for buffer that
is used to call fat_hwread().
Fat_hwread() must be called with IO buffer that have proper
alingment because it might use DMA.
Fix changes fs_heap_malloc() to fat_io_alloc() which uses
correct fat_dma_alloc() if CONFIG_FAT_DMAMEMORY is defined.
Signed-off-by: Ari Kimari <ari.kimari@tii.ae>
Check fs_fatsecperclus' value when read from eMMC device. Return an error if it is zero.
Signed-off-by: Yinzhe Wu <Yinzhe.Wu@sony.com>
Reviewed-by: Jacky Cao <Jacky.Cao@sony.com>
Tested-by: Yinzhe Wu <Yinzhe.Wu@sony.com>
Most tools used for compliance and SBOM generation use SPDX identifiers
This change brings us a step closer to an easy SBOM generation.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
currently, nuttx implements readv/writev on the top of read/write.
while it might work for the simplest cases, it's broken by design.
for example, it's impossible to make it work correctly for files
which need to preserve data boundaries without allocating a single
contiguous buffer. (udp socket, some character devices, etc)
this change is a start of the migration to a better design.
that is, implement read/write on the top of readv/writev.
to avoid a single huge change, following things will NOT be done in
this commit:
* fix actual bugs caused by the original readv-based-on-read design.
(cf. https://github.com/apache/nuttx/pull/12674)
* adapt filesystems/drivers to actually benefit from the new interface.
(except a few trivial examples)
* eventually retire the old interface.
* retire read/write syscalls. implement them in libc instead.
* pread/pwrite/preadv/pwritev (except the introduction of struct uio,
which is a preparation to back these variations with the new
interface.)
Summary:
1.Add configuration to allocate memory from the specified section
2.Replace all memory operations (kmm_) in the vfs with
fs_heap_. When FS_HEAPSIZE > 0, memory is requested for the file system by specifying a configured heap location. By default (i.e. FS_HEAPSIZE=0) fs_heap_ is equivalent to kmm_
Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
Unbinding `ff_currentcluster` and `f_pos`:
1. Added `ff_pos` in `struct fat_file_s`.
2. Added function `fat_zero_cluster` for doing zeroing for gap
between EOF and new position beyond EOF.
3. Added function `fat_get_sectors` for getting the sector where
`f_pos` is located, allocting new cluster when `f_pos` is beyond
EOF.
4. Modify function `fat_read`, and `fat_write` with above functions.
5. Remove redundant logics in `fat_seek` since now new cluster is
allocated when writing instead of seeking.
Signed-off-by: Yinzhe Wu <Yinzhe.Wu@sony.com>
Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Jacky Cao <Jacky.Cao@sony.com>
Tested-by: Yinzhe Wu <Yinzhe.Wu@sony.com>
When issuing an ioctl for a file that exists in a FAT32 file system,
the FAT ioctl() is first executed, but it returns -ENOSYS in
an attempt to pass through to the vfs.
Therefore, the ioctl of the VFS layer, which expects -ENOTTY,
is not processed and an error occurs.
Signed-off-by: Takeyoshi Kikuchi <kikuchi@centurysys.co.jp>
The DIRSEC_BYTENDX(f, i) is supposed to have DIRSEC_NDXMASK(f) in its expansion instead of DIRSEC_NDXMASK(fs). It went unnoticed in the codebase as DIRSEC_BYTENDX(fs, idx) is the way it is used, and it leads to a similar expansion as desired, and thus it has worked till now without any issues from this.
Signed-off-by: Saurav Pal <resyfer.dev@gmail.com>
Fix the issue where fat driver is not using the last two clusters in
the file system.
The fat parameter fs->fs_nclusters is the maximum number of data clusters;
this doesn't include the two in the beginning. Many checks in the fat driver
treat the fs->fs_nclusters-1 as being the last accessible cluster, which is not
right, the last accessible one is actually this number + 2 when the cluster
count includes the two first ones.
Normally this is not an issue when writes are being done through the same
driver, the last two clusters are just never used. But if the filesystem is
modified by external driver, for example with a populated fat created with PC,
or modifying the FS via USB-MSC, this leads to the fat driver not being able to
read anything that uses the last two clusters.
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
ubsan_prologue: ================================================================================
ubsan_prologue: UBSAN: shift-out-of-bounds in fat/fs_fat32util.c:989:40
__ubsan_handle_shift_out_of_bounds: left shift of 268435455 by 4 places cannot be represented in type 'int'
ubsan_epilogue: ================================================================================
Signed-off-by: chao an <anchao@xiaomi.com>
1. Update all CMakeLists.txt to adapt to new layout
2. Fix cmake build break
3. Update all new file license
4. Fully compatible with current compilation environment(use configure.sh or cmake as you choose)
------------------
How to test
From within nuttx/. Configure:
cmake -B build -DBOARD_CONFIG=sim/nsh -GNinja
cmake -B build -DBOARD_CONFIG=sim:nsh -GNinja
cmake -B build -DBOARD_CONFIG=sabre-6quad/smp -GNinja
cmake -B build -DBOARD_CONFIG=lm3s6965-ek/qemu-flat -GNinja
(or full path in custom board) :
cmake -B build -DBOARD_CONFIG=$PWD/boards/sim/sim/sim/configs/nsh -GNinja
This uses ninja generator (install with sudo apt install ninja-build). To build:
$ cmake --build build
menuconfig:
$ cmake --build build -t menuconfig
--------------------------
2. cmake/build: reformat the cmake style by cmake-format
https://github.com/cheshirekow/cmake_format
$ pip install cmakelang
$ for i in `find -name CMakeLists.txt`;do cmake-format $i -o $i;done
$ for i in `find -name *\.cmake`;do cmake-format $i -o $i;done
Co-authored-by: Matias N <matias@protobits.dev>
Signed-off-by: chao an <anchao@xiaomi.com>
Testing for overflow by adding a value to a variable to see if it "wraps
around" works only for unsigned integer values, because signed overflow
has undefined behavior according to the C and C++ standards.
Signed-off-by: Mingjie Shen <shen497@purdue.edu>
since mmap may exist in block_operations, but truncate may not,
moving mmap beforee truncate could make three struct more compatible
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
- Add mmap into file_operations and remove it from ioctl definitions.
- Add mm_map structure definitions to support future unmapping
- Modify all drivers to initialize the operations struct accordingly
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
- Add truncate into file_operations
- Move truncate to be common for mountpt_operations and file_operations
- Modify all drivers to initialize the operations struct accordingly
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
1.Don't check the return value of nxsem_init or nxmutex_init
2.Fix some style issue
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
The field of first cluster under LFN directory entry must be 0x0000. If
it is set a value other than 0, it causes a problem where the long file
name entry cannot be found on a Windows PC and the short file name is
always used. In addition, correct the macro error in big endian.
Summary:
- Due to the recent changes of wchar_t, ls command always
causes errors for the fat file system.
- This commit fixes this issue by replacing wchar_t with
uint16_t under fs/fat
Impact:
- None
Testing:
- Tested with spresense:wifi and stm32f4discovery:wifi
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>