<feed xmlns='http://www.w3.org/2005/Atom'>
<title>u-boot.git/fs, branch next</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/u-boot.git/atom/fs?h=next</id>
<link rel='self' href='http://cgit.235523.xyz/u-boot.git/atom/fs?h=next'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/'/>
<updated>2026-08-22T19:48:06Z</updated>
<entry>
<title>fs: btrfs: fix zstd decompression of compressed inline extents</title>
<updated>2026-08-22T19:48:06Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-01T00:55:20Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=6f0719e4c420d9e3b1cbe92b2934e03f2f57e6fc'/>
<id>urn:sha1:6f0719e4c420d9e3b1cbe92b2934e03f2f57e6fc</id>
<content type='text'>
The kernel compresses an inline extent as a whole block:
run_delalloc_inline() calls btrfs_compress_bio(inode, 0, blocksize, ...),
so the data is zero-filled past EOF and the resulting zstd frame declares
a content size of one block. The extent item records the unaligned file
size though - __cow_file_range_inline() passes i_size down to
insert_inline_extent(), which stores it as ram_bytes.

btrfs_read_extent_inline() sizes its decompression buffer from ram_bytes,
so for a 1900-byte file the destination is 1900 bytes while the frame
decodes to 4096. Since commit 918adf8e0733 ("btrfs: Use U-Boot API for
decompression") btrfs decompresses through the common U-Boot helper,
which uses the one-shot zstd_decompress_dctx(). That API requires the
destination to cover the whole frame and fails with dstSize_tooSmall,
error 70, otherwise. The streaming ZSTD_decompressStream() path it
replaced stopped once the output buffer was full, so it never hit this.

The kernel side does not notice because fs/btrfs/zstd.c streams into its
own buffer and copies out at most destlen.

Allocate a full block for the decompression buffer and copy only
ram_bytes back to the caller. An inline extent never spans more than one
block, which bounds the allocation.

This shows up on RK3399 and ODROID-N2 as "zstd_decompress: failed to
decompress: 70" (armbian/build#9651, #10208), where it breaks fdt apply
on zstd-compressed overlays. Images built with mkfs.btrfs --rootdir
--compress zstd do not reproduce it, since btrfs-progs writes a frame
whose content size already equals ram_bytes. Only files written at
runtime through the kernel trip it.

Fixes: 918adf8e0733 ("btrfs: Use U-Boot API for decompression")
Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
<entry>
<title>fs: btrfs: deduplicate the inode size lookup</title>
<updated>2026-08-10T18:38:57Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-02T09:35:26Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=a11f8659f451c5601bac6fdf5b48594d347db38d'/>
<id>urn:sha1:a11f8659f451c5601bac6fdf5b48594d347db38d</id>
<content type='text'>
btrfs_readdir() and btrfs_size() both open code the same search for an
inode item to read its size field. Move it into one helper.

Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
<entry>
<title>fs: btrfs: release the path when btrfs_search_slot() fails</title>
<updated>2026-08-10T18:38:57Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-02T09:35:22Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=1a5c8af2d4e4b4029739eb8787ce259d74977dfd'/>
<id>urn:sha1:1a5c8af2d4e4b4029739eb8787ce259d74977dfd</id>
<content type='text'>
The U-Boot copy of btrfs_search_slot() returns on error with the nodes
it has descended through still attached to the path. The kernel one
releases the path on any error unless p-&gt;skip_release_on_error is set,
and callers written against that convention treat a failed search as
owning nothing. btrfs_size() is one: it returns straight away on a
search error and never reaches its btrfs_release_path() call, so the
attached extent buffer references leak.

Route both error exits through a release of the path. The error
returns of read_node_slot() carry no extra reference, so the path is
the only thing to clean up.

Suggested-by: Qu Wenruo &lt;quwenruo.btrfs@gmx.com&gt;
Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
<entry>
<title>fs: btrfs: report file sizes from readdir</title>
<updated>2026-08-10T18:38:57Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-02T09:35:19Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=1cf825afd0d7ebb4857002833658574efbef6626'/>
<id>urn:sha1:1cf825afd0d7ebb4857002833658574efbef6626</id>
<content type='text'>
btrfs_readdir() zeroes the dirent and fills in only the name and the
type, so dent-&gt;size stays 0 and every file is listed as zero bytes:

  =&gt; ls host 0 /
          0   f_192k.bin
          0   small_3k.bin

Reads themselves are fine, since btrfs_read() takes the size from
btrfs_size(), which does its own inode item lookup. It affects EFI
too: dir_read() in lib/efi_loader/efi_file.c copies dent-&gt;size into
both file_size and physical_size, so an EFI application enumerating a
directory on btrfs sees every file as empty, which is the generic-code
path Alexey's readdir series moves btrfs onto.

The custom listing that fs_ls_generic() replaced looked the inode item
up and printed the real size, and every other filesystem in the tree
fills dent-&gt;size in its own readdir: ext4fs.c:327, exfat io.c:805,
erofs fs.c:186, squashfs sqfs.c:1095 and fat.c:1555.

btrfs_next_dir_entry() already has the dir item mapped, so read the
key it points at while we are there and hand it back to the caller,
and use that to reach the inode item. A subvolume entry points at a
root item instead and has no size of its own, so leave that one at 0.

  =&gt; ls host 0 /
     196608   f_192k.bin
       3000   small_3k.bin

Fixes: 31cf3f177823 ("fs: btrfs: use fs_ls_generic() and drop custom implementation")
Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
<entry>
<title>Merge patch series "fs: regression-safe load &lt;iface&gt; for null_dev_desc_ok fstypes"</title>
<updated>2026-07-27T16:52:25Z</updated>
<author>
<name>Tom Rini</name>
<email>trini@konsulko.com</email>
</author>
<published>2026-07-27T15:07:51Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=7ffa20af30dd0a39c2c15eb81b03ba42fab1ea09'/>
<id>urn:sha1:7ffa20af30dd0a39c2c15eb81b03ba42fab1ea09</id>
<content type='text'>
Vincent Jardin &lt;vjardin@free.fr&gt; says:

3 commits providing documentation of impacts and testing the dispatch
for null_dev_desc_ok fstypes (semihosting, ubifs, sandbox) in the
generic `load &lt;iface&gt; ...` command.

The test does not cover ubifs, I could not make it work with
qemu. Since the code logic is there and testing with semihost
is done, it should cover the needed cases.

Link: https://lore.kernel.org/r/20260715165735.3207801-1-vjardin@free.fr
</content>
</entry>
<entry>
<title>fs: dispatch null_dev_desc_ok filesystems before lookup</title>
<updated>2026-07-27T15:07:39Z</updated>
<author>
<name>Vincent Jardin</name>
<email>vjardin@free.fr</email>
</author>
<published>2026-07-15T16:57:15Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=5b1dac9ee2029c6aa9fe4f8554f2250b94b89da2'/>
<id>urn:sha1:5b1dac9ee2029c6aa9fe4f8554f2250b94b89da2</id>
<content type='text'>
Filesystems that are null_dev_desc_ok (semihosting, ubifs) have
no UCLASS_BLK device under their ifname, so on real hardware
fs_set_blk_dev() always fails at the partition lookup.
The workaround was to add a per-filesystem
command (example cmd/ubifs.c), which duplicates the plumbing of
fstype_info.

Probe such entries with block_desc=NULL up front, so
  load semihosting - &lt;addr&gt; &lt;file&gt;
works without a new command.

Sandbox boards that exercise the existing fallback through "host
bind" stay unchanged.

Signed-off-by: Vincent Jardin &lt;vjardin@free.fr&gt;
Reviewed-by: Simon Glass &lt;sjg@chromium.org&gt;
</content>
</entry>
<entry>
<title>Merge patch series "fs/squashfs: fix symlink load failure on large images"</title>
<updated>2026-07-25T13:55:35Z</updated>
<author>
<name>Tom Rini</name>
<email>trini@konsulko.com</email>
</author>
<published>2026-07-25T13:55:35Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=b635d43bca429500cb8ef20aa151cb5773b9a8a5'/>
<id>urn:sha1:b635d43bca429500cb8ef20aa151cb5773b9a8a5</id>
<content type='text'>
Allan ELKAIM &lt;allan.elkaim@gmail.com&gt; says:

sqfsload fails to load a file through a symlink when the squashfs
image contains a large number of inodes (e.g. a rootfs that includes
the tzdata timezone database).

Root cause: sqfs_read_nest() resolves the symlink by calling itself
recursively without first freeing the parent directory's inode and
directory table buffers. This causes a temporary double allocation
that can exhaust the U-Boot heap. When malloc() subsequently fails
inside sqfs_read_directory_table(), the error goes undetected and
sqfs_search_dir() is called with a NULL pos_list pointer, leading to:

  Error: invalid inode reference to directory table.
  Failed to load '/boot/Image'

Patch 1 fixes the structural problem (temporary double allocation)
and plugs the silent NULL pointer path in sqfs_read_directory_table().
Patch 2 adds the missing return-value checks on sqfs_dir_offset() that
turn any residual lookup failure into a clean error propagation.

Patch 3 (reworked in v3 following Richard Genoud's review) fixes
pre-existing leaks of dirs-&gt;entry on the error paths of
sqfs_search_dir(), by centralizing the cleanup at the 'out' label.

All patches are independent and can be reviewed separately.

The bug was first observed on U-Boot v2024.01 and is still present
on v2026.04. The patches have been tested on a Raspberry Pi CM4
running U-Boot v2026.04 (Yocto Scarthgap 5.0.17) with a 325 MB
squashfs rootfs containing 22 517 inodes. The symlink
/boot/Image -&gt; Image-6.6.63-v8 now resolves successfully.

This series addresses the bug reported at:
https://lists.u-boot-project.org/pipermail/u-boot/2026-May/618533.html

Link: https://lore.kernel.org/r/20260713142420.2618339-1-allan.elkaim@gmail.com
</content>
</entry>
<entry>
<title>fs/squashfs: fix dirs-&gt;entry leaks on sqfs_search_dir() error paths</title>
<updated>2026-07-25T00:39:29Z</updated>
<author>
<name>Allan ELKAIM</name>
<email>allan.elkaim@gmail.com</email>
</author>
<published>2026-07-13T14:22:47Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=171b604888537dd7112ffddaa13abb16932eabd0'/>
<id>urn:sha1:171b604888537dd7112ffddaa13abb16932eabd0</id>
<content type='text'>
Several error paths in sqfs_search_dir() return through 'goto out'
while a directory entry obtained from sqfs_readdir_nest() is still
held, leaking dirs-&gt;entry: the inode lookup failure, the symlink
nesting limit check, every allocation/tokenization failure during
symlink resolution, and the case where readdir aborts after an
entry was already read.

Instead of freeing dirs-&gt;entry at each error site, centralize the
cleanup at the 'out' label: on error, no valid entry may be handed
back to the caller, so it can be freed unconditionally there. On
success, dirs-&gt;entry is already NULL: it is freed at the end of
each token iteration and before recursing into a symlink target,
and the root directory path never allocates it.

Explicit frees remain only where a success path needs them:
between reads in the readdir loop, at the end of each token
iteration, and before the recursive call. The now-redundant frees
on individual error paths are removed.

Suggested-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
Signed-off-by: Allan ELKAIM &lt;allan.elkaim@gmail.com&gt;
</content>
</entry>
<entry>
<title>fs/squashfs: add sqfs_dir_offset() error checks</title>
<updated>2026-07-25T00:39:29Z</updated>
<author>
<name>Allan ELKAIM</name>
<email>allan.elkaim@gmail.com</email>
</author>
<published>2026-07-13T14:22:45Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=57e0bb7bf00dadd7537f93609afb955108ce22c7'/>
<id>urn:sha1:57e0bb7bf00dadd7537f93609afb955108ce22c7</id>
<content type='text'>
sqfs_dir_offset() returns a negative errno on failure, but three
call sites in sqfs_search_dir() use the return value as an array
index without checking for errors first. If the lookup fails,
dirs-&gt;table is set to an invalid address, leading to undefined
behavior.

Add negative-value guards after each sqfs_dir_offset() call so
that any lookup failure propagates cleanly as an error rather
than producing incorrect results.

Note: the corresponding sqfs_find_inode() NULL checks and the
heap exhaustion fix during symlink resolution are applied in
separate patches.

Acked-by: Miquel Raynal &lt;miquel.raynal@bootlin.com&gt;
Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
Signed-off-by: Allan ELKAIM &lt;allan.elkaim@gmail.com&gt;
</content>
</entry>
<entry>
<title>fs/squashfs: fix heap exhaustion during symlink resolution</title>
<updated>2026-07-25T00:39:29Z</updated>
<author>
<name>Allan ELKAIM</name>
<email>allan.elkaim@gmail.com</email>
</author>
<published>2026-07-13T14:22:43Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=9a9d46cb5e1a8f600c52f3ddaeaca8d4f28f66ee'/>
<id>urn:sha1:9a9d46cb5e1a8f600c52f3ddaeaca8d4f28f66ee</id>
<content type='text'>
When sqfs_read_nest() encounters a symlink it resolves it by calling
itself recursively. In the unfixed code this looks like:

  // dirsp is open: inode_table + dir_table still on heap
  resolved = sqfs_resolve_symlink(symlink, filename);
  ret = sqfs_read_nest(resolved, ...); // recursive: allocates a new
                                       // inode_table + dir_table pair
  free(resolved);
  goto out;
  // out: sqfs_closedir(dirsp) &lt;- parent tables freed HERE, too late

There is no permanent leak: the parent's tables are freed at the
out: label once the recursive call returns. However, for the entire
duration of the recursive call both the parent's inode_table +
dir_table and the child's inode_table + dir_table are live on the
heap simultaneously. On large squashfs images these tables can be
significant in size, and this temporary double allocation may exhaust
the heap budget.

A superficial workaround would be to increase CONFIG_SYS_MALLOC_LEN,
but that wastes memory on all boards and does not address the
structural problem. The correct fix is to change the freeing order:
release the parent directory's resources before recursing. This way
only one set of inode and directory tables is live at any given time,
halving the peak heap usage during symlink resolution.

When heap exhaustion does occur and malloc returns NULL for dir_table
or pos_list inside sqfs_read_directory_table(), the failure is
currently silent and cascading:

  - metablks_count is not reset to -1 before the goto out, so the
    function returns a positive block count alongside a NULL pointer.
  - sqfs_opendir_nest() does not detect the failure (it only checks
    metablks_count &lt; 1) and calls sqfs_search_dir() with m_list=NULL.
  - sqfs_dir_offset() iterates over m_list[0..n], reading from
    addresses 0x0, 0x4, 0x8, ... None of those values match the
    inode's start_block, so the function returns -EINVAL.
  - The error propagates up as a load failure with no indication
    that the root cause was heap exhaustion:

      Error: invalid inode reference to directory table.
      Failed to load '&lt;symlink path&gt;'

Two fixes:
1. In sqfs_read_directory_table(), set metablks_count = -1 whenever
   malloc fails after sqfs_count_metablks() returns a positive value,
   so that the caller's "metablks_count &lt; 1" check correctly detects
   the failure and avoids calling sqfs_search_dir() with a NULL
   pos_list.
2. In sqfs_read_nest() and sqfs_size_nest(), call sqfs_closedir() on
   the parent dirsp before the recursive call so that the parent's
   inode and directory tables are freed before the child allocates
   its own. Only one set of tables is then live at any given time,
   halving peak heap usage during symlink resolution.

Link: https://lists.denx.de/pipermail/u-boot/2026-May/618533.html

Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
Acked-by: Miquel Raynal &lt;miquel.raynal@bootlin.com&gt;
Signed-off-by: Allan ELKAIM &lt;allan.elkaim@gmail.com&gt;
</content>
</entry>
</feed>
