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>
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>
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>
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>
In U-Boot's ext4l implementation, bh_cache_sync() writes all dirty
buffers to disk. However, buffers passed through the journal via
jbd2_journal_dirty_metadata() were not being marked dirty for
bh_cache_sync() to pick up.
Add mark_buffer_dirty() after jbd2_journal_dirty_metadata() to ensure
these buffers are written by bh_cache_sync(). This is needed because
U-Boot's journal implementation does not write buffers to their final
locations.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Skip orphan handling in U-Boot. We do synchronous journal commits
after each operation, so orphan recovery is not needed. Adding to
the orphan list without proper locking can corrupt the list.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Remove static from ext4_create(), ext4_mkdir(), ext4_symlink(), and
ext4_rename2() and add declarations in ext4.h to allow calling them
from ext4l interface code.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The REQ_OP flags (REQ_SYNC, REQ_FUA) use bits 0-1, which collide
with REQ_OP_WRITE (value 1). Move the flags to bits 8+ and add
REQ_OP_MASK to properly separate operation from flags.
Move BH_OwnsData from buffer_head.h to ext4_uboot.h to keep
Linux headers unmodified. Define it as BH_JBDPrivateStart to
avoid conflicts with JBD2 state bits (17-25).
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Implement ext4l_statfs() to return filesystem statistics using the
ext4 superblock. The function returns block size, total block count,
and free block count.
Add unit test to verify the statfs implementation returns valid data.
Cover-letter:
fs: ext4l: Complete read-only filesystem support (Part I)
This series completes read-only support for the ext4l filesystem driver,
which is a port of the Linux ext4 driver to U-Boot.
The ext4l driver provides more complete ext4 support than the existing
ext4 driver, including proper handling of extents, directory hashing,
and other ext4 features.
Changes include:
Sandbox infrastructure:
- Fix IRQ macros and buffer_head includes for sandbox builds
Core fixes:
- Fix path lookup by implementing proper dentry operations
- Fix fscrypt_match_name to do actual name comparison
Filesystem operations:
- Add directory listing (opendir/readdir/closedir)
- Add file existence check (exists)
- Add file size query (size)
- Add file read support (read)
- Add UUID query (uuid)
- Add filesystem statistics (statfs)
New command:
- Add fsinfo command to display filesystem statistics
Testing:
- Add comprehensive unit tests for all operations
- Enable fsuuid command for sandbox testing
END
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The filesystem uuid method is not implemented.
Add ext4l_uuid() which returns the filesystem UUID as a string and
wire it into the filesystem operations table. Add a test.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add ext4l_read() function to read file contents. The function resolves
the path to an inode, then reads the file block by block using
ext4_bread() and copies the data to the output buffer.
Signed-off-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add ext4l_size() function to retrieve the size of a file or directory.
Wire it into the filesystem operations table in fs_legacy.c.
Signed-off-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Implement ext4l_exists() to check if a file or directory exists on the
filesystem. This uses ext4l_resolve_path() to look up the path and
returns 1 if found, 0 otherwise.
Wire the function into fs_legacy.c and add a basic test.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Implement directory-iteration for the ext4l filesystem driver, allowing
callers to iterate through directory entries one at a time.
Add ext4l_opendir() which opens a directory and returns a stream handle,
ext4l_readdir() which returns the next directory entry, and
ext4l_closedir() which closes the stream and frees resources.
The implementation uses a struct dir_context to capture single entries
from ext4_readdir(), with logic to skip previously returned entries
since the htree code may re-emit them.
Update struct file to include a position.
Wire these functions into fs_legacy.c for the ext4l filesystem type.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The fscrypt_match_name stub macro always returns 1, causing every
directory entry to match regardless of name. Also d_splice_alias is
a no-op that returns NULL, so the inode found by ext4_lookup is
never associated with the dentry.
Fix fscrypt_match_name to properly compare name lengths and contents.
Fix d_splice_alias, d_instantiate and d_instantiate_new to set
d->d_inode.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Implement directory listing (ls) for the ext4l filesystem driver. This
includes path resolution with symlink following (limited to 8 levels to
prevent loops).
Add ext4l_ls() which uses ext4_lookup() for path resolution and
ext4_readdir() for directory enumeration. The dir_context actor callback
formats and prints each directory entry.
Export ext4_lookup() from namei.c and add declarations to ext4.h.
Add test_ls to the Python test suite, which creates a test file using
debugfs and verifies it appears in the directory listing with the
correct size.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Cover-letter:
ext4l: Add support for listing directoties (Part H)
This series adds directory-listing support to the ext4l filesystem
driver. It exports a few required functions from the Linux ext4 code,
fixes the dir_emit() stub to properly call the actor callback, and
implements ext4l_ls() with path resolution and symlink following.
END
Signed-off-by: Simon Glass <simon.glass@canonical.com>
The dir_emit() macro was stubbed to do nothing, which meant directory
listing would never output any entries. Replace it with a proper
inline function that calls ctx->actor() to emit each directory entry.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Remove the static qualifier from ext4_readdir() so it can be called
from the ext4l interface code for directory listing operations.
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add runtime control for printing ext4 messages via the ext4l_msgs
environment variable. When set to 'y' or '1', the recorded message
buffer is printed after a successful mount.
This provides a runtime alternative to the compile-time
CONFIG_EXT4L_DEBUG option.
Usage: setenv ext4l_msgs y
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
Add a 4KB membuf to record ext4 messages for later retrieval. This
allows programmatic access to filesystem messages without requiring
CONFIG_EXT4L_DEBUG to be enabled.
- Add ext4l_msg_buf and ext4l_msg_data in interface.c
- Add ext4l_record_msg() to record messages
- Add ext4l_get_msg_buf() to access the buffer
- Modify __ext4_msg() to always record messages, print only if debug
Note that this increases the number of strings in the ext4l
implementation. For production it might be useful to make this an
option, although the messages can be quite important.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>