<feed xmlns='http://www.w3.org/2005/Atom'>
<title>wireguard-linux/fs/erofs, branch stable</title>
<subtitle>WireGuard for the Linux kernel</subtitle>
<id>https://git.zx2c4.com/wireguard-linux/atom/fs/erofs?h=stable</id>
<link rel='self' href='https://git.zx2c4.com/wireguard-linux/atom/fs/erofs?h=stable'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/'/>
<updated>2026-09-11T04:16:20Z</updated>
<entry>
<title>erofs: add missing buf-&gt;off in erofs_bread()</title>
<updated>2026-09-11T04:16:20Z</updated>
<author>
<name>Binglei Wang</name>
<email>l3b2w1@gmail.com</email>
</author>
<published>2026-09-11T04:11:33Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=135d84c66f85426299db01a09d93a79a87af18ba'/>
<id>urn:sha1:135d84c66f85426299db01a09d93a79a87af18ba</id>
<content type='text'>
erofs_bread() locates the target folio with

 index = (buf-&gt;off + offset) &gt;&gt; PAGE_SHIFT;

but computes the in-folio offset without taking buf-&gt;off into account:

 return buf-&gt;base + (offset &amp; ~PAGE_MASK);

If buf-&gt;off is not page-aligned, the returned pointer misses the in-page
component of buf-&gt;off, so callers end up fetching data from a wrong
offset.

buf-&gt;off is set to sbi-&gt;dif0.fsoff in erofs_init_metabuf(), and fsoff can
be specified via the "fsoffset=" mount option, which only requires
block-size alignment. Therefore, on an image with a sub-page block size
(e.g. 512 bytes), a non-page-aligned fsoff (e.g. 512) triggers the issue,
since 512 is a multiple of the block size but not of PAGE_SIZE.

It can be reproduced by mounting an image that is placed at a
non-page-aligned offset:

 mkfs.erofs -b512 -zlz4hc sub.erofs src/
 # prepend 512 bytes of padding to the image
 mount -t erofs -o loop,fsoffset=512 padded.erofs /mnt

which fails with

 erofs (device loop0): cannot find valid erofs superblock

because the on-disk superblock (at offset 1024 within the image, i.e.
1536 within the padded file) is read from a wrong in-folio offset. With
this fixed, the very same image mounts successfully and its file contents
match those read from the unpadded image.

Fix it by including buf-&gt;off in the in-folio offset calculation, so that
it is consistent with the folio index calculation.

Fixes: c36ec00d7f67 ("erofs: add 'fsoffset' mount option to specify filesystem offset")
Signed-off-by: Binglei Wang &lt;l3b2w1@gmail.com&gt;
Reviewed-by: Gao Xiang &lt;xiang@kernel.org&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: delimit inode_share cache key components</title>
<updated>2026-09-07T10:20:30Z</updated>
<author>
<name>Chengyu Zhu</name>
<email>hudsonzhu@tencent.com</email>
</author>
<published>2026-09-07T08:33:19Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=96bf9831fbf423b8104f7948cd8fe7007ecfb46c'/>
<id>urn:sha1:96bf9831fbf423b8104f7948cd8fe7007ecfb46c</id>
<content type='text'>
Previously, inode_share keys were encoded as follows:

  fingerprint || domain_id

It would be better to have a separator between the fingerprint and domain
ID so that the fingerprint won't be parsed as part of a domain ID.

Change the key encoding as follows:

  domain_id || '\0' || fingerprint

Since domain_id is a NUL-terminated string, this makes the in-memory key
indices unambiguous.

Signed-off-by: Chengyu Zhu &lt;hudsonzhu@tencent.com&gt;
Reviewed-by: Gao Xiang &lt;xiang@kernel.org&gt;
Fixes: e0bf7d1c074d ("erofs: support user-defined fingerprint name")
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: disable LZ4 rolling decompression for now</title>
<updated>2026-09-03T14:49:35Z</updated>
<author>
<name>Gao Xiang</name>
<email>xiang@kernel.org</email>
</author>
<published>2026-09-03T14:28:41Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=82e664cf1219c459c33aae931b222cf951af9cb7'/>
<id>urn:sha1:82e664cf1219c459c33aae931b222cf951af9cb7</id>
<content type='text'>
LZ4 rolling decompression [1] was introduced to reduce the memory
footprint of temporary pages:

 For many cases, it is needed for users to read small data within
 a compressed extent (pcluster), either due to random small read, or
 since uptodate folios (typically order-0) cannot be reused for
 decompression again since decompression algorithm refills
 already-uptodate folios.

Rolling decompression works because LZ4 is LZ77-based and only refers
to the most recent 64 KiB of decompressed data, so in theory only a
bounded rolling window of temporary pages is needed when decompressing.

It can save a lot of temporary memory, e.g.
 601,960-byte data can be compressed into a 256k LZ4 compressed extent,
 which means it needs 146 extra pages per request in the worst case if
 rolling decompression is disabled.

However, the upstream LZ4 implementation is not under EROFS' control:
For example, the literal copy memmove() may still **copy long literals
backward** on x86 based on the address comparison even when the source
and destination ranges do not overlap (IOWs, inline decompression
doesn't need to be considered here). That breaks the rolling assumption
and makes the optimization broken.

Disable it for now to make sure the data correctness first since EROFS
is used everywhere now: The rolling window approach can be revived once
we either ensure that the official LZ4 code always copies forward for
non-overlapping ranges or maintain our own LZ4 implementation in EROFS.

The main impact is a higher runtime memory footprint; However, recent
commit 0f6273ab4637 ("erofs: add a reserved buffer pool for lz4
decompression") helps mitigate this when enabled but it's still not
perfect.

[1] https://www.usenix.org/conference/atc19/presentation/gao
    § 3.3 Decompression

Reported-by: "Walther, Jens-Uwe" &lt;waltju@amazon.de&gt;
Closes: https://lore.kernel.org/r/BEZP281MB2102E57CD31862B8D958B33DD2AC2@BEZP281MB2102.DEUP281.PROD.OUTLOOK.COM
Fixes: 8e6c8fa9f2e9 ("erofs: enable big pcluster feature")
Cc: Yann Collet &lt;yann.collet.73@gmail.com&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: preserve LZMA decoders on resize failure</title>
<updated>2026-09-02T02:32:01Z</updated>
<author>
<name>Nikhil Gurudasani</name>
<email>nikhilgurudasani314@gmail.com</email>
</author>
<published>2026-08-30T10:41:09Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=617d0d8d199ba1790c94310fd75a22d01c97a8d6'/>
<id>urn:sha1:617d0d8d199ba1790c94310fd75a22d01c97a8d6</id>
<content type='text'>
The pool-resize path frees each stream's old decoder before allocating
its replacement. If an allocation fails after some streams have already
been replaced, the failed stream is put back on the list with state ==
NULL. z_erofs_lzma_max_dictsize is still advanced as if the whole
pool had been resized.

An existing LZMA mount can select the broken stream and pass
NULL to xz_dec_microlzma_reset(). A retry at the same size also
skip another resize attempt. Since the global maximum was advanced,
thus, the invalid state is left unrepaired.

Allocate each replacement before freeing the old decoder, temporarily
retaining one old decoder during allocation. Stop at the first failure
and advance z_erofs_lzma_max_dictsize only after all streams satisfy
the request.

Record each stream's dictionary capacity so retries can skip streams
already enlarged before a partial failure.

Fixes: 622ceaddb764 ("erofs: lzma compression support")
Cc: stable@vger.kernel.org
Signed-off-by: Nikhil Gurudasani &lt;nikhilgurudasani314@gmail.com&gt;
Reviewed-by: Gao Xiang &lt;xiang@kernel.org&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: add sysfs feature entry for xattr prefixes</title>
<updated>2026-09-02T02:03:30Z</updated>
<author>
<name>Jingbo Xu</name>
<email>jefflexu@linux.alibaba.com</email>
</author>
<published>2026-09-02T01:50:39Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=839f075aabdf5c21048f9801b87c0b841dd3d064'/>
<id>urn:sha1:839f075aabdf5c21048f9801b87c0b841dd3d064</id>
<content type='text'>
Let /sys/fs/erofs/features/xattr_prefixes advertise that this kernel
supports the EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES on-disk format.

Fixes: 6a318ccd7e08 ("erofs: enable long extended attribute name prefixes")
Cc: stable@vger.kernel.org # 6.4+
Reviewed-by: Gao Xiang &lt;xiang@kernel.org&gt;
Signed-off-by: Jingbo Xu &lt;jefflexu@linux.alibaba.com&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>Merge tag 'erofs-for-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs</title>
<updated>2026-08-25T19:27:41Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-08-25T19:27:41Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=73ae59e975966d24e32926247ddb45a537ebe184'/>
<id>urn:sha1:73ae59e975966d24e32926247ddb45a537ebe184</id>
<content type='text'>
Pull more erofs updates from Gao Xiang:

 - Fix up the EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS default logic so
   that "make savedefconfig" won't write the needless default value to
   the defconfig file

 - Add support for SEEK_{HOLE,DATA}, splice() as well as enable large
   folios in inode_share mode

 - Fix z_erofs_gbuf_growsize() after the previous buffer resizing fails

* tag 'erofs-for-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: simplify z_erofs_gbuf_growsize()
  erofs: skip sufficiently large global buffers when resizing
  erofs: support large folios in inode_share mode
  erofs: support splice() in inode_share mode
  erofs: support SEEK_HOLE/SEEK_DATA in inode_share mode
  erofs: Fix EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS default logic
</content>
</entry>
<entry>
<title>erofs: simplify z_erofs_gbuf_growsize()</title>
<updated>2026-08-24T04:21:24Z</updated>
<author>
<name>Gao Xiang</name>
<email>xiang@kernel.org</email>
</author>
<published>2026-08-23T14:23:05Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=a7d28aa0e9b2c983b915d091f9596f0e3b253355'/>
<id>urn:sha1:a7d28aa0e9b2c983b915d091f9596f0e3b253355</id>
<content type='text'>
 - Use guard(mutex)() to manage gbuf_resize_mutex;

 - Nullify tmp_pages after successful allocation, so that the error
   path becomes clearer.

Reviewed-by: Chao Yu &lt;chao@kernel.org&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: skip sufficiently large global buffers when resizing</title>
<updated>2026-08-24T04:21:09Z</updated>
<author>
<name>Nikhil Gurudasani</name>
<email>nikhilgurudasani314@gmail.com</email>
</author>
<published>2026-08-22T14:00:17Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=a7d097cf01301c5da37927c8f26123d006f0fd8a'/>
<id>urn:sha1:a7d097cf01301c5da37927c8f26123d006f0fd8a</id>
<content type='text'>
z_erofs_gbuf_nrpages is advanced only after every global buffer has been
grown. If a resize fails after some buffers were enlarged, a retry
revisits those enlarged buffers.

Retrying the same size then returns -ENOMEM because alloc_pages_bulk()
has no pages to add and the unchanged return value is treated as a
failure. Retrying an intermediate size allocates a temporary pointer
array smaller than gbuf-&gt;nrpages and copies more existing pointers than
the array can hold.

Skip buffers that already satisfy the request. Once all remaining
buffers have caught up, advancing z_erofs_gbuf_nrpages again describes
the guaranteed minimum size across the pool.

Fixes: d6db47e571dc ("erofs: do not use pagepool in z_erofs_gbuf_growsize()")
Cc: stable@vger.kernel.org # 6.10+
Signed-off-by: Nikhil Gurudasani &lt;nikhilgurudasani314@gmail.com&gt;
Reviewed-by: Gao Xiang &lt;xiang@kernel.org&gt;
Reviewed-by: Chao Yu &lt;chao@kernel.org&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: support large folios in inode_share mode</title>
<updated>2026-08-24T04:20:57Z</updated>
<author>
<name>Jingbo Xu</name>
<email>jefflexu@linux.alibaba.com</email>
</author>
<published>2026-08-21T11:25:40Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=c77516e1e6fe914eb74d5f7a8ba9851f4ce31867'/>
<id>urn:sha1:c77516e1e6fe914eb74d5f7a8ba9851f4ce31867</id>
<content type='text'>
erofs_fill_inode() calls mapping_set_large_folios() on each erofs
file's own mapping, but in inode_share mode reads are routed to the
shared inode's page cache instead, whose mapping never had large
folio support enabled.

Set up large folios for the shared inode's mapping as well.

Signed-off-by: Jingbo Xu &lt;jefflexu@linux.alibaba.com&gt;
Reviewed-by: Gao Xiang &lt;xiang@kernel.org&gt;
Reviewed-by: Chao Yu &lt;chao@kernel.org&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
<entry>
<title>erofs: support splice() in inode_share mode</title>
<updated>2026-08-24T04:20:41Z</updated>
<author>
<name>Zhan Xusheng</name>
<email>zhanxusheng@xiaomi.com</email>
</author>
<published>2026-08-21T01:56:41Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=e8325399d6e18d2acc670999632a461d424611b9'/>
<id>urn:sha1:e8325399d6e18d2acc670999632a461d424611b9</id>
<content type='text'>
erofs_ishare_fops routes everything that touches the page cache to the
backing file in -&gt;private_data: read_iter clones the iocb onto it, mmap
does vma_set_file(), fadvise calls vfs_fadvise() on it.  splice_read was
left as filemap_splice_read(), which works on the user file's own mapping:
it does init_sync_kiocb(&amp;iocb, in), and filemap_get_pages() then takes
iocb-&gt;ki_filp-&gt;f_mapping.

So splice() and sendfile() fill the per-inode page cache rather than the
shared one.  The content is the same either way, since erofs_fill_inode()
sets a_ops on that mapping too, which is why this went unnoticed.  Two
identical 8 MiB files under inode_share, reading one of them with splice(2)
alone, in pages:

  before   own 2048   shared 0
  after    own 0      shared 2048

"own" is cachestat(fd), which reports the file's own mapping; "shared" is
mmap()+mincore(), which erofs_ishare_mmap() redirects to the backing file.

Read through the backing file, as read_iter already does.

Link: https://lore.kernel.org/all/b7dc7192-d586-45a2-bc4a-b41dc681c9bb@linux.alibaba.com/
Signed-off-by: Zhan Xusheng &lt;zhanxusheng@xiaomi.com&gt;
Reviewed-by: Jingbo Xu &lt;jefflexu@linux.alibaba.com&gt;
Reviewed-by: Chao Yu &lt;chao@kernel.org&gt;
Signed-off-by: Gao Xiang &lt;xiang@kernel.org&gt;
</content>
</entry>
</feed>
