The ext4l driver supports metadata_csum checksums, unlike the old ext4
driver. Only disable metadata_csum when CONFIG_FS_EXT4L is not enabled,
allowing ext4l to use modern ext4 filesystem features.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add ext4l_rename() to rename files and directories, including moves
across directories. This uses the Linux ext4_rename() function.
Also fix the symlink test to verify reading through symlinks works
correctly, since ext4l_resolve_path follows symlinks (stat behavior).
Add Python test wrappers for mkdir, ln, and rename tests.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The ext4l_ln() function returned -EEXIST when creating a symlink where
a file already exists. This differs from the old ext4 implementation
which deletes any existing file before creating the symlink (like ln -sf
behaviour).
Update ext4l_ln() to match this behaviour by calling __ext4_unlink() to
remove any existing non-directory file before creating the symlink.
Directories cannot be replaced with symlinks and return -EISDIR.
This allows test_symlink3 to pass.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add ext4l_ln() to create symbolic links. This uses the Linux ext4_symlink()
function which supports both fast symlinks (stored in inode) and regular
symlinks (stored in data blocks).
Fix the fscrypt_prepare_symlink() stub to properly init the disk_link
structure with the symlink target, which is required for symlink creation
to work correctly.
Add some notes about U-Boot's argument ordering with symlinks.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Implement ext4l_mkdir() to create directories on ext4 filesystems.
The function parses the path to extract the parent directory and
basename, resolves the parent inode, checks for existing entries,
and calls the Linux ext4_mkdir() function to create the directory.
Hook ext4l_mkdir into the filesystem layer via the .mkdir callback
in fs_legacy.c, enabling the standard 'mkdir' command to work with
ext4l filesystems.
Add a unit test that verifies directory creation, duplicate detection
(-EEXIST), nested directory creation, and error handling for
non-existent parent directories (-ENOENT).
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Implement ext4l_unlink() to delete files from ext4 filesystems. This
enables the 'rm' command to work with ext4l.
The implementation:
- Resolves the parent directory and target file
- Verifies the target is not a directory (use rmdir for that)
- Calls ext4_unlink() to remove the directory entry
- Uses journal transactions for crash safety
Add ext4l_op_ptr() macro to select between ext4l_unlink() and the
fallback based on CONFIG_EXT4_WRITE
Call ext4_commit_super() to ensure the changes are written to disk.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add the ability to write files to ext4 filesystems using the ext4l
driver. This enables the 'save' command to work with ext4l.
The implementation uses the jbd2 journal for crash safety:
- ext4l_write() creates files if needed and writes data
- Journal transactions commit synchronously for durability
- Buffer cache syncs dirty buffers after write operations
The write path consists of the following steps:
1. Lookup or create file via ext4_create()
2. Start journal transaction
3. For each block: get/allocate block, copy data, sync to disk
4. Update inode size and commit transaction
5. Sync all dirty buffers
Add an ext4l_op_ptr() macro to select between a write operation and a
fallback based on CONFIG_EXT4_WRITE, avoiding #ifdefs in fstypes[].
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Some block devices, such as LUKS-encrypted volumes mounted via
blkmap_crypt, only support read access. When ext4l attempts to write
the superblock during mount, the write fails and causes mount to fail.
Add a way to detect this read-only device detection:
- Test writes during mount by writing back the superblock data; if the
write fails, mark the device as read-only
- Update bdev_read_only() to return the actual read_only status
- Update sb_rdonly() to check the SB_RDONLY flag
This allows ext4l to successfully mount read-only devices like LUKS
volumes for read access.
We could perhaps have a read-only flag in the block device, but that is
left for another day.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
When running filesystem tests back-to-back, buffer_heads could be freed
while journal_heads still reference them. This causes use-after-free
crashes when the journal code later accesses the stale b_bh pointer.
Add protection in free_buffer_head() to skip buffers with JBD attached,
since the journal owns a reference and will clean them up properly. Also
add protection in brelse() to prevent the ref count from dropping to
zero while JBD is still attached.
Update comments in ext4l_close_internal() to clarify why cache cleanup
is critical even during skip_io mode.
Fixes crashes when test_fs13 runs after test_fs11 in the same session.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
When running multiple filesystem tests in sequence, probe may be called
without an explicit close of the previous mount. The old device may have
been rebound to a different file, making I/O to it invalid.
Add a new ext4l_close_internal() function with a skip_io parameter to
handle this case. When skip_io is true, it skips journal-destroy
entirely since the device may be invalid. It will be recovered on next
mount.
Also call the ext4- and JBD2- cleanup functions to properly reset the
global state for subsequent mounts: ext4_exit_system_zone(),
ext4_exit_es(), ext4_exit_mballoc(), and jbd2_journal_exit_global()
This ensures the caches are destroyed, thus freeing all orphaned
journal_heads, even when skip_io is true.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add bh_cache_release_jbd() to forcibly release any journal_heads still
attached to buffer_heads after journal destroy. This must be called
after journal destroy but before bh_cache_clear() to ensure all
journal_heads are properly released, even if journal destroy did not
fully clean up (e.g., on abort).
The function clears b_bh in each journal_head to prevent use-after-free
when the buffer_head is later freed, and resets transaction pointers.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The ext4l driver requires the filesystem framework (FS) and rbtree
library (RBTREE) to build correctly. Add the first as an explicit
dependency and 'select' the second, to prevent build failures when ext4l
is enabled.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The crc16() stub always returns 0, which causes group-descriptor
checksum-verification to fail for filesystems using the old CRC16
checksum algorithm (gdt_csum feature without metadata_csum).
Replace the stub with U-Boot's real CRC16 implementation to allow
mounting these filesystems.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The atomic_add() and atomic64_add() functions are now provided by
asm-generic/atomic.h so remove the duplicate declarations from
ext4_uboot.h and the implementation from stub.c
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Resources are not properly released on unmount, causing memory leaks
in long-running U-Boot sessions that remount filesystems.
Add ext4l_free_sb() to release all resources on unmount:
- Destroy journal and commit superblock
- Release superblock buffer and unregister lazy init
- Free mballoc data and release system zone
- Destroy xattr caches
- Free group descriptors and flex groups
- Evict all tracked inodes
- Free root dentry, sbi, and superblock structures
Also:
- Init the s_inodes list when allocating superblock
- Free mount context (ctx, fc) after successful mount
- Call destroy_inodecache() during global cleanup
- Clear folio cache on buddy cache inode before iput()
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Several buffer cache issues cause problems when remounting:
1. bh_cache_insert() only checks block number, but the same block can
be read with different sizes (e.g. superblock at 1K vs 4K). Check
both block number and size when determining if already cached.
2. bh_cache_clear() leaves stale buffer references, causing memory
leaks. Force the reference count to 1 before releasing since ext4
code won't access these buffers after unmount.
3. brelse() frees buffer heads when the reference count reaches zero,
but cached buffer heads should only be freed by bh_cache_clear()
during unmount. This causes a double-free. Add a BH_Cached flag to
distinguish cached buffers from temporary ones: set BH_Cached in
bh_cache_insert() when adding to cache, and in brelse() only free
non-cached buffers when count reaches zero.
Also fix a bit conflict: BH_OwnsData was using BH_JBDPrivateStart which
conflicts with BH_BITMAP_UPTODATE in ext4.h. Move U-Boot private bits
to start at BH_JBDPrivateStart + 1.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
U-Boot does not track allocated inodes, causing memory leaks when
remounting filesystems.
Add s_inodes list to super_block and i_sb_list to inode structures to
track all allocated inodes, allowing proper eviction on unmount.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Move the message buffer functions from interface.c to support.c since
they are internal support code rather than filesystem-interface
functions. This keeps interface.c focused on functions called from the
U-Boot filesystem layer.
Functions moved:
- ext4l_msg_init()
- ext4l_record_msg()
- ext4l_get_msg_buf()
- ext4l_print_msgs()
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add documentation for the ext4l_msgs environment variable which
controls whether the ext4l filesystem driver prints mount messages
when probing an ext4 filesystem.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
The memory leaks were in fact not coming from the kmem cache, so let's
drop this unnecessary feature.
This reverts commit e63fc511c3.
Signed-off-by: Simon Glass <simon.glass@canonical.com>
When mcheck heap-protection is enabled, each allocation adds quite a
bit of overhead for headers and canaries. While this is needed for the
full allocator, it serves no purpose for pre-relocation allocations,
since:
1. Simple malloc is a bump allocator that cannot free memory
3. Mcheck's corruption-detection provides no benefit for non-freeable
memory
Since the pre-relocation heap space is limited (typically <16KB), this
overhead can exhaust the heap, causing boot failures.
Fix this by bypassing mcheck hooks in dlmalloc(), dlfree(),
dlmemalign() and dlcalloc() when called before relocation, directly
calling the simple malloc functions instead.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The mcheck heap protection stores a caller string in each allocation
header for debugging purposes. The length is hard-coded to 48 bytes in
mcheck_core.inc.h
Add a CONFIG_MCHECK_CALLER_LEN Kconfig option to make this configurable,
allowing users to adjust the trade-off between the amount of debugging
context and the memory overhead per allocation.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Some blkmap slices (like blkmap_crypt) don't support writes and have
their write function set to NULL. The blkmap_blk_write_slice() function
calls the write function without checking if it's NULL, causing a crash
when attempting to write to such slices.
Add a NULL check before calling the write function. When the slice
doesn't support writes, return 0 to indicate no blocks were written.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Update the ReadTheDocs documentation to use the correct U-Boot logo
from the original 2023 website, stickers and coins. This includes the
project name.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add a pre_remove handler that unregisters the video_idle cyclic when
the last video device is removed. This ensures the cyclic won't run
after driver model is reinitialised by the test framework.
This complements the uclass_find() fix by properly cleaning up the
cyclic registration rather than just gracefully handling the orphaned
state.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
When the test framework reinitialises driver model, it orphans existing
uclasses without calling their destroy callbacks. The video_idle cyclic
callback remains registered and when it runs, it calls uclass_get()
which creates new uclasses if they don't exist.
Use uclass_find() instead which returns NULL if the uclass doesn't
exist, allowing video_idle to gracefully exit without allocating memory.
This avoids memory-leak detection failures in tests like dm_test_host.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
When running sandbox with lots of console output, the vidconsole slows
things down significantly since it renders truetype fonts to the
internal framebuffer. Add a -Q/--quiet_vidconsole command-line option
that removes vidconsole from stdout and stderr, using only the serial
console.
This can provide a ~300x speedup for output-heavy operations.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
When os_persistent_file() is called without a directory set in the
environment variable and the file isn't found in the current directory,
also check in the executable's directory.
This allows tests like dm_test_host to work when run directly from the
build directory rather than through the pytest framework, avoiding the
need to set U_BOOT_PERSISTENT_DATA_DIR manually.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Rename local variables in cmpxchg macro to avoid shadowing when used
inside try_cmpxchg, which also declares __old. Clang complains about
"variable '__old' is uninitialised when used within its own
initialisation" due to the nested macro expansion.
Cover-letter:
ext4l: Infrastructure and fixes for write support (part K)
This series adds infrastructure and bug fixes needed for ext4l write
support. It includes:
- kmem_cache implementation controlled by CONFIG_LIB_KMEM_CACHE
- Bit operation functions imported from Linux (find_bit, fns)
- Little-endian bit operations for ext4 bitmaps
- Buffer I/O infrastructure for write operations
- Folio and buffer head fixes for U-Boot's malloc'd buffers
- Inode handling fixes (i_mode, i_blocks, iput eviction)
- Journal cleanup detection in bh_cache_clear()
- Various bug fixes for clang warnings and multi-word bit operations
END
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The set_bit(), clear_bit(), and change_bit() functions only modify the
first word of a bitmap, regardless of the bit number. For bit numbers
>= 64 on 64-bit systems, the shift wraps around and modifies the wrong
bit position.
Fix these functions to properly calculate the word offset before
modifying the bit. This is needed for block bitmap operations where bit
numbers can be in the thousands.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Update the percpu_counter_initialized() and percpu_counter_init()
macros in ext4_uboot.h to use the new initialized field.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Implement iput() to properly handle inode reference counting and
eviction. When the reference count drops to zero and the inode has no
links (i_nlink == 0), call ext4_evict_inode() to free the inode's data
blocks and the inode itself.
This is required for unlink operations to properly free filesystem
resources.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The ktime_get_real_seconds() stub returns 0, causing deleted inodes
to have zero i_dtime. This causes fsck to complain about deleted
inodes with zero deletion time.
Instead, use the boot-relative time in seconds. While not a real
wall-clock timestamp, it provides a non-zero value that satisfies
filesystem-consistency checks.
Future work can improve on this, perhaps using an on-board RTC.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The dquot_alloc_block(), dquot_free_block() and dquot_alloc_block_nofail()
functions are stubs that do nothing. These functions are called by ext4
when allocating and freeing blocks, and they should update the inode's
i_blocks field.
Fix these functions to properly track block allocation in i_blocks,
which is stored in 512-byte units.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add declaration for ext4_commit_super() to the ext4_uboot.h header
and update the comment to reflect both superblock initialisation
and commit functions.
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Fix inode_init_owner() to properly set i_mode, which is needed for
ext4_create() to work correctly.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add more complete buffer I/O infrastructure so that we can support
writing to an ext4 filesystem.
- end_buffer_write_sync(): I/O completion callback for sync writes
- submit_bh(): Add the write path with b_end_io callback invocation
- __getblk(): Allocate journal-descriptor buffers
- free_buffer_head(): Don't free shared folios from shadow buffers
- __brelse(): Only decrement refcount, don't free
- bh_cache_sync(): Sync all dirty buffers to disk
- sync_dirty_buffer()/mark_buffer_dirty(): Write buffer immediately
The shadow-buffer fix is needed for jbd2 journaling: shadow buffers
created by jbd2_journal_write_metadata_buffer() share their folio with
the original buffer (as indicated by b_private).
With this, the buffer I/O layer is ready for ext4 write support.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The existing folios macros assume page-aligned memory, but U-Boot uses
malloc'd buffers for simplicity.
Update the macros accordinging:
- offset_in_folio(): Calculate the offset from the folio's data pointer
- bh_offset(): Calculate the actual offset within the folio
- folio_set_bh(): Actually set b_folio and b_data
- kmap_local_folio(): Return a pointer to folio data + offset
Implement __filemap_get_folio(), folio_put() and folio_get() for
folio-lifecycle management.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The ext4 block allocator uses little-endian bit operations on block
bitmaps. Implement these operations by wrapping the existing
set/test/clear_bit() functions.
Add find_next_zero_bit() to search for free blocks in bitmaps.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add lib/find_bit.c and include/linux/find.h from Linux v6.19, trimmed
to include only the functions needed for ext4l: find_first_bit(),
find_first_zero_bit(), find_next_bit(), find_next_zero_bit() and
find_last_bit()
The following items are removed from the Linux originals:
- find.h: _and_bit, _andnot_bit, _or_bit, _nth_bit variants, wrap
functions, clump8 functions, big-endian support, most for_each_...
macros
- find_bit.c: Corresponding implementations, random.h include
Add wrapper functions matching sandbox's asm/bitops.h declarations
(int return type, void* addr) that call the _find_* implementations.
Build find_bit.o only for sandbox for now.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add the fns() function from Linux to find the N'th set bit in a word.
This is needed by lib/find_bit.c which uses it in the FIND_NTH_BIT
macro.
Taken from Linux v6.19
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
When debugging journal-cleanup issues, stale journal_head attachments on
buffer_heads can cause crashes on subsequent mounts.
Add detection logic in bh_cache_clear() to warn when a buffer_head still
has a journal_head attached. This indicates the journal was not properly
destroyed before unmount. Clear the JBD flag and pointer to prevent
issues with subsequent mounts.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add a Kconfig option to control whether full kmem_cache_free() and
kmem_cache_destroy() implementations are provided in lib/linux_compat.c
Most boards do not need these functions, so they can use simple inline
stubs in slab.h. Subsystems like ext4 that require proper cache
management can select CONFIG_LIB_KMEM_CACHE.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Initialize 'len' to 0 to silence a Clang warning about the potential use
of an uninitialised variable. The else branch calls BUG() which never
returns, but Clang cannot determine this.
Series-to: concept
Cover-letter:
ext4l: Linux adaptation patches for ext4 write support
This series contains adaptations to Linux-imported files needed for
ext4l write support in U-Boot. These changes are separated from the
main ext4l implementation to make it easier to track modifications
to imported code.
The patches include:
- Bit position fixes for REQ_OP and BH_OwnsData to avoid conflicts
- JBD2 journal adaptations for U-Boot's single-threaded environment
- Function exports to allow calling ext4 internals from U-Boot code
- Cache management fixes for multiple mount/unmount cycles
- Compiler warning fixes for Clang compatibility
These changes are minimal modifications to the Linux ext4 and jbd2
code, using #ifdef __UBOOT__ guards where appropriate to ease future
Linux updates.
END
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Series-links: 1:96
In U-Boot, filesystems may be mounted and unmounted multiple times in a
single session. The ext4 cache initialization functions would fail on
subsequent mounts because the caches were already initialized but pointers
were not reset on exit.
Add early return checks in init functions when already initialized, and
reset cache pointers to NULL in exit functions to allow clean
reinitialization.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Remove static from ext4_commit_super() to allow calling it from
ext4l interface code to sync superblock after write operations.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add __maybe_unused to ext4_groupinfo_slab_names since U-Boot's
kmem_cache_create macro ignores the name parameter, making the array
appear unused to the compiler.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>