Commit Graph

1162 Commits

Author SHA1 Message Date
Simon Glass
da2593e6b0 ext4l: Add rename support
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>
2026-01-01 17:13:59 -07:00
Simon Glass
8eabf8fb91 ext4l: Update symlink to replace existing files
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>
2026-01-01 17:13:59 -07:00
Simon Glass
4a0adf41fd ext4l: Add symlink support
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>
2026-01-01 17:13:59 -07:00
Simon Glass
5ae10b6f46 ext4l: Add mkdir support for directory creation
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>
2026-01-01 17:13:59 -07:00
Simon Glass
1d4959fde3 ext4l: Add unlink support for file deletion
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>
2026-01-01 17:13:59 -07:00
Simon Glass
2655c75957 ext4l: Add write support
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>
2026-01-01 17:13:59 -07:00
Simon Glass
5161a55207 ext4l: Add support for read-only devices
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>
2026-01-01 17:13:59 -07:00
Simon Glass
3946f6504e ext4l: Prevent freeing buffer_heads with active journal_heads
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>
2026-01-01 17:13:59 -07:00
Simon Glass
7b1fd66e98 ext4l: Add safeguard to close previous mount in probe
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>
2026-01-01 17:13:59 -07:00
Simon Glass
b6980e8fca ext4l: Add bh_cache_release_jbd() to clean up journal references
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>
2026-01-01 17:13:59 -07:00
Simon Glass
ab9cd9a045 ext4l: Add a few Kconfig dependencies
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>
2026-01-01 17:13:59 -07:00
Simon Glass
93fbdeb4f6 ext4l: Use the real crc16 implementation
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>
2026-01-01 17:13:59 -07:00
Simon Glass
f635cfdb10 ext4l: Remove duplicate atomic_add declarations
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>
2026-01-01 17:13:59 -07:00
Simon Glass
cff8a56162 ext4l: Clean up fully when unmounting
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>
2026-01-01 17:13:55 -07:00
Simon Glass
b37da53a23 ext4l: Fix a few problems with handling bh_cache
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>
2026-01-01 14:31:27 -07:00
Simon Glass
f7db5fb482 ext4l: Add inode-tracking lists
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>
2026-01-01 14:27:30 -07:00
Simon Glass
142ffe2c65 ext4l: Move message buffer functions to support.c
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>
2026-01-01 14:27:30 -07:00
Simon Glass
5b792aad9e ext4l: Fix cmpxchg macro warning with clang
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>
2025-12-30 15:55:37 -07:00
Simon Glass
0d7e4430e3 ext4l: Fix bit operations for bits beyond first word
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>
2025-12-30 15:53:05 -07:00
Simon Glass
879e9f526d ext4l: Use percpu_counter initialized field
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>
2025-12-30 15:52:32 -07:00
Simon Glass
f5cf00f392 ext4l: Implement iput() to evict deleted inodes
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>
2025-12-30 15:52:11 -07:00
Simon Glass
20cb6b8024 ext4l: Return boot-relative time from ktime_get_real_seconds()
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>
2025-12-30 15:52:06 -07:00
Simon Glass
bd195aeed9 ext4l: Fix dquot functions to update i_blocks
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>
2025-12-30 15:52:04 -07:00
Simon Glass
22d24122c6 ext4l: Add ext4_commit_super() declaration
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>
2025-12-30 15:52:03 -07:00
Simon Glass
a70d9fa66f ext4l: Fix inode_init_owner to set i_mode
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>
2025-12-30 15:50:48 -07:00
Simon Glass
e2be062e4d ext4l: Implement buffer write I/O and allocation
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>
2025-12-30 15:50:39 -07:00
Simon Glass
6af248ee40 ext4l: Adjust folio offset and mapping operations
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>
2025-12-30 15:50:18 -07:00
Simon Glass
bb745f843c ext4l: Implement little-endian bit operations
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>
2025-12-30 15:48:36 -07:00
Simon Glass
014f082f05 ext4l: Add journal_head detection in bh_cache_clear
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>
2025-12-30 15:48:35 -07:00
Simon Glass
50b1e9f946 linux: ext4l: Initialize len in ext4_ext_find_hole
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
2025-12-30 13:53:48 -07:00
Simon Glass
52a65fdc6b linux: ext4l: Make cache init/exit functions reentrant for U-Boot
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>
2025-12-30 13:53:48 -07:00
Simon Glass
633636f9dc linux: ext4l: Export ext4_commit_super function
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>
2025-12-30 13:53:48 -07:00
Simon Glass
edcaae9539 linux: ext4l: Mark ext4_groupinfo_slab_names unused
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>
2025-12-30 13:53:48 -07:00
Simon Glass
5761cf33ab linux: jbd2: Add jbd2_journal_exit_global for clean shutdown
In U-Boot, filesystems may be mounted and unmounted multiple times in a
single session. The JBD2 global state (caches) was only initialized once
and never cleaned up, preventing proper reinitialization.

Add jbd2_journal_exit_global() to properly destroy caches and reset the
initialization flag. This allows the JBD2 subsystem to be cleanly
reinitialized on subsequent mounts.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-30 13:36:38 -07:00
Simon Glass
ae723b8385 linux: jbd2: Add validation in jbd2_journal_write_metadata_buffer
When debugging journal corruption issues, invalid journal_head or
buffer_head pointers can cause crashes that are difficult to diagnose.

Add explicit validation of jh_in and its associated buffer_head at the
start of jbd2_journal_write_metadata_buffer() to catch corruption early
and provide useful debug output rather than crashing with a SIGSEGV.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-30 13:36:38 -07:00
Simon Glass
111587bfd4 linux: ext4l: Mark journaled metadata buffers dirty for bh_cache_sync
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>
2025-12-30 13:35:48 -07:00
Simon Glass
1e8f07fe57 linux: ext4l: Skip orphan handling in U-Boot
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>
2025-12-30 13:26:48 -07:00
Simon Glass
f0f85edc07 linux: ext4l: Export ext4 functions for U-Boot interface
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>
2025-12-30 13:25:30 -07:00
Simon Glass
dbf97406e9 linux: jbd2: Add synchronous commit on transaction stop
U-Boot operates in a single-threaded environment without a journal
daemon. Commit transactions synchronously when jbd2_journal_stop()
is called and there are no active handles (t_updates == 0).

This ensures crash-safety by writing journal entries to disk immediately
after each file-operation completes.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-30 13:25:04 -07:00
Simon Glass
3235605698 linux: ext4l: Fix REQ_OP and BH_OwnsData bit positions
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>
2025-12-30 13:15:37 -07:00
Simon Glass
8349f9f700 fs: ext4l: Add statfs support
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>
2025-12-27 13:35:43 -07:00
Simon Glass
a6b1cd23a7 cmd: Add fsinfo command
Add the fsinfo command to display filesystem statistics including block
size, total blocks, used blocks, and free blocks. Both raw byte counts
and human-readable sizes are shown.

Example output:
  => fsinfo mmc 0:1
  Block size: 4096 bytes
  Total blocks: 16384 (67108864 bytes, 64 MiB)
  Used blocks: 2065 (8458240 bytes, 8.1 MiB)
  Free blocks: 14319 (58650624 bytes, 55.9 MiB)

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-27 13:35:43 -07:00
Simon Glass
fd4b07ff95 fs: Add statfs method to the filesystem interface
Add infrastructure for obtaining filesystem statistics. This includes:

- struct fs_statfs to hold block size, total blocks, and free blocks
- statfs method in struct fstype_info
- fs_statfs() wrapper function
- fs_statfs_unsupported() stub for filesystems without support

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-27 13:35:43 -07:00
Simon Glass
73848983f5 ext4l: Add uuid() support
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>
2025-12-27 13:35:43 -07:00
Simon Glass
5180ac32d7 ext4l: Add read() support
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>
2025-12-27 13:35:43 -07:00
Simon Glass
8810a02743 ext4l: Add size() support
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>
2025-12-27 13:35:43 -07:00
Simon Glass
0e9c88b170 ext4l: Add exists() support
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>
2025-12-27 13:35:42 -07:00
Simon Glass
b9558d8a06 ext4l: Add open/read/close directory
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>
2025-12-27 13:35:42 -07:00
Simon Glass
ac579a0ecb ext4l: Fix comment formatting
Add blank line after function doc titles per kernel-doc style.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-27 13:24:26 -07:00
Simon Glass
725c0ed93b ext4l: Fix path lookup by implementing dentry operations
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>
2025-12-27 13:24:26 -07:00