Commit Graph
1447088 Commits
Author SHA1 Message Date
David Sterba 5127e497bd btrfs: remove 32bit compat code for VFS inode number
Commit 0b2600f81c ("treewide: change inode->i_ino from unsigned long
to u64") sets the inode number type to u64 unconditionally, so we can
use it directly as there's no difference on 32bit and 64bit platform. We
used to have a copy of the number in our btrfs_inode.

The size of btrfs_inode on 32bit platform is about 688 bytes (after the
change).

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Jan Kara d8d89ba2e5 btrfs: limit size of bios submitted from writeback
Currently btrfs_writepages() just accumulates as large bio as possible
(within writeback_control constraints) and then submits it. This can
however lead to significant latency in writeback IO submission (I have
observed tens of milliseconds) because the submitted bio easily has over
hundred of megabytes. Consequently this leads to IO pipeline stalls and
reduced throughput.

At the same time beyond certain size submitting so large bio provides
diminishing returns because the bio is split by the block layer
immediately anyway. So compute (estimate of) bio size beyond which we
are unlikely to improve performance and just submit the bio for
writeback once we accumulate that much to keep the IO pipeline busy.
This improves writeback throughput for sequential writes by about 15% on
the test machine I was using.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Jan Kara <jack@suse.cz>
[ Fix the handling of missing device to avoid NULL pointer dereference. ]
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Qu Wenruo bac3c2910c btrfs: remove 2K block size support
Originally 2K block size support was introduced to test subpage (block
size < page size) on x86_64 where the page size is exactly the original
minimal block size.

However that 2K block size support has some problems:

- No 2K nodesize support
  This is critical, as there is still no way to exercise the subpage
  metadata routine.

- Very easy to test subpage data path now
  With the currently experimental large folio support, it's very easy to
  test the subpage data folio path already, as when a folio larger than
  4K is encountered on x86_64, we will need all the subpage folio states
  and bitmaps.

  So there is no need to use 2K block size just to verify subpage data
  path even on x86_64.

And with the incoming huge folio (2M on x86_64) support, the 2K block
size will easily double the bitmap size, considering the burden to
maintain and the limited extra coverage, I believe it's time to remove
it for the incoming huge folio support.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Filipe Manana 798c2ef739 btrfs: change return type from int to bool in check_eb_range()
The function always returns true or false but the its return type is
defined as int, which makes no sense. Change it to bool.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Filipe Manana d54d38fed9 btrfs: add missing unlikely to if branches leading to a DEBUG_WARN()
If statement branches that lead to a DEBUG_WARN() are unexpected to happen
and in most places we surround their expressions with the unlikely tag,
however a few places are missing. Add the unlikely tag to those missing
places to make it explicit to a reader that it's not expected and to hint
the compiler to generate better code.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Thorsten Blum 4c45ac3623 btrfs: use QSTR() in __btrfs_ioctl_snap_create()
Drop the length argument and use the simpler QSTR().

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Filipe Manana a6df0dcc23 btrfs: use the enums instead of int type in struct btrfs_block_group fields
The 'disk_cache_state' and 'cached' fields are defined with an int type
but all the values we assigned to them come from the enums
btrfs_disk_cache_state and btrfs_caching_type. So change the type in the
btrfs_block_group structure from int to these enums - in practice an enum
is an int, so this is more for readability and clarity.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Sun YangKai <sunk67188@gmail.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Filipe Manana 2d1e969b44 btrfs: use min_size variable to setup block rsv in btrfs_replace_file_extents()
There's no need to calculate again the size for the temporary block
reserve in btrfs_replace_file_extents() - we have already calculated it
and stored it in the 'min_size' variable.

So use the variable to make it more clear and also make the variable const
since it's not supposed to change during the whole function.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
ZhengYuan Huang 18d32b0013 btrfs: balance: fix potential bg lookup failure in btrfs_may_alloc_data_chunk()
[BUG]
Running btrfs balance can trigger a null-ptr-deref before relocating a
data chunk when metadata corruption leaves a chunk in the chunk tree
without a corresponding block group in the in-memory cache:

  KASAN: null-ptr-deref in range [0x0000000000000088-0x000000000000008f]
  RIP: 0010:btrfs_may_alloc_data_chunk+0x40/0x1c0 fs/btrfs/volumes.c:3601
  Call Trace:
    __btrfs_balance fs/btrfs/volumes.c:4217 [inline]
    btrfs_balance+0x2516/0x42b0 fs/btrfs/volumes.c:4604
    btrfs_ioctl_balance fs/btrfs/ioctl.c:3577 [inline]
    btrfs_ioctl+0x25cf/0x5b90 fs/btrfs/ioctl.c:5313
    ...

[CAUSE]
__btrfs_balance() iterates the on-disk chunk tree and passes the chunk
logical bytenr to btrfs_may_alloc_data_chunk() before relocating a data
chunk. That helper then queries the in-memory block group cache:

  cache = btrfs_lookup_block_group(fs_info, chunk_offset);
  chunk_type = cache->flags;   /* cache may be NULL */

A corrupt image can contain a chunk item whose matching block group
item is missing, so no block group is ever inserted into the cache. In
that case btrfs_lookup_block_group() returns NULL.

The code only guards this with ASSERT(cache), which becomes a no-op when
CONFIG_BTRFS_ASSERT is disabled. The subsequent dereference of
cache->flags therefore crashes the kernel.

[FIX]
Add a NULL check after btrfs_lookup_block_group() in
btrfs_may_alloc_data_chunk() and print and error message for clarity.

Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
ZhengYuan Huang 7a308f6d29 btrfs: balance: fix potential bg lookup failure in chunk_usage_range_filter()
[BUG]
Running btrfs balance with a usage range filter (-dusage=min..max) can
trigger a null-ptr-deref when metadata corruption causes a chunk to have
no corresponding block group in the in-memory cache:

  KASAN: null-ptr-deref in range [0x0000000000000070-0x0000000000000077]
  RIP: 0010:chunk_usage_range_filter fs/btrfs/volumes.c:3845 [inline]
  RIP: 0010:should_balance_chunk fs/btrfs/volumes.c:4031 [inline]
  RIP: 0010:__btrfs_balance fs/btrfs/volumes.c:4182 [inline]
  RIP: 0010:btrfs_balance+0x249e/0x4320 fs/btrfs/volumes.c:4618
  ...
  Call Trace:
    btrfs_ioctl_balance fs/btrfs/ioctl.c:3577 [inline]
    btrfs_ioctl+0x25cf/0x5b90 fs/btrfs/ioctl.c:5313
    vfs_ioctl fs/ioctl.c:51 [inline]
    ...

The bug is reproducible on recent development branch.

[CAUSE]
Two separate data structures are involved:

1. The on-disk chunk tree, which records every chunk (logical address
   space region) and is iterated by __btrfs_balance().

2. The in-memory block group cache (fs_info->block_group_cache_tree),
   which is built at mount time by btrfs_read_block_groups() and holds
   a struct btrfs_block_group for each chunk. This cache is what the
   usage range filter queries.

On a well-formed filesystem, these two are kept in 1:1 correspondence.
However, btrfs_read_block_groups() builds the cache from block group
items in the extent tree, not directly from the chunk tree. A corrupted
image can therefore contain a chunk item in the chunk tree whose
corresponding block group item is absent from the extent tree; that
chunk's block group is then never inserted into the in-memory cache.

When balance iterates the chunk tree and reaches such an orphaned chunk,
should_balance_chunk() calls chunk_usage_range_filter(), which queries
the block group cache:

  cache = btrfs_lookup_block_group(fs_info, chunk_offset);
  chunk_used = cache->used;   /* cache may be NULL */

btrfs_lookup_block_group() returns NULL silently when no cached entry
covers chunk_offset. chunk_usage_range_filter() does not check the return
value, so the immediately following dereference of cache->used triggers
the crash.

[FIX]
Add a NULL check after btrfs_lookup_block_group() in
chunk_usage_range_filter(). When the lookup fails, emit a btrfs_err()
message identifying the affected bytenr and return -EUCLEAN to indicate
filesystem corruption.

Since chunk_usage_range_filter() now has an error path, change its
return type from bool to error pointer, return 0 if the chunk matches
the usage range, and 1 if it should be filtered out.

Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
ZhengYuan Huang 6dde5221f6 btrfs: balance: fix potential bg lookup failure in chunk_usage_filter()
[BUG]
Running btrfs balance with a usage filter (-dusage=N) can trigger a
null-ptr-deref when metadata corruption causes a chunk to have no
corresponding block group in the in-memory cache:

  KASAN: null-ptr-deref in range [0x0000000000000070-0x0000000000000077]
  RIP: 0010:chunk_usage_filter fs/btrfs/volumes.c:3874 [inline]
  RIP: 0010:should_balance_chunk fs/btrfs/volumes.c:4018 [inline]
  RIP: 0010:__btrfs_balance fs/btrfs/volumes.c:4172 [inline]
  RIP: 0010:btrfs_balance+0x2024/0x42b0 fs/btrfs/volumes.c:4604
  ...
  Call Trace:
    btrfs_ioctl_balance fs/btrfs/ioctl.c:3577 [inline]
    btrfs_ioctl+0x25cf/0x5b90 fs/btrfs/ioctl.c:5313
    vfs_ioctl fs/ioctl.c:51 [inline]
    ...

The bug is reproducible on current development branch.

[CAUSE]
Two separate data structures are involved:

1. The on-disk chunk tree, which records every chunk (logical address
   space region) and is iterated by __btrfs_balance().

2. The in-memory block group cache (fs_info->block_group_cache_tree),
   which is built at mount time by btrfs_read_block_groups() and holds
   a struct btrfs_block_group for each chunk. This cache is what the
   usage filter queries.

On a well-formed filesystem, these two are kept in 1:1 correspondence.
However, btrfs_read_block_groups() builds the cache from block group
items in the extent tree, not directly from the chunk tree. A corrupted
image can therefore contain a chunk item in the chunk tree whose
corresponding block group item is absent from the extent tree; that
chunk's block group is then never inserted into the in-memory cache.

When balance iterates the chunk tree and reaches such an orphaned chunk,
should_balance_chunk() calls chunk_usage_filter(), which queries the block
group cache:

  cache = btrfs_lookup_block_group(fs_info, chunk_offset);
  chunk_used = cache->used;   /* cache may be NULL */

btrfs_lookup_block_group() returns NULL silently when no cached entry
covers chunk_offset. chunk_usage_filter() does not check the return value,
so the immediately following dereference of cache->used triggers the crash.

[FIX]
Add a NULL check after btrfs_lookup_block_group() in chunk_usage_filter().
When the lookup fails, emit a btrfs_err() message identifying the
affected bytenr and return -EUCLEAN to indicate filesystem corruption.

Since chunk_usage_filter() now has an error path, change its return type
from bool to error pointer and 0 if the chunk passes the usage filter,
and 1 if it should be skipped.

Update should_balance_chunk() accordingly to propagate negative errors
from the usage filter.

Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:30 +02:00
Mark Harmstone c6153ed23e btrfs: add ioctl GET_CSUMS to read raw checksums from file range
Add a new unprivileged BTRFS_IOC_GET_CSUMS ioctl, which can be used to
query the on-disk csums for a file range.

The ioctl is deliberately per-file rather than exposing raw csum tree
lookups, to avoid leaking information to users about files they may not
have access to.

This is done by userspace passing a struct btrfs_ioctl_get_csums_args to
the kernel, which details the offset and length we're interested in, and
a buffer for the kernel to write its results into. The kernel writes a
struct btrfs_ioctl_get_csums_entry into the buffer, followed by the
csums if available. The maximum size of the user buffer is capped to
16MiB.

If the extent is an uncompressed, non-NODATASUM extent, the kernel sets
the entry type to BTRFS_GET_CSUMS_HAS_CSUMS and follows it with the
csums. If it is sparse, preallocated, or beyond the EOF, it sets the
type to BTRFS_GET_CSUMS_ZEROED - this is so userspace knows it can use
the precomputed hash of the zero sector. Otherwise, it sets the type to
BTRFS_GET_CSUMS_NODATASUM, BTRFS_GET_CSUMS_COMPRESSED,
BTRFS_GET_CSUM_ENCRYPTED, or BTRFS_GET_CSUM_INLINE.

For example, a file with a [0, 4K) hole and [4K, 12K) data extent would
produce the following output buffer:

  | [0, 4K) ZEROED | [4K, 12K) HAS_CSUMS | csum data |

We do store the csums of compressed extents, but we deliberately don't
return them here: they're calculated over the compressed data, not the
uncompressed data that's returned to userspace. Similarly for encrypted
data, once encryption is supported, in which the csums will be on the
ciphertext.

The main use case for this is for speeding up mkfs.btrfs --rootdir. For
the case when the source FS is btrfs and using the same csum algorithm,
we can avoid having to recalculate the csums - in my synthetic
benchmarks (16GB file on a spinning-rust drive), this resulted in a ~11%
speed-up (218s to 196s).

When using the --reflink option added in btrfs-progs v6.16.1, we can forgo
reading the data entirely, resulting a ~2200% speed-up on the same test
(128s to 6s).

    # mkdir rootdir
    # dd if=/dev/urandom of=rootdir/file bs=4096 count=4194304

    (without ioctl)
    # echo 3 > /proc/sys/vm/drop_caches
    # time mkfs.btrfs --rootdir rootdir testimg
    ...
    real    3m37.965s
    user    0m5.496s
    sys     0m6.125s

    # echo 3 > /proc/sys/vm/drop_caches
    # time mkfs.btrfs --rootdir rootdir --reflink testimg
    ...
    real    2m8.342s
    user    0m5.472s
    sys     0m1.667s

    (with ioctl)
    # echo 3 > /proc/sys/vm/drop_caches
    # time mkfs.btrfs --rootdir rootdir testimg
    ...
    real    3m15.865s
    user    0m4.258s
    sys     0m6.261s

    # echo 3 > /proc/sys/vm/drop_caches
    # time mkfs.btrfs --rootdir rootdir --reflink testimg
    ...
    real    0m5.847s
    user    0m2.899s
    sys     0m0.097s

Another notable use case is for deduplication, where reading the
checksums may serve as a hint instead of reading the whole file data.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Mark Harmstone <mark@harmstone.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Qu Wenruo 95ee223189 btrfs: check and set EXTENT_DELALLOC_NEW before clearing EXTENT_DELALLOC
[WARNING]
When running test cases with injected errors or shutdown, e.g.
generic/388 or generic/475, there is a chance that the following kernel
warning is triggered:

  BTRFS info (device dm-2): first mount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff
  BTRFS info (device dm-2): using crc32c checksum algorithm
  BTRFS info (device dm-2): checking UUID tree
  BTRFS info (device dm-2): turning on async discard
  BTRFS info (device dm-2): enabling free space tree
  BTRFS critical (device dm-2 state E): emergency shutdown
  ------------[ cut here ]------------
  WARNING: extent_io.c:1742 at extent_writepage_io+0x437/0x520 [btrfs], CPU#2: kworker/u43:2/651591
  CPU: 2 UID: 0 PID: 651591 Comm: kworker/u43:2 Tainted: G        W  OE       7.0.0-rc6-custom+ #365 PREEMPT(full)  5804053f02137e627472d94b5128cc9fcb110e88
  RIP: 0010:extent_writepage_io+0x437/0x520 [btrfs]
  Call Trace:
   <TASK>
   extent_write_cache_pages+0x2a5/0x820 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
   btrfs_writepages+0x74/0x130 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
   do_writepages+0xd0/0x160
   __writeback_single_inode+0x42/0x340
   writeback_sb_inodes+0x22d/0x580
   wb_writeback+0xc6/0x360
   wb_workfn+0xbd/0x470
   process_one_work+0x198/0x3b0
   worker_thread+0x1c8/0x330
   kthread+0xee/0x120
   ret_from_fork+0x2a6/0x330
   ret_from_fork_asm+0x11/0x20
   </TASK>
  ---[ end trace 0000000000000000 ]---
  BTRFS error (device dm-2 state E): root 5 ino 259 folio 1323008 is marked dirty without notifying the fs
  BTRFS error (device dm-2 state E): failed to submit blocks, root=5 inode=259 folio=1323008 submit_bitmap=0: -117
  BTRFS info (device dm-2 state E): last unmount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff

[CAUSE]
Inside btrfs we have the following pattern in several locations, for
example inside btrfs_dirty_folio():

	btrfs_clear_extent_bit(&inode->io_tree, start_pos, end_of_last_block,
			       EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
			       cached);

	ret = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
					extra_bits, cached);
	if (ret)
		return ret;

However btrfs_set_extent_delalloc() can return IO errors other than -ENOMEM
through the following callchain:

 btrfs_set_extent_delalloc()
 \- btrfs_find_new_delalloc_bytes()
    \- btrfs_get_extent()
       \- btrfs_lookup_file_extent()
          \- btrfs_search_slot()

When such IO error happened, the previous btrfs_clear_extent_bit() has
cleared the EXTENT_DELALLOC for the range, and we're expecting
btrfs_set_extent_delalloc() to re-set EXTENT_DELALLOC.

But since btrfs_set_extent_delalloc() failed before
btrfs_set_extent_bit(), EXTENT_DELALLOC flag is no longer present.

And if the folio range is dirty before entering
btrfs_set_extent_delalloc(), we got a dirty folio but no EXTENT_DELALLOC
flag now.

Then we hit the folio writeback:

  extent_writepage()
  |- writepage_delalloc()
  |  No ordered extent is created, as there is no EXTENT_DELALLOC set
  |  for the folio range.
  |  This also means the folio has no ordered flag set.
  |
  |- extent_writepage_io()
     \- if (unlikely(!folio_test_ordered(folio))
        Now we hit the warning.

[FIX]
Introduce a new helper, btrfs_reset_extent_delalloc() to replace the
currently open-coded btrfs_clear_extent_bit() +
btrfs_set_extent_delalloc() combination.

Instead of calling btrfs_clear_extent_bit() first, update
EXTENT_DELALLOC_NEW first, as that part can fail due to metadata IO,
meanwhile btrfs_clear_extent_bit() and btrfs_set_extent_bit() won't
return any error but retry memory allocation until succeeded.

This allows us to fail early without clearing EXTENT_DELALLOC bit, so
even if that new btrfs_reset_extent_delalloc() failed before touching
EXTENT_DELALLOC, the existing dirty range will still have their old
EXTENT_DELALLOC flag present, thus avoid the warning.

CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 4b01341133 btrfs: remove unnecessary ctl argument from write_cache_extent_entries()
There is no need to pass the free space control structure as an argument
because we can grab it from the given block group.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 5580c972e5 btrfs: remove unnecessary ctl argument from __btrfs_write_out_cache()
We can get the free space control structure from the given block group,
so there is no need to pass it as an argument.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 81b86e6afe btrfs: remove block group argument from copy_free_space_cache()
It's not necessary since we can get the block group from the given
free space control structure.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 2a1ed20f0d btrfs: remove op field from struct btrfs_free_space_ctl
The op field always points to the same use_bitmap function, the only
exception is during self tests where we make it temporarily point to a
different function. So just because of this op pointer field we are
increasing the structure size by 8 bytes.

Instead of storing a pointer to a use_bitmap function in struct
btrfs_free_space_ctl, move the pointer to struct btrfs_info, make
insert_into_bitmap() use that pointer if we are running the self tests
and initialize that pointer to the current, default use_bitmap function
(now exported for the tests as btrfs_use_bitmap). This way we reduce
the size of struct btrfs_free_space_ctl from 136 to 128 bytes and can
now fit 32 structures in a 4K page instead of 30. This also avoids the
cost of the indirection of a function pointer call when we are not
running the self tests.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 08d9e2162c btrfs: reduce size of struct btrfs_free_space_ctl
We have a 4 bytes hole in the structure, reorder some fields so that we
eliminate the hole and reduce the structure size from 144 bytes down to
136 bytes. This way on a 4K page system, we can fit 30 structures per
page instead of 28.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana acef2bf43a btrfs: remove unit field from struct btrfs_free_space_ctl
The unit field always has a value matching the sector size, and since we
have a block group pointer in the structure, we can access the block group
and then its fs_info field to get to the sector size. So remove the field,
which will allow us later to shrink the structure size.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 5e4b57f77c btrfs: remove start field from struct btrfs_free_space_ctl
There's no need for the start field, we can take it from the block group.
This reduces the structure size from 152 bytes down to 144 bytes, so on
a 4K page system we can now fit 28 structures instead of 26.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana 66fd877b13 btrfs: use a kmem_cache for free space control structures
We are currently allocating the free space control structures for block
groups using the generic slabs, and given that the size of the
btrfs_free_space_ctl structure is 152 bytes (on a release kernel), we end
up using the kmalloc-192 slab and therefore waste quite some memory since
on a 4K page system we can only fit 21 free space control structures per
page. These structures are allocated and delallocated every time we create
and remove block groups.

So use a kmem_cache for free space control structures, this way on a 4K
page system we can fit 26 structures instead of 21.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:29 +02:00
Filipe Manana a8d1f0b539 btrfs: reduce size of struct btrfs_block_group
We currently have several holes in the structure:

  struct btrfs_block_group {
        struct btrfs_fs_info *     fs_info;              /*     0     8 */
        struct btrfs_inode *       inode;                /*     8     8 */
        spinlock_t                 lock __attribute__((__aligned__(4))); /*    16     4 */

        /* XXX 4 bytes hole, try to pack */

        u64                        start;                /*    24     8 */
        u64                        length;               /*    32     8 */
        u64                        pinned;               /*    40     8 */
        u64                        reserved;             /*    48     8 */
        u64                        used;                 /*    56     8 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        u64                        delalloc_bytes;       /*    64     8 */
        u64                        bytes_super;          /*    72     8 */
        u64                        flags;                /*    80     8 */
        u64                        cache_generation;     /*    88     8 */
        u64                        global_root_id;       /*    96     8 */
        u64                        remap_bytes;          /*   104     8 */
        u32                        identity_remap_count; /*   112     4 */

        /* XXX 4 bytes hole, try to pack */

        u64                        last_used;            /*   120     8 */
        /* --- cacheline 2 boundary (128 bytes) --- */
        u64                        last_remap_bytes;     /*   128     8 */
        u32                        last_identity_remap_count; /*   136     4 */

        /* XXX 4 bytes hole, try to pack */

        u64                        last_flags;           /*   144     8 */
        u32                        bitmap_high_thresh;   /*   152     4 */
        u32                        bitmap_low_thresh;    /*   156     4 */
        struct rw_semaphore        data_rwsem __attribute__((__aligned__(8))); /*   160    40 */
        /* --- cacheline 3 boundary (192 bytes) was 8 bytes ago --- */
        long unsigned int          full_stripe_len;      /*   200     8 */
        long unsigned int          runtime_flags;        /*   208     8 */
        unsigned int               ro;                   /*   216     4 */
        int                        disk_cache_state;     /*   220     4 */
        int                        cached;               /*   224     4 */

        /* XXX 4 bytes hole, try to pack */

       struct btrfs_caching_control * caching_ctl;      /*   232     8 */
        struct btrfs_space_info *  space_info;           /*   240     8 */
        struct btrfs_free_space_ctl * free_space_ctl;    /*   248     8 */
        /* --- cacheline 4 boundary (256 bytes) --- */
        struct rb_node             cache_node __attribute__((__aligned__(8))); /*   256    24 */
        struct list_head           list;                 /*   280    16 */
        refcount_t                 refs __attribute__((__aligned__(4))); /*   296     4 */

        /* XXX 4 bytes hole, try to pack */

        struct list_head           cluster_list;         /*   304    16 */
        /* --- cacheline 5 boundary (320 bytes) --- */
        struct list_head           bg_list;              /*   320    16 */
        struct list_head           ro_list;              /*   336    16 */
        atomic_t                   frozen __attribute__((__aligned__(4))); /*   352     4 */

        /* XXX 4 bytes hole, try to pack */

        struct list_head           discard_list;         /*   360    16 */
        int                        discard_index;        /*   376     4 */

        /* XXX 4 bytes hole, try to pack */

        /* --- cacheline 6 boundary (384 bytes) --- */
        u64                        discard_eligible_time; /*   384     8 */
        u64                        discard_cursor;       /*   392     8 */
        enum btrfs_discard_state   discard_state;        /*   400     4 */

        /* XXX 4 bytes hole, try to pack */

        struct list_head           dirty_list;           /*   408    16 */
        struct list_head           io_list;              /*   424    16 */
        struct btrfs_io_ctl        io_ctl;               /*   440    72 */
        /* --- cacheline 8 boundary (512 bytes) --- */
        atomic_t                   reservations __attribute__((__aligned__(4))); /*   512     4 */
        atomic_t                   nocow_writers __attribute__((__aligned__(4))); /*   516     4 */
        struct mutex               free_space_lock __attribute__((__aligned__(8))); /*   520    32 */
        bool                       using_free_space_bitmaps; /*   552     1 */
        bool                       using_free_space_bitmaps_cached; /*   553     1 */

       /* XXX 2 bytes hole, try to pack */

        int                        swap_extents;         /*   556     4 */
        u64                        alloc_offset;         /*   560     8 */
        u64                        zone_unusable;        /*   568     8 */
        /* --- cacheline 9 boundary (576 bytes) --- */
        u64                        zone_capacity;        /*   576     8 */
        u64                        meta_write_pointer;   /*   584     8 */
        struct btrfs_chunk_map *   physical_map;         /*   592     8 */
        struct list_head           active_bg_list;       /*   600    16 */
        struct work_struct         zone_finish_work;     /*   616    32 */
        /* --- cacheline 10 boundary (640 bytes) was 8 bytes ago --- */
        struct extent_buffer *     last_eb;              /*   648     8 */
        enum btrfs_block_group_size_class size_class;    /*   656     4 */

        /* XXX 4 bytes hole, try to pack */

        u64                        reclaim_mark;         /*   664     8 */

        /* size: 672, cachelines: 11, members: 61 */
        /* sum members: 634, holes: 10, sum holes: 38 */
        /* forced alignments: 8 */
        /* last cacheline: 32 bytes */
  } __attribute__((__aligned__(8)));

Reorder some fields to eliminate the holes while keeping closely related
or frequently accessed fields together. After the reordering the size of
the structure is reduced down to 632 bytes and the number of cache lines
decreases from 11 to 10. We can still only pack 6 block groups per 4K page
but on a 64K page system we will now be able to pack 103 block groups
instead of 97. The new structure layout, on a release kernel, is the
following:

  struct btrfs_block_group {
        struct btrfs_fs_info *     fs_info;              /*     0     8 */
        struct btrfs_inode *       inode;                /*     8     8 */
        spinlock_t                 lock __attribute__((__aligned__(4))); /*    16     4 */
        unsigned int               ro;                   /*    20     4 */
        u64                        start;                /*    24     8 */
        u64                        length;               /*    32     8 */
        u64                        pinned;               /*    40     8 */
        u64                        reserved;             /*    48     8 */
        u64                        used;                 /*    56     8 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        u64                        delalloc_bytes;       /*    64     8 */
        u64                        bytes_super;          /*    72     8 */
        u64                        flags;                /*    80     8 */
        u64                        cache_generation;     /*    88     8 */
        u64                        global_root_id;       /*    96     8 */
        u64                        remap_bytes;          /*   104     8 */
        u32                        identity_remap_count; /*   112     4 */
        u32                        last_identity_remap_count; /*   116     4 */
        u64                        last_used;            /*   120     8 */
        /* --- cacheline 2 boundary (128 bytes) --- */
        u64                        last_remap_bytes;     /*   128     8 */
        u64                        last_flags;           /*   136     8 */
        u32                        bitmap_high_thresh;   /*   144     4 */
        u32                        bitmap_low_thresh;    /*   148     4 */
        struct rw_semaphore        data_rwsem __attribute__((__aligned__(8))); /*   152    40 */
        /* --- cacheline 3 boundary (192 bytes) --- */
        long unsigned int          full_stripe_len;      /*   192     8 */
        long unsigned int          runtime_flags;        /*   200     8 */
        int                        disk_cache_state;     /*   208     4 */
        int                        cached;               /*   212     4 */
        struct btrfs_caching_control * caching_ctl;      /*   216     8 */
        struct btrfs_space_info *  space_info;           /*   224     8 */
        struct btrfs_free_space_ctl * free_space_ctl;    /*   232     8 */
        struct rb_node             cache_node __attribute__((__aligned__(8))); /*   240    24 */
        /* --- cacheline 4 boundary (256 bytes) was 8 bytes ago --- */
        struct list_head           list;                 /*   264    16 */
        refcount_t                 refs __attribute__((__aligned__(4))); /*   280     4 */
        atomic_t                   frozen __attribute__((__aligned__(4))); /*   284     4 */
        struct list_head           cluster_list;         /*   288    16 */
        struct list_head           bg_list;              /*   304    16 */
        /* --- cacheline 5 boundary (320 bytes) --- */
        struct list_head           ro_list;              /*   320    16 */
        struct list_head           discard_list;         /*   336    16 */
        int                        discard_index;        /*   352     4 */
        enum btrfs_discard_state   discard_state;        /*   356     4 */
        u64                        discard_eligible_time; /*   360     8 */
        u64                        discard_cursor;       /*   368     8 */
        struct list_head           dirty_list;           /*   376    16 */
        /* --- cacheline 6 boundary (384 bytes) was 8 bytes ago --- */
        struct list_head           io_list;              /*   392    16 */
        struct btrfs_io_ctl        io_ctl;               /*   408    72 */
        /* --- cacheline 7 boundary (448 bytes) was 32 bytes ago --- */
        atomic_t                   reservations __attribute__((__aligned__(4))); /*   480     4 */
        atomic_t                   nocow_writers __attribute__((__aligned__(4))); /*   484     4 */
        struct mutex               free_space_lock __attribute__((__aligned__(8))); /*   488    32 */
        /* --- cacheline 8 boundary (512 bytes) was 8 bytes ago --- */
        bool                       using_free_space_bitmaps; /*   520     1 */
        bool                       using_free_space_bitmaps_cached; /*   521     1 */

        /* XXX 2 bytes hole, try to pack */
        /* Bitfield combined with previous fields */

        static enum btrfs_block_group_size_class size_class; /*     0: 0  0 */
        int                        swap_extents;         /*   524     4 */
        u64                        alloc_offset;         /*   528     8 */
        u64                        zone_unusable;        /*   536     8 */
        u64                        zone_capacity;        /*   544     8 */
        u64                        meta_write_pointer;   /*   552     8 */
        struct btrfs_chunk_map *   physical_map;         /*   560     8 */
        struct list_head           active_bg_list;       /*   568    16 */
        /* --- cacheline 9 boundary (576 bytes) was 8 bytes ago --- */
        struct work_struct         zone_finish_work;     /*   584    32 */
        struct extent_buffer *     last_eb;              /*   616     8 */
        u64                        reclaim_mark;         /*   624     8 */

        /* size: 632, cachelines: 10, members: 60, static members: 1 */
        /* sum members: 630, holes: 1, sum holes: 2 */
        /* sum bitfield members: 8 bits (1 bytes) */
        /* forced alignments: 8 */
        /* last cacheline: 56 bytes */
  } __attribute__((__aligned__(8)));

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
Filipe Manana d293344c22 btrfs: use a kmem_cache for block groups
We are currently allocating block groups using the generic slabs, and
given that the size of btrfs_block_group structure is 672 bytes (on a
release kernel), we end up using the kmalloc-1024 slab and therefore
waste quite some memory since on a 4K page system we can only fit 4
block groups per page. The block groups are also allocated and
delallocated with some frequency, specially if we have auto reclaim
enabled.

So use a kmem_cache for block groups, this way on a 4K page system we
can fit 6 block groups per page instead of 4.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba 3fc0803f1c btrfs: make more ASSERTs verbose, part 3
We have support for optional string to be printed in ASSERT() (added in
19468a623a ("btrfs: enhance ASSERT() to take optional format
string")), it's not yet everywhere it could be so add a few more files.

Try to finish what was left after 1c094e6cce ("btrfs: make a few
more ASSERTs verbose").

Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba b1db292ee3 btrfs: convert ioctl handlers to AUTO_KFREE
Many ioctl handlers are suitable for the AUTO_KFREE conversions as the
data are temporary and short lived. The conversions are trivial or the
collateral changes are straightforward.

A kfree() preceding mnt_drop_write_file() is slightly more efficient but
in the reverse order (i.e. the automatic kfree) does not cause any
significant change as the write drop does only a few simple operations.

Note: __free() handles also error pointers, so this is safe for the
memdup_user() errors too.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba 37f1f51fba btrfs: convert kmalloc_array to kmalloc_objs in btrfs_calc_avail_data_space()
There's one use of kmalloc_array() that can be transformed to
kmalloc_objs() in the same way as suggested in commit 69050f8d6d
("treewide: Replace kmalloc with kmalloc_obj for non-scalar types"),
swap the arguments and drop GFP flags. All the other cases of
kmalloc_array() do not use a simple type so this is the only one.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba 9f4ab0787e btrfs: do more kmalloc_obj()/kmalloc_objs() conversions
Do a few more (trivial) conversions that started in commit 69050f8d6d
("treewide: Replace kmalloc with kmalloc_obj for non-scalar types").

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba 54ce0b1d59 btrfs: lift assertions to beginning of insert_delayed_ref()
There are only two possible types of the delayed ref action, this can be
verified at the beginning for the whole function and not just one block.
Replace the assertion with a debugging warning just in case.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba 1a69592502 btrfs: replace open coded DEBUG_WARN in extent_writepage()
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
David Sterba cf384a2ab8 btrfs: move condition to WARN_ON in btrfs_set_delalloc_extent()
For a simple if + WARN_ON we should use the condition directly in the
macro.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
Qu Wenruo 115421e29b btrfs: remove folio checked subpage bitmap tracking
The folio checked flag is only utilized by the COW fixup mechanism
inside btrfs.

Since the COW fixup is already removed from non-experimental builds,
there is no need to keep the checked subpage bitmap.

This will saves us some space for large folios, for example for a single
256K sized large folio on 4K page sized systems:

 Old bitmap size = 6 * (256K / 4K / 8) = 48 bytes
 New bitmap size = 5 * (256K / 4K / 8) = 40 bytes

This will be more obvious when we're going to support huge folios (order
= 9).

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:28 +02:00
Qu Wenruo b2a9f217ad btrfs: remove the COW fixup mechanism
[BACKGROUND]
Btrfs has a special mechanism called COW fixup, which detects dirty
pages without an ordered extent (folio ordered flag).

Normally a dirty folio must go through delayed allocation (delalloc)
before it can be submitted, and delalloc will create an ordered extent
for it and mark the range with ordered flag.

However in older kernels, there are bugs related to get_user_pages()
which can lead to some page marked dirty but without notifying the fs to
properly prepare them for writeback.

In that case without an ordered extent btrfs is unable to properly
submit such dirty folios, thus the COW fixup mechanism is introduced,
which do the extra space reservation so that they can be written back
properly.

[MODERN SOLUTIONS]
The MM layer has solved it properly now with the introduction of
pin_user_pages*(), so we're handling cases that are no longer valid.

So commit 7ca3e84980 ("btrfs: reject out-of-band dirty folios during
writeback") is introduced to change the behavior from going through
COW fixup to rejecting them directly for experimental builds.

So far it works fine, but when errors are injected into the IO path, we
have random failures triggering the new warnings.

It looks like we have error path that cleared the ordered flag but
leaves the folio dirty flag, which later triggers the warning.

[REMOVAL OF COW FIXUP]
Although I hope to fix all those known warnings cases, I just can not
figure out the root cause yet.

But on the other hand, if we remove the ordered and checked flags in the
future, and purely rely on the dirty flags and ordered extent search, we
can get a much cleaner handling.

Considering it's no longer hitting the COW fixup for normal IO paths, I
think it's finally the time to remove the COW fixup completely.

Furthermore, the function name "btrfs_writepage_cow_fixup()" is no
longer meaningful, and since it's pretty small, only a folio flag check
with error message, there is no need to put it as a dedicated helper,
just open code it inside extent_writepage_io().

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:27 +02:00
Qu Wenruo 79a15639bf btrfs: pass a valid btrfs_tree_parent_check when possible
Commit 6e181cfe2409 ("btrfs: revalidate cached tree blocks on the
uptodate path") introduced the @check parameter for
btrfs_buffer_uptodate() to allow re-validation of a cached extent
buffer.

But there are still call sites that don't utilize this parameter, which
exposes them to possible corrupted tree blocks, e.g. an empty child leaf
of a parent node, which should be rejected by btrfs_verify_level_key()
but if @check is NULL such check will be skipped and cause problems.

Thankfully for a lot of cases there is already an existing @check
structure around and we can pass it directly to btrfs_buffer_uptodate().

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08 15:53:27 +02:00
Linus Torvalds 4549871118 Linux 7.1-rc7 2026-06-07 15:37:58 -07:00
Linus Torvalds c68691dc1d Merge tag 'x86-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:

 - Add more AMD Zen6 models (Pratik Vishwakarma)

 - Avoid confusing bootup message by the Intel resctl enumeration
   code when running on certain AMD systems (Tony Luck)

* tag 'x86-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/resctrl: Only check Intel systems for SNC
  x86/CPU/AMD: Add more Zen6 models
2026-06-07 13:12:29 -07:00
Linus Torvalds 09feffa073 Merge tag 'timers-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Ingo Molnar:

 - Fix the arch_inlined_clockevent_set_next_coupled() prototype in the
   !CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST case (Naveen Kumar Chaudhary)

 - Fix an off-by-1 bug in the sys_settimeofday() usecs validation code
   (Naveen Kumar Chaudhary)

 - Mark vdso_k_*_data pointers as __ro_after_init (Thomas Weißschuh)

 - Fix livelock race in tmigr_handle_remote_up() (Amit Matityahu)

* tag 'timers-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  timers/migration: Fix livelock in tmigr_handle_remote_up()
  vdso/datastore: Mark vdso_k_*_data pointers as __ro_after_init
  time: Fix off-by-one in settimeofday() usec validation
  clockevents: Fix duplicate type specifier in stub function parameter
2026-06-07 13:02:02 -07:00
Linus Torvalds 77e8e6861b Merge tag 'sched-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull rseq fix from Ingo Molnar:

 - Fix uninitialized stack variable in rseq_exit_user_update() (Qing
   Wang)

* tag 'sched-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  rseq: Fix using an uninitialized stack variable in rseq_exit_user_update()
2026-06-07 12:54:37 -07:00
Linus Torvalds 96c1ddbc16 Merge tag 'locking-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Ingo Molnar:

 - Fix a NULL pointer dereference bug in the FUTEX_CMP_REQUEUE_PI
   code (Ji'an Zhou)

 - Fix a NULL pointer dereference bug in the rtmutex code (Davidlohr
   Bueso)

* tag 'locking-urgent-2026-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  locking/rtmutex: Skip remove_waiter() when waiter is not enqueued
  futex/requeue: Prevent NULL pointer dereference in remove_waiter() on self-deadlock
2026-06-07 12:43:21 -07:00
Linus Torvalds e2264c52e1 Merge tag 'regulator-fix-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator fix from Mark Brown:
 "Arnd's randconfig testing turned up a missing selection of
  CONFIG_IRQ_DOMAIN which was causing build breaks"

* tag 'regulator-fix-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: mt6363: select CONFIG_IRQ_DOMAIN
2026-06-07 12:39:36 -07:00
Linus Torvalds 33d8d8ec31 Merge tag 'input-for-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov:

 - two quirks for atkbd to deal with laptops that can not handle
   "deactivate" command on the keyboard PS/2 port

* tag 'input-for-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: atkbd - skip deactivate for HONOR BCC-N's internal keyboard
  Input: atkbd - add DMI quirk for Lenovo Yoga Air 14 (83QK)
2026-06-07 08:40:53 -07:00
Nathan Chancellor 979c294509 cfi: Include uaccess.h for get_kernel_nofault()
After commit 0652a3daa7 ("tracing: Fix CFI violation in probestub
being called by tprobes"), there are many build errors when building
ARCH=arm multi_v7_defconfig + CONFIG_CFI=y like:

  In file included from drivers/base/devres.c:17:
  In file included from drivers/base/trace.h:16:
  In file included from include/linux/tracepoint.h:23:
  include/linux/cfi.h:44:6: error: call to undeclared function 'get_kernel_nofault'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     44 |         if (get_kernel_nofault(hash, func - cfi_get_offset()))
        |             ^
  1 error generated.

get_kernel_nofault() is called in the generic version of
cfi_get_func_hash() but nothing ensures uaccess.h is always included for
a proper expansion and prototype.  Include uaccess.h in cfi.h to clear
up the errors.

Cc: stable@vger.kernel.org
Fixes: 0652a3daa7 ("tracing: Fix CFI violation in probestub being called by tprobes")
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-06-06 15:08:36 -07:00
Cryolitia PukNgae fb402386af Input: atkbd - skip deactivate for HONOR BCC-N's internal keyboard
After commit 9cf6e24c9f ("Input: atkbd -
do not skip atkbd_deactivate() when skipping ATKBD_CMD_GETID"), HONOR
BCC-N, aka HONOR MagicBook 14 2026's internal keyboard stops
working. Adding the atkbd_deactivate_fixup quirk fixes it.

DMI: HONOR BCC-N/BCC-N-PCB, BIOS 1.04 04/07/2026

Fixes: 9cf6e24c9f ("Input: atkbd - do not skip atkbd_deactivate() when skipping ATKBD_CMD_GETID")
Reported-by: Hongfei Ren <lcrhf@outlook.com>
Link: https://github.com/colorcube/Linux-on-Honor-Magicbook-14-Pro/issues/1#issuecomment-4562679891
Tested-by: Hongfei Ren <lcrhf@outlook.com>
Cc: stable@kernel.org
Signed-off-by: Cryolitia PukNgae <cryolitia.pukngae@linux.dev>
Link: https://patch.msgid.link/20260605-honor-v1-1-78e05e491193@linux.dev
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2026-06-06 12:57:41 -07:00
Linus Torvalds 6086121dc4 Merge tag 'sound-7.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
 "It's getting calmer, but we still came up with a handful of small
  fixes, including two core fixes. All look sane and safe.

  Core:
   - Fix wait queue list corruption in snd_pcm_drain() on linked streams
   - Fix UMP event stack overread in seq dummy driver

  USB-audio:
   - Add quirk for AB13X USB Audio
   - Fix the regression with sticky mixer volumes in 7.1-rc

  ASoC:
   - Fix 32-slot TDM breakage on Freescale SAI
   - Varioud DMI quirks for AMD ACP"

* tag 'sound-7.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: seq: dummy: fix UMP event stack overread
  ALSA: usb-audio: Add iface reset and delay quirk for AB13X USB Audio
  ALSA: PCM: Fix wait queue list corruption in snd_pcm_drain() on linked streams
  ASoC: amd: acp70: add standalone RT721 SoundWire machine
  ASoC: amd: yc: Add MSI Raider A18 HX A9WJG to quirk table
  ASoC: fsl_sai: Fix 32 slots TDM broken by integer shift UB in xMR write
  ASoC: amd: yc: Enable internal mic on MSI Bravo 17 C7VF
  ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11
  ALSA: usb-audio: Set the value of potential sticky mixers to maximum
2026-06-06 09:49:16 -07:00
Linus Torvalds d054796f8b Merge tag 'rust-fixes-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust fixes from Miguel Ojeda:
 "Toolchain and infrastructure:

   - Fix 'rustc-option' (the Makefile one) when cross-compiling that
     leads to build or boot failures in certain configs

   - Work around a Rust compiler bug (already fixed for Rust 1.98.0)
     thats lead to boot failures in certain configs due to missing
     'uwtable' LLVM module flags

   - Support a Rust compiler change (starting with Rust 1.98.0) in the
     unstable target specification JSON files

   - Forbid Rust + arm + KASAN configs, which do not build

  'kernel' crate:

   - Fix NOMMU build by adding a missing helper"

* tag 'rust-fixes-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux:
  rust: x86: support Rust >= 1.98.0 target spec
  rust: arm64: set uwtable llvm module flag for CONFIG_UNWIND_TABLES
  rust: helpers: add is_vmalloc_addr wrapper for NOMMU builds
  rust: kasan/kbuild: fix rustc-option when cross-compiling
  ARM: Do not select HAVE_RUST when KASAN is enabled
2026-06-06 09:44:42 -07:00
Linus Torvalds 76351effa5 Merge tag 'vfs-7.1-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner:

 - Fix error handling in ovl_cache_get()

 - Tighten access checks for exited tasks in pidfd_getfd()

 - Fix selftests leak in __wait_for_test()

 - Limit FUSE_NOTIFY_RETRIEVE to uptodate folios

 - Reject fuse_notify() pagecache ops on directories

 - Clear JOBCTL_PENDING_MASK for caller in zap_other_threads()

 - Fix failure to unlock in nfsd4_create_file()

 - Fix pointer arithmetic in qnx6 directory iteration

 - Fix UAF due to unlocked ->mnt_ns read in may_decode_fh()

 - Avoid potential null folio->mapping deref during iomap error
   reporting

* tag 'vfs-7.1-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  iomap: avoid potential null folio->mapping deref during error reporting
  fhandle: fix UAF due to unlocked ->mnt_ns read in may_decode_fh()
  fs/qnx6: fix pointer arithmetic in directory iteration
  VFS: fix possible failure to unlock in nfsd4_create_file()
  signal: clear JOBCTL_PENDING_MASK for caller in zap_other_threads()
  fuse: reject fuse_notify() pagecache ops on directories
  fuse: limit FUSE_NOTIFY_RETRIEVE to uptodate folios
  selftests: harness: fix pidfd leak in __wait_for_test
  pidfd: refuse access to tasks that have started exiting harder
  ovl: keep err zero after successful ovl_cache_get()
2026-06-06 07:28:59 -07:00
Linus Torvalds 8e65320d91 Merge tag 'drm-fixes-2026-06-06' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie:
 "Weekly drm fixes, not contributing to things settling down
  unfortunately. Lots of driver fixes for various bounds checks, leaks
  and UAF type things, i915/xe probably the most sane, amdgpu has a mix
  of fixes all over, then ethosu has lots of small fixes.

  The problem of fixing thing in private has really hit us with the
  change handle ioctl, and "Sima was right" and we should have disabled
  the ioctl, since it was only introduced a couple of kernels ago and
  failed to upstream it's tests in time.

  The patch here fixes the problems Sima identified, but disables the
  ioctl as well, with a list of known problems in it and a request for
  proper tests to be written and upstreamed. It's a niche user ioctl
  designed for CRIU with AMD ROCm, so I think it's fine to just disable
  it.

  Maybe this week will settle down.

  core:
   - disable the gem change handle ioctl for security reasons (plan to
     fix it on list later with proper test coverage)

  dumb-buffer:
   - remove strict limits on buffer geometry

  amdgpu:
   - BT.2020 fix for DCE
   - DC bounds checking fixes
   - SDMA 7.1 fix
   - UserQ fixes
   - SI fix
   - SMU 13 fixes
   - SMU 14 fixes
   - GC 12.1 fix
   - Userptr fix
   - GC 10.1 fix
   - GART fix for non-4K pages

  amdkfd:
   - UAF race fix
   - Fix a potential NULL pointer dereference
   - GC 11 buffer overflow fix for SDMA

  xe:
   - Revert removing support for unpublished NVL-S GuC
   - Suspend fixes related to multi-queue

  i915:
   - Fix color blob reference handling in intel_plane_state
   - Revert "drm/i915/backlight: Remove try_vesa_interface"

  ethosu:
   - reject unsupported NPU_OP_RESIZE
   - fix index of IFM region
   - fix weight index
   - fix overflows in DMA-size calculations
   - reject DMA commands with uninitialized length
   - fix OOB write in ethosu_gem_cmdstream_copy_and_validate

  imx:
   - fix kernel-doc warnings

  ivpu:
   - add overflow checks in firmware handling and get_info_ioctl

  v3d:
   - wait for pending L2T flush before cleaning caches
   - fix leak of vaddr
   - skip CSD when it has zeroed workgroups
   - fix ref counting in performance monitoring"

* tag 'drm-fixes-2026-06-06' of https://gitlab.freedesktop.org/drm/kernel: (50 commits)
  drm/gem: Try to fix change_handle ioctl, attempt 4
  Revert "drm/i915/backlight: Remove try_vesa_interface"
  accel/ethosu: fix OOB write in ethosu_gem_cmdstream_copy_and_validate()
  accel/ethosu: reject DMA commands with uninitialized length
  accel/ethosu: fix arithmetic issues in dma_length()
  accel/ethosu: fix wrong weight index in NPU_SET_SCALE1_LENGTH on U85
  accel/ethosu: reject NPU_OP_RESIZE commands from userspace
  accel/ethosu: fix IFM region index out-of-bounds in command stream parser
  drm/v3d: Fix global performance monitor reference counting
  drm/xe/multi_queue: skip submit when primary queue is suspended
  drm/xe: Clear pending_disable before signaling suspend fence
  Revert "drm/xe: Skip exec queue schedule toggle if queue is idle during suspend"
  drm/amd/pm: smu_v14_0_0: use SoftMin for gfxclk in set_soft_freq_limited_range
  drm/amdgpu: Fix incorrect VRAM GART mappings on non-4K page size systems
  drm/amdgpu/userq: move wptr_obj cleanup in mqd_destroy
  drm/amdgpu: improve the userq seq BO free bit lookup
  drm/amdgpu/userq: remove the vital queue unmap logging
  drm/amdkfd: Fix buffer overflow in SDMA queue checkpoint/restore on GFX11
  drm/amdkfd: fix NULL dereference in get_queue_ids()
  drm/amdgpu: set noretry=1 as default for GFX 10.1.x (Navi10/12/14)
  ...
2026-06-05 18:02:23 -07:00
Simona Vetter 1a4f03d22f drm/gem: Try to fix change_handle ioctl, attempt 4
[airlied: just added some comments on how to reenable]
On-list because the cat is out of the bag and we're clearly not good
enough to figure this out in private. The story thus far:

5e28b7b944 ("drm: Set old handle to NULL before prime swap in
change_handle") tried to fix a race condition between the gem_close and
gem_change_handle ioctls, but got a few things wrong:

- There's a confusion with the local variable handle, which is actually
  the new handle, and so the two-stage trick was actually applied to the
  wrong idr slot. 7164d78559 ("drm/gem: fix race between
  change_handle and handle_delete") tried to fix that by adding yet
  another code block, but forgot to add the error handling. Which meant
  we now have two paths, both kinda wrong.

- dc366607c4 ("drm: Replace old pointer to new idr") tried to apply
  another fix, but inconsistently, again because of the handle confusion
  - this would be the right fix (kinda, somewhat, it's a mess) if we'd
  do the two-stage approach for the new handle. Except that wasn't the
  intent of the original fix.

We also didn't have an igt merged for the original ioctl, which is a big
no-go. This was attempted to address off-list in the original bugfix,
and amd QA people claimed the bug was fixed now. Very clearly that's not
the case. Here's my attempt to sort this out:

- Rename the local variable to new_handle, the old aliasing with
  args->handle is just too dangerously confusing.

- Merge the gem obj lookup with the two-stage idr_replace so that we
  avoid getting ourselves confused there.

- This means we don't have a surplus temporary reference anymore, only
  an inherited from the idr. A concurrent gem_close on the new_handle
  could steal that. Fix that with the same two-stage approach
  create_tail uses. This is a bit overkill as documented in the comment,
  but I also don't trust my ability to understand this all correctly, so
  go with the established pattern we have from other ioctls instead for
  maximum paranoia.

- Adjust error paths. I've tried to make the error and success paths
  common, because they are identical except for which handle is removed
  and on which we call idr_replace to (re)install the object again. But
  that made things messier to read, so I've left it at the more verbose
  version, which unfortunately hides the symmetry in the entire code
  flow a bit.

- While at it, also replace the 7 space indent with 1 tab.

And finally, because I flat out don't trust my abilities here at all
anymore:

- Disable the ioctl until we have the igt situation and everything else
  sorted out on-list and with full consensus.

v2:

Sashiko noticed that I didn't handle the error path for idr_replace
correctly, it must be checked with IS_ERR_OR_NULL like in
gem_handle_delete. So yeah, definitely should just the existing paths
1:1 because this is endless amounts of tricky.

Also add the Fixes: line for the original ioctl, I forgot that too.

Reported-by: DARKNAVY (@DarkNavyOrg) <vr@darknavy.com>
Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch>
Fixes: dc366607c4 ("drm: Replace old pointer to new idr")
Cc: syzbot+d7c9eed171647e421013@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
Cc: Edward Adam Davis <eadavis@qq.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 5e28b7b944 ("drm: Set old handle to NULL before prime swap in change_handle")
Cc: David Francis <David.Francis@amd.com>
Cc: Puttimet Thammasaeng <pwn8official@gmail.com>
Cc: Christian Koenig <Christian.Koenig@amd.com>
Fixes: 7164d78559 ("drm/gem: fix race between change_handle and handle_delete")
Cc: Zhenghang Xiao <kipreyyy@gmail.com>
Fixes: 5e28b7b944 ("drm: Set old handle to NULL before prime swap in change_handle")
Reviewed-by: David Francis <David.Francis@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20260604194437.1725314-1-simona.vetter@ffwll.ch
2026-06-06 08:54:55 +10:00
Dave Airlie 8ff3adc8c3 Merge tag 'drm-intel-fixes-2026-06-05' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-fixes
- Fix color blob reference handling in intel_plane_state (Chaitanya Kumar Borah)
- Revert "drm/i915/backlight: Remove try_vesa_interface" [backlight] (Suraj Kandpal)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tursulin@igalia.com>
Link: https://patch.msgid.link/aiKgmwz7VGOaFXIv@linux
2026-06-06 08:42:15 +10:00
Dave Airlie f80cbe57ec Merge tag 'drm-misc-fixes-2026-06-05' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
Short summary of fixes pull:

dumb-buffer:
- remove strict limits on buffer geometry

ethosu:
- reject unsupported NPU_OP_RESIZE
- fix index of IFM region
- fix weight index
- fix overflows in DMA-size calculations
- reject DMA commands with uninitialized length
- fix OOB write in ethosu_gem_cmdstream_copy_and_validate

imx:
- fix kernel-doc warnings

ivpu:
- add overflow checks in firmware handling and get_info_ioctl

v3d:
- wait for pending L2T flush before cleaning caches
- fix leak of vaddr
- skip CSD when it has zeroed workgroups
- fix ref counting in performance monitoring

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260605072602.GA268798@linux.fritz.box
2026-06-06 08:38:26 +10:00
Linus Torvalds c10130c234 Merge tag 'io_uring-7.1-20260605' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull io_uring fix from Jens Axboe:
 "A single fix for a missing flag mask when multishot is used with
  an incrementally consumed buffer ring, potentially leading to
  application confusion because of lack of IORING_CQE_F_BUF_MORE
  consistency"

* tag 'io_uring-7.1-20260605' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
  io_uring/net: inherit IORING_CQE_F_BUF_MORE across bundle recv retries
2026-06-05 13:52:15 -07:00