This commit fixes a regression introduced by
89df084b0e. That commit
added a check to ensure iov_base is not NULL, assuming NULL
always represents an inaccessible address.
However, in CONFIG_BUILD_KERNEL mode where CONFIG_ARCH_TEXT_VBASE
is set to 0, address zero is a valid virtual address for the
user-space text segment. The previous check caused libelf to
fail with -EFAULT when attempting to load ELF program headers
into the base of the user address space.
This patch wraps the safety check in a conditional to ensure it is
only executed when address zero is not considered a valid
executable base.
Signed-off-by: Lwazi Dube <lwazeh@gmail.com>
When CONFIG_FS_BACKTRACE is enabled, collecting a stack trace for every
new file descriptor adds overhead to fast path operations like open(),
dup(), and socket().
This patch adds a new configuration option CONFIG_FS_BACKTRACE_DEFAULT.
When enabled (default behavior), the GROUP_FLAG_FD_BACKTRACE flag is
automatically set during group allocation, causing backtrace to be
captured for all tasks globally, preserving the original diagnostic
capability.
When disabled, backtrace capture is zero-cost by default and must be
explicitly enabled per task group using GROUP_FLAG_FD_BACKTRACE.
Signed-off-by: zhanxiaoqi <zhanxiaoqi@bytedance.com>
Allow to close the lock even the dying task is in
signal handler context. Also the file type check can
be ignored as they are already validated in create phase.
Signed-off-by: Jari Nippula <jari.nippula@tii.ae>
This adds a kernel-level performance profiler for the VFS.
By enabling CONFIG_FS_PROFILER, the core VFS system calls
(file_read, file_write, file_open, and file_close) are
instrumented to track high-resolution execution times using
clock_systime_timespec() seamlessly.
The collected statistics are exposed dynamically via a new
procfs node at /proc/fs/profile, allowing CI regression
testing without needing external debugging tools.
Signed-off-by: Sumit6307 <sumitkesar6307@gmail.com>
In proxy_fstat(), the write permission bits for a block driver proxy
were gated on `i_ops->read` instead of `i_ops->write`:
The effect is that a driver implementing read but not write would have
S_IWOTH | S_IWGRP | S_IWUSR incorrectly set in the fstat() result,
reporting the file as writable when it is not.
Fix: replace `->read` with `->write` in the write check condition.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.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>
Add INIT message which can be used in case ns_announcement isn't
supported on the system.
It unlocks the client flow by calling rpmsg_post() on the semaphore.
Without this or an NS announcement, the client's semaphore will wait
forever.
This is practical when the server side is running from linux userspace
using ioctl where controlling NS announcements is problematic.
Signed-off-by: Andre Heinemans <andre.heinemans@nxp.com>
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>
Correct duplicate "is is" word found in 181 files throughout the
codebase.
In most cases "is is" was changed to "is", but in contexts like
"MCU is is sleep mode" it was corrected to "MCU in sleep mode".
Also fixes a "the the" typo in net/inet/inet_sockif.c.
This is a pure style/documentation fix that improves code readability.
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
Fix 269 occurrences of duplicate "the" word typo found in 209 files
across source code, header files, and configuration.
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This PR addresses several portability and technical debt issues in the mnemofs filesystem by resolving source-level TODO items.
Changes:
- Implemented a portable fallback for mfs\_clz (Count Leading Zeros) in fs/mnemofs/mnemofs.h using a binary search approach. This ensures compatibility with non-GCC compilers.
- Removed the redundant 8-bit mfs\_arrhash and consolidated hashing with the existing 16-bit mfs\_hash in mnemofs\_util.c.
- Removed the related TODO comments in mnemofs.h and mnemofs\_util.c.
- Fixed NuttX style (indentation and braces) in the fallback bit primitives.
Signed-off-by: Sumit <sumit6307@gmail.com>
Intermediate files of make depend like .ddc and .dds may remain
when make is interrupted. Remove them using make distclean.
Signed-off-by: SPRESENSE <41312067+SPRESENSE@users.noreply.github.com>
Implement Linux-compatible TFD_TIMER_CANCEL_ON_SET flag for timerfd to
allow applications to detect discontinuous changes to CLOCK_REALTIME.
Background:
According to Linux timerfd_create(2) man page, when a timerfd is created
with CLOCK_REALTIME and TFD_TIMER_CANCEL_ON_SET flag is specified, the
read() operation should fail with ECANCELED if the real-time clock
undergoes a discontinuous change. This allows applications to detect
and respond to system time changes.
Implementation:
1. Add clock notifier infrastructure (clock_notifier.h/c) to notify
interested parties when system time changes
2. Implement TFD_TIMER_CANCEL_ON_SET flag support in timerfd
3. Register timerfd with clock notifier when flag is set
4. Cancel timer and return ECANCELED when clock change is detected
5. Notify clock changes in:
- clock_settime()
- clock_initialize()
- clock_timekeeping_set_wall_time()
- rpmsg_rtc time synchronization
Changes include:
- New files: include/nuttx/clock_notifier.h, sched/clock/clock_notifier.c
- Modified: fs/vfs/fs_timerfd.c to handle TFD_TIMER_CANCEL_ON_SET
- Modified: clock subsystem to call notifier chain on time changes
- Modified: rpmsg_rtc to notify time changes during sync
Use case example:
Applications using timerfd with absolute time can now detect when
system time is adjusted (e.g., NTP sync, manual time change) and
take appropriate action such as recalculating timeouts or updating
scheduled events.
Reference: https://man7.org/linux/man-pages/man2/timerfd_create.2.html
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
For re-enter case, the inode information may unlock with not filled,
and get by other user. that lead to the error behavior.
Especially SMP scene.
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
For re-enter case, the inode information may unlock with not filled,
and get by other user. that lead to the error behavior.
Especially SMP scene.
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
For re-enter case, the inode information may unlock with not filled,
and get by other user. that lead to the error behavior.
Especially SMP scene.
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
Since the busy-wait time statistics for entering the critical section have been added, the critmon information in the document has been updated accordingly.
Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
Add configuration "CONFIG_SCHED_CRITMONITOR_MAXTIME_BUSYWAIT", which can record the busy waiting time to get spinlock or enter critical section.
Signed-off-by: wangzhi16 <wangzhi16@xiaomi.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>
Fix MISRA Rule 10.3 exist clock to sclock cause wide type implicit conversion to narrow type, NSEC_PER_USEC to l
Signed-off-by: jiangtao16 <jiangtao16@xiaomi.com>
Because fs always need malloc the small memory for inode or filep,
so enable the mempool by default to optimize the memory
fragmentation issue.
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Signals in NuttX serve two primary purposes:
1. Synchronization and wake-up:
Signals can be used to block threads on specific signal sets and later
wake them up by delivering the corresponding signals to those threads.
2. Asynchronous notification:
Signals can also be used to install callback handlers for specific signals, allowing threads to
asynchronously invoke those handlers when the signals are delivered.
This change introduces the ability to disable all signal functionality to reduce footprint for NuttX.
Signed-off-by: Chengdong Wang wangchengdong@lixiang.com
To simplify the handling of Block devices and MTD devices,
the unique_chardev and unique_blkdev functions now use local
variable names instead of allocating device names from the heap.
Signed-off-by: jingfei <jingfei@xiaomi.com>
Fix a race on userfs_state_s iobuffer.
1. Task 1 takes the mutex and does a userfs operation.
2. A higher priority task 2 blocks on the mutex.
3. Task 1 releases the mutex when finished. The iobuffer response has not
been processed by task 1 yet, but task 2 is higher priority
and control switches to it.
4. Task 2 does a userfs operation and releases the mutex.
The iobuffer now contains task 2's response.
5. Control returns to task 1 for it to check the iobuffer
response. It contains task 2's response, not its own.
Fix it by releasing the mutex only after the exclusive iobuffer
usage lifecycle is complete.
Signed-off-by: liamHowatt <liamjmh0@gmail.com>
issue description:
task A: NSH:
1.open-> reboot->sync->task_fsfsync
2.nx_vopen-> context switch
3.fdlist_allocate: ----> 4.fsync->file_sync->assert(inode or priv is empty)
(new fd with empty filep)
5.file_vopen:
(init empty filep)
6.return fd
Task A allocates a new fd with an empty filep in fdlist_allocate. Before
it can fully initialize the filep in file_vopen, the NSH task triggers a
file - system sync operation. The sync operation encounters the empty
filep associated with the newly allocated fd, causing the assertion to
fail and the system to crash.
To resolve this race condition, we should modify the fd allocation
process. Instead of allocating a new fd with an empty filep first and
then initializing it later, we should use the file_allocate_from_inode
function. This function allows us to initialize the file structure first
and then bind it to the new filep when allocating the fd. By doing so,
we ensure that the filep is always properly initialized before it is
used in any file - system operations, thus preventing the assertion
failure and the subsequent system crash.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
When a child process inherits file descriptors from its parent via
fdlist_copy(), the fd tags (fd_tag_fdsan and fd_tag_fdcheck) were not
being copied. This caused assertion failures when the child process
closed inherited file descriptors, because the fdcheck/fdsan subsystems
expected the tags to match.
Root Cause:
----------
The fdlist_install() function was not preserving the fd tags during
fd duplication. When copying fds from parent to child in fdlist_copy(),
the tags were lost, resulting in:
- fd_tag_fdsan: Used for file descriptor ownership tracking (FDSAN)
- fd_tag_fdcheck: Used for fd validity checking (FDCHECK)
Both tags being reset to 0/NULL instead of copied from parent.
Symptom:
--------
Child processes would crash with assertion failure in fdcheck_restore()
when closing inherited file descriptors:
fdcheck_restore+0x69/0xa0
fdlist_get2+0x11/0x48
fdlist_close+0xd/0x94
close+0x15/0x30
This occurred because fdcheck_restore() validates that the fd_tag_fdcheck
matches the expected value, and the mismatch triggered an assertion.
Solution:
---------
1. Add a 'copy' parameter to fdlist_install() to distinguish between:
- New fd allocation (copy=false): Initialize fresh tags
- Fd duplication (copy=true): Preserve tags from source fd
2. Add fdp parameter to fdlist_install() to access source fd tags
3. In fdlist_copy(), pass copy=true to preserve parent's fd tags
4. In fdlist_dup3(), pass copy=false since dup operations should
create independent fd tracking (not copy parent tags)
Changes:
--------
- fdlist_install(): Added 'fdp' and 'copy' parameters
- When copy=true, preserve fd_tag_fdsan and fd_tag_fdcheck from source
- fdlist_copy(): Pass copy=true to preserve parent tags
- fdlist_dup3(): Pass copy=false for normal dup behavior
Impact:
-------
This fix ensures that file descriptor ownership tracking and validity
checking work correctly across fork/clone operations, preventing
crashes when child processes close inherited file descriptors.
Without this fix, any program using fork() with inherited fds would
crash if CONFIG_FDSAN or CONFIG_FDCHECK were enabled.
Issue backtrace:
backtrace_unwind+0x105/0x108
sched_backtrace+0x6f/0x80
sched_dumpstack+0x33/0x80
_assert+0x229/0x510
arm_syscall+0x81/0x98
up_assert+0xd/0x18
__assert+0x1d/0x24
fdcheck_restore+0x69/0xa0
fdlist_get2+0x11/0x48
fdlist_close+0xd/0x94
close+0x15/0x30
closefd+0x5/0x30
notify_parent_process+0x2b/0x40
run_helper_tcp4_echo_server+0x75/0x114
run_test_part+0x5f/0x68
uv_run_tests_main+0x35/0x60
run_test_part+0x5f/0x68
uv_run_tests_main+0x35/0x60
nxtask_startup+0x13/0x2c
nxtask_start+0x4d/0x64
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Before this fix, the check for OPEN_MAX was performed using orig_rows
instead of the new row count after extension. This caused the check to
pass even when the allocation would exceed OPEN_MAX limit.
For example:
- OPEN_MAX = 256
- CONFIG_NFILE_DESCRIPTORS_PER_BLOCK = 32
- orig_rows = 8 (8 * 32 = 256, at the limit)
The old code checked: 32 * 8 > 256 (false, allows extension)
The new code checks: 32 * (8 + 1) > 256 (true, correctly blocks)
Without this fix, the system could allocate more file descriptors than
OPEN_MAX allows, potentially causing memory corruption or exceeding
system limits.
This fix ensures the check evaluates the new total count (orig_rows + 1)
before allowing the extension to proceed.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Issue:
When using a stack-allocated file structure, the sequence:
1. file_open() initializes the stack file structure
2. file_mmap() creates memory mapping and increments reference count
3. file_munmap() decrements reference count and may free the file structure
4. file_close() attempts to close already freed structure → crash
Root cause:
The memory mapping operations (fs_reffilep/fs_putfilep) manage reference counts
independently and can free the stack-allocated file structure prematurely.
Solution:
- Add reference count protection during file_open() for stack-allocated files
- Clear reference count appropriately during file_close()
- This ensures the file structure remains valid throughout its lifetime
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
When a thread is terminated via pthread_exit() while blocked in epoll_wait(),
the file reference taken at the beginning of epoll_wait() is not properly
released, leading to resource leaks.
Problem scenario found during libuv test:
1. Echo server thread is blocked in epoll_wait()
2. Main task sends pthread_kill signal to the server thread
3. Signal handler calls pthread_exit() to terminate the thread
4. epoll_wait() is interrupted before reaching the file_put() call
5. The epoll fd reference count remains elevated
6. epoll_do_close() is never called, leaving fds in internal queues
7. File descriptors leak
Solution:
Register a TLS (Thread Local Storage) cleanup handler using tls_cleanup_push()
at the beginning of epoll_wait() blocking section. This ensures that if the
thread exits abnormally (via pthread_exit, pthread_cancel, etc.), the cleanup
handler (epoll_cleanup) will be called automatically to release the file
reference via file_put().
The cleanup handler is properly paired with tls_cleanup_pop() when epoll_wait()
completes normally, ensuring the handler is only invoked on abnormal exit.
This fix is applied to both epoll_wait() code paths (with and without extended
mode) to ensure consistent behavior.
Impact:
- Prevents epoll fd reference count leaks on thread cancellation
- Ensures proper cleanup even when epoll_wait() is interrupted by pthread_exit
- Critical for multi-threaded applications using signals and thread termination
- Works together with previous fix for teardown/oneshot list cleanup
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
When an epoll fd is closed, the file descriptors in the teardown and
oneshot lists were not being properly dereferenced, leading to fd leaks.
This fix ensures that all fds in the teardown and oneshot lists are
properly released via file_put() during epoll_do_close(), matching the
behavior for fds in the setup list.
Impact:
- Prevents fd leaks when epoll fd is closed
- Ensures proper cleanup of all tracked file descriptors
- Critical for applications using EPOLLONESHOT or fd removal operations
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
The 'created' flag values were incorrectly inverted in file_mq_vopen():
1. When opening an existing message queue (inode_find succeeds):
- Before: incorrectly set *created = 1 (indicating new creation)
- After: correctly set *created = 0 (indicating existing queue)
2. When creating a new message queue (inode_find fails):
- Before: incorrectly set *created = 0 (indicating existing queue)
- After: correctly set *created = 1 (indicating new creation)
This bug could lead to incorrect resource management and cleanup behavior
in the calling function nxmq_vopen() when file_allocate() returns an error,
as it relies on the 'created' flag to determine whether the message queue
was newly created and needs to be cleaned up.
Impact:
- Resource leak when opening existing queues that should not be released
- Missing cleanup when creating new queues that should be released on error
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
lfs_fs_size() can return more blocks than block_count during active
writes due to copy-on-write blocks. This caused f_bavail to underflow
to a large positive number. Add clamping to prevent this.
Signed-off-by: Julian Oes <julian@oes.ch>
This reverts commit ac6fff747a7a6122e61de373350148331a94692f.
This reverts commit c83e3f651b967c64b5652a6bd2e96bcae48417b4.
This reverts commit 133db24d072457331134b683ad7b84c8a002feb9.
This reverts commit 5c1248ec38964e7886b23e65f732241c5d870d69.
This reverts commit 2cc850b6dcbad904282f1a326f52bff054251591.
This reverts commit 49cad84508e7db903068180fe4ebdfaef335efac.
Signed-off-by: guohao15 <guohao15@xiaomi.com>
if first call unlink after call nxmq_file_close
cause i_crefs not 0 will leak msqg, inode will
free in unlink, but forget free msgq
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
The lines will end with \n to prevent atoi('\n') from always being 0. It is recommended to check the first byte directly.
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
when i is zero and file_get is failed, num is -1,
it's uint32_max for nfds.
so remove num and simplify code logic.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>