summaryrefslogtreecommitdiff
path: root/fs
AgeCommit message (Collapse)AuthorFilesLines
2026-06-08btrfs: check and set EXTENT_DELALLOC_NEW before clearing EXTENT_DELALLOCQu Wenruo4-32/+60
[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-08btrfs: remove unnecessary ctl argument from write_cache_extent_entries()Filipe Manana1-3/+2
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-08btrfs: remove unnecessary ctl argument from __btrfs_write_out_cache()Filipe Manana1-3/+2
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-08btrfs: remove block group argument from copy_free_space_cache()Filipe Manana1-5/+4
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-08btrfs: remove op field from struct btrfs_free_space_ctlFilipe Manana5-33/+31
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-08btrfs: reduce size of struct btrfs_free_space_ctlFilipe Manana1-2/+2
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-08btrfs: remove unit field from struct btrfs_free_space_ctlFilipe Manana2-44/+52
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-08btrfs: remove start field from struct btrfs_free_space_ctlFilipe Manana2-6/+4
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-08btrfs: use a kmem_cache for free space control structuresFilipe Manana1-2/+13
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-08btrfs: reduce size of struct btrfs_block_groupFilipe Manana1-17/+16
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-08btrfs: use a kmem_cache for block groupsFilipe Manana3-3/+26
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-08btrfs: make more ASSERTs verbose, part 3David Sterba10-23/+39
We have support for optional string to be printed in ASSERT() (added in 19468a623a9109 ("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 1c094e6ccead7a ("btrfs: make a few more ASSERTs verbose"). Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08btrfs: convert ioctl handlers to AUTO_KFREEDavid Sterba1-184/+103
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-08btrfs: convert kmalloc_array to kmalloc_objs in btrfs_calc_avail_data_space()David Sterba1-2/+1
There's one use of kmalloc_array() that can be transformed to kmalloc_objs() in the same way as suggested in commit 69050f8d6d075d ("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-08btrfs: do more kmalloc_obj()/kmalloc_objs() conversionsDavid Sterba1-5/+5
Do a few more (trivial) conversions that started in commit 69050f8d6d075d ("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-08btrfs: lift assertions to beginning of insert_delayed_ref()David Sterba1-1/+4
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-08btrfs: replace open coded DEBUG_WARN in extent_writepage()David Sterba1-1/+1
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
2026-06-08btrfs: move condition to WARN_ON in btrfs_set_delalloc_extent()David Sterba1-2/+1
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-08btrfs: remove folio checked subpage bitmap trackingQu Wenruo7-61/+4
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-08btrfs: remove the COW fixup mechanismQu Wenruo6-243/+10
[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 7ca3e84980ef ("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-08btrfs: pass a valid btrfs_tree_parent_check when possibleQu Wenruo3-15/+14
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-06gfs2: use d_splice_alias() for ->lookup() return valueAl Viro1-6/+2
Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-06ntfs: use d_splice_alias() for ->lookup() return valueAl Viro1-2/+1
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-06Merge tag 'vfs-7.1-rc7.fixes' of ↵Linus Torvalds8-20/+60
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-06bpf: add bpf_real_inode() kfuncChristian Brauner1-0/+16
Add a sleepable BPF kfunc that resolves the real inode backing a dentry via d_real_inode(). On overlay/union filesystems the inode attached to the dentry is the overlay inode which does not carry the underlying device information. d_real_inode() resolves through the overlay and returns the inode from the lower, real filesystem. This is used in the RestrictFilesytemAccess bpf program that has been merged into systemd a little while ago. Link: https://github.com/systemd/systemd/pull/41340 [1] Link: https://patch.msgid.link/20260526-work-bpf-verity-v2-1-cd0b1850d31b@kernel.org Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06bpf: Add simple xattr support to bpffsDaniel Borkmann1-0/+33
Add support for extended attributes on bpffs inodes so that user space and BPF LSM programs can attach metadata, for example, a content hash or a security label - to a pinned object or directory. BPF LSM or user space tooling can then uniformly look at this (e.g. security.bpf.*) in similar way to other fs'es. The store is in-memory and non-persistent: it lives only for the lifetime of the mount, like everything else in bpffs. The modelling is similar to tmpfs. bpffs serves the trusted.* and security.* namespaces; user.* is left unsupported. As bpffs is FS_USERNS_MOUNT, security.* is reachable by the unprivileged mounter in a user namespace, and thus we are using the simple_xattr_set_limited infra there (trusted.* needs global CAP_SYS_ADMIN). bpf_fill_super() is open-coded instead of using simple_fill_super(), because the root inode must now be allocated through bpf_fs_alloc_inode() i.e. carry the bpf_fs_inode wrapper and come from the right cache - which requires s_op (and s_xattr) to be installed before the first inode is created. While at it, also harden s_iflags with SB_I_NOEXEC and SB_I_NODEV. bpf_fs_listxattr() is only reachable through the filesystem via i_op->listxattr, so the BPF token inode is left untouched. Name-based fsetxattr()/fgetxattr() on a token fd still work since the get/set handlers are installed at the superblock. For security.* namespace, we use simple_xattr_set_limited() but there was no simple_xattr_add_limited() API yet which was needed in bpf_fs_initxattrs() to avoid underflows in the accounting. The symlink target is freed in bpf_free_inode() rather than in bpf_destroy_inode() so that it is released only after an RCU grace period, as an RCU path walk following the symlink may still dereference inode->i_link in security_inode_follow_link(). Lastly, the bpf_symlink() allocated the symlink target is switched to GFP_KERNEL_ACCOUNT, so the string is charged to the caller's memcg. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://patch.msgid.link/20260602074012.416289-1-daniel@iogearbox.net Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06kernfs: link kn to its parent before the LSM init hookChristian Brauner1-4/+5
After commit 12e9e3cd03b5 ("simpe_xattr: use per-sb cache"), kernfs_xattr_set() and kernfs_xattr_get() compute the cache via kernfs_root(kn) before any other check. kernfs_root(kn) walks kn->__parent first and falls back to kn->dir.root, both of which are NULL on a freshly kmem_cache_zalloc()'d kn. kn->__parent was being set in kernfs_new_node() after __kernfs_new_node() returned, and kn->dir.root is set even later by kernfs_create_dir_ns() / kernfs_create_empty_dir(). The LSM kernfs_init_security hook is invoked from inside __kernfs_new_node(), before either field has been initialized. selinux_kernfs_init_security() ends with kernfs_xattr_set(kn, XATTR_NAME_SELINUX, ...). kernfs_root(kn) then returns NULL, and &((struct kernfs_root *)NULL)->xa_cache evaluates to offsetof(struct kernfs_root, xa_cache) which faults: BUG: kernel NULL pointer dereference, address: 00000000000000e0 RIP: 0010:simple_xattr_set+0x27/0x8b0 Call Trace: kernfs_xattr_set+0x63/0xb0 selinux_kernfs_init_security+0x13b/0x270 security_kernfs_init_security+0x36/0xc0 __kernfs_new_node+0x182/0x290 kernfs_new_node+0x80/0xc0 kernfs_create_dir_ns+0x2b/0xa0 cgroup_create+0x116/0x380 cgroup_mkdir+0x7c/0x1a0 Reproduces deterministically at PID 1 (systemd) on an SELinux-enabled distro. The first cgroup mkdir under /sys/fs/cgroup with a labelled parent panics the kernel. The LSM hook's contract is that the kn_dir argument is the parent of the new kn, so kn->__parent should already point at kn_dir when the hook runs. Move kernfs_get(parent) and rcu_assign_pointer of kn->__parent from kernfs_new_node() into __kernfs_new_node() right before the security hook, and unwind the parent reference on the err_out4 path. kernfs_root(kn) then takes its parent branch during the hook and returns parent->dir.root, which is the correct root. This also closes the same-shape latent bug in kernfs_xattr_get() (which today is hidden only by kernfs_iattrs_noalloc() returning NULL on a fresh kn). Fixes: 12e9e3cd03b5 ("simpe_xattr: use per-sb cache") Reported-by: Calum Mackay <calum.mackay@oracle.com> Closes: https://lore.kernel.org/all/5386153f-9112-4971-98fc-de90d7aae2c6@oracle.com/ Link: https://patch.msgid.link/20260526-ablief-demut-wehen-aef8446ef5c9@brauner Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06simpe_xattr: use per-sb cacheMiklos Szeredi5-158/+158
Move the hash table to the super block to remove excessive overhead in case of small number of xattrs per inode. Add linked list to the inode, used for listxattr and eviction. Listxattr uses rcu protection to iterate the list of xattrs. Before being made per-sb, lazy allocation was protected by inode lock. Now inode lock no longer provides sufficient exclusion, so use cmpxchg() to ensure atomicity. Though I haven't found a description of this pattern, after some research it seems that cmpxchg_release() and READ_ONCE() should provide the necessary memory barriers. Use simple_xattr_free_rcu() in simple_xattrs_free(). This is needed because the hash table is now shared between inodes and lookup on a different inode might be running the compare function on the just freed element within the RCU grace period. Following stats are based on slabinfo diff, after creating 100k empty files, then adding a "user.test=foo" xattr to each: v7.0 (no rhashtable): File creation: 993.40 bytes/file Xattr addition: 79.99 bytes/file v7.1-rc2 (per-inode rhashtable): File creation: 939.73 bytes/file Xattr addition: 1296.08 bytes/file v7.1-rc2 + this patch (per-sb rhashtable) File creation: 946.84 bytes/file Xattr addition: 111.86 bytes/file The overhead of a single xattr is reduced to nearly v7.0 levels. The per xattr overhead is slightly larger due to the addition of three pointers to struct simple_xattr. Fixes: b32c4a213698 ("xattr: add rhashtable-based simple_xattr infrastructure") Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://patch.msgid.link/20260605135322.2632068-5-mszeredi@redhat.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06simple_xattr: change interface to pass struct simple_xattrs **Miklos Szeredi4-69/+50
Change the simple_xattr API to accept pointer-to-pointer (struct simple_xattrs **) instead of pointer. This allows the functions to handle lazy allocation internally without requiring callers to use simple_xattrs_lazy_alloc(). The simple_xattr_set(), simple_xattr_set_limited() and simple_xattr_add() functions now handle allocation when xattrs is NULL. simple_xattrs_free() now also frees the xattrs structure itself and sets the pointer to NULL. This simplifies callers and removes the need for most callers to explicitly manage xattrs allocation and lifetime. In shmem_initxattrs(), the total required space for all initial xattrs (ispace) is pre-calculated and deducted from sbinfo->free_ispace. Since this patch modifies the function to add new xattrs directly to the inode's &info->xattrs list rather than using a local temporary variable, a failure means that the partially populated info->xattrs list remains attached to the inode. When the VFS caller handles the -ENOMEM error, it drops the newly created inode via iput(), shmem_free_inode() adds freed to sbinfo->free_ispace a second time, permanently inflating the tmpfs free space quota. Fix by substracting already added xattrs from ispace. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://patch.msgid.link/20260605135322.2632068-4-mszeredi@redhat.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06kernfs: fix xattr race condition with multiple superblocksMiklos Szeredi4-11/+36
Multiple superblocks with different namespaces can share the same kernfs_node when kernfs_test_super() finds a matching root but different namespace. This means multiple inodes from different superblocks can reference the same kernfs_node->iattr->xattrs structure. The VFS layer only holds per-inode locks during xattr operations, which is insufficient to serialize concurrent xattr modifications on the shared kernfs_node. This can lead to race conditions in simple_xattr_set() where the lookup->replace/remove sequence is not atomic with respect to operations from other superblocks. Fix this by protecting xattr operations with the existing hashed kernfs_locks->open_file_mutex[] array, which is already used to protect per-node open file data. The hashed mutex array provides scalable per-node serialization (scaled by CPU count, up to 1024 locks on 32+ CPU systems) with zero memory overhead. Changes: - Rename open_file_mutex[] to node_mutex[] to reflect dual purpose - Add kernfs_node_lock_ptr() and kernfs_node_lock() helpers - Protect simple_xattr_set() calls in kernfs_xattr_set() and kernfs_vfs_user_xattr_set() with the hashed mutex - Update file.c to use new helpers via compatibility wrappers - Update documentation to explain the extended lock usage Fixes: b32c4a213698 ("xattr: add rhashtable-based simple_xattr infrastructure") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260601162454.2116375-1-mszeredi%40redhat.com Assisted-by: Claude:claude-sonnet-4-5 Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://patch.msgid.link/20260605135322.2632068-2-mszeredi@redhat.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-05Merge tag 'nfs-for-7.1-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfsLinus Torvalds1-1/+1
Pull NFS client fix from Trond Myklebust: - Fix a use after free in nfs_write_completion * tag 'nfs-for-7.1-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFS: write_completion: dereference loop-local req, not hdr->req
2026-06-05Merge tag 'xfs-fixes-7.1-rc7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linuxLinus Torvalds6-43/+50
Pull xfs fixes from Carlos Maiolino: "A collection of fixes mostly for the RT device, including a small refactor that has no functional change" * tag 'xfs-fixes-7.1-rc7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: Remove mention of PageWriteback xfs: abort mount if xfs_fs_reserve_ag_blocks fails xfs: factor rtgroup geom write pointer reporting into a helper xfs: drop the RTG reference later in xfs_ioc_rtgroup_geometry xfs: fix rtgroup cleanup in CoW fork repair xfs: fix error returns in CoW fork repair xfs: fix overlapping extents returned for pNFS LAYOUTGET xfs: fix use of uninitialized imap in xfs_fs_map_blocks error path xfs: handle racing deletions in xfs_zone_gc_iter_irec
2026-06-05Merge tag 'erofs-for-7.1-rc7-fixes' of ↵Linus Torvalds2-4/+4
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs Pull erofs fixes from Gao Xiang: - Fix a UAF of sbi->sync_decompress when compressed I/Os race with unmount - Fix a regression introduced this development cycle that incorrectly rejects multiple-algorithm images * tag 'erofs-for-7.1-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: fix EFSCORRUPTED on multi-algorithm images in z_erofs_map_sanity_check() erofs: fix use-after-free on sbi->sync_decompress
2026-06-06ntfs: validate resident volume name values on lookupDaeMyung Kang1-1/+13
The shared lookup-time attribute validator now has a safe caller path for $VOLUME_NAME corruption: ntfs_write_volume_label() no longer treats lookup errors as an absent label, and the mount path reinitializes its search context before continuing to $VOLUME_INFORMATION. Add $VOLUME_NAME-specific resident value validation. A volume name is stored as a UTF-16LE string, so reject odd byte lengths, and reject values longer than the NTFS volume label limit. Empty labels remain valid. Also reject non-resident $VOLUME_NAME records. $VOLUME_NAME is required to be resident, like $FILE_NAME; a crafted non-resident record would otherwise pass lookup and ntfs_write_volume_label() would remove it as if it were a normal resident attribute. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: DaeMyung Kang <charsyam@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: reinit search context before volume information lookupDaeMyung Kang1-0/+1
On mount the volume inode is searched for $VOLUME_NAME and then, reusing the same search context, for $VOLUME_INFORMATION. The $VOLUME_NAME lookup is optional and its result is otherwise ignored. Once lookup-time validation can reject a corrupt $VOLUME_NAME with -EIO, the search context is left in an undefined state: ntfs_attr_find() documents that on an actual error @ctx->attr is undefined. Continuing the $VOLUME_INFORMATION search from that context is not contractually valid. Reinitialize the search context before the $VOLUME_INFORMATION lookup so it always starts from a well-defined state regardless of the $VOLUME_NAME lookup outcome. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: DaeMyung Kang <charsyam@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: do not replace volume name after lookup errorsDaeMyung Kang1-3/+8
ntfs_write_volume_label() removes an existing $VOLUME_NAME attribute and then adds the replacement. The old code only distinguished lookup success from all other results, so any lookup error was treated like an absent label and the add path still ran. That is unsafe once lookup-time validation rejects corrupt $VOLUME_NAME records with -EIO: the corrupt record would remain in place and a second $VOLUME_NAME record could be appended next to it. Only add the replacement after the old label was removed successfully or after lookup returned -ENOENT. Propagate all other lookup errors, and also stop if removing the old attribute fails. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: DaeMyung Kang <charsyam@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: validate attribute values on lookupDaeMyung Kang2-64/+107
ntfs_attr_find() and ntfs_external_attr_find() check that generic resident attribute values fit in their attribute records and that fixed-size resident values are large enough. For variable-length resident formats, however, the fixed part is not enough: embedded length fields can still point callers past the resident value. A crafted image can set a small resident $FILE_NAME value_length while leaving file_name_length large. Callers then trust file_name_length and read past the resident value when converting or comparing the name. This was reproduced with a crafted image under KASAN as a slab-out-of-bounds read from the kmalloc-1k MFT record copy. The stack included ntfs_lookup(), ntfs_iget(), ntfs_read_locked_inode(), ntfs_attr_name_get(), ntfs_ucstonls(), and utf16s_to_utf8s(). Add a shared attribute value validator and use it before a lookup path can return an attribute, including the AT_UNUSED enumeration case where callers inspect returned attributes directly. The helper validates resident value bounds, minimum resident value sizes, variable-length $FILE_NAME fields, and non-resident mapping-pairs metadata that was previously checked separately in both lookup paths. This also preserves the intended resident @val matching semantics in the external attribute lookup path. The old duplicated validation block overwrote the actual resident value length with the type-specific minimum length before comparing @val, so variable-length resident values could fail to match even when the bytes were identical. Keep the comparison on the actual value length, and make ntfs_attrlist_entry_add() compare resident attributes with lowest_vcn zero instead of reading the non-resident union member after a successful resident match. Reject non-resident $FILE_NAME records too: the format requires $FILE_NAME to be resident and callers treat returned records as resident. Cc: stable@vger.kernel.org # v7.1 Fixes: 6ceb4cc81ef3 ("ntfs: add bound checking to ntfs_attr_find") Signed-off-by: DaeMyung Kang <charsyam@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: detect mapping-pairs LCN accumulator overflowSamuel Moelius1-1/+5
The NTFS mapping-pairs parser accumulates relative LCN deltas in a signed integer. A corrupted attribute can drive that addition past the representable range. One corrupt runlist shape sets the accumulated LCN to S64_MAX and then adds a delta of 1 in the next mapping-pairs entry. Signed overflow is undefined and can turn an invalid runlist into a different set of physical clusters. Check the LCN addition for overflow before storing the next run. Cc: stable@vger.kernel.org # v7.1 Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: Add WQ_PERCPU to alloc_workqueue usersMarco Crivellari1-1/+1
This continues the effort to refactor workqueue APIs, which began with the introduction of new workqueues and a new alloc_workqueue flag in: commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq") commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag") The refactoring is going to alter the default behavior of alloc_workqueue() to be unbound by default. With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND), any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND must now use WQ_PERCPU. For more details see the Link tag below. In order to keep alloc_workqueue() behavior identical, explicitly request WQ_PERCPU. Cc: stable@vger.kernel.org # v7.1 Link: https://lore.kernel.org/all/20250221112003.1dSuoGyc@linutronix.de/ Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: serialize volume label accessesHyunchul Lee3-10/+28
Protect vol->volume_label with a mutex and snaphost the label before copy_to_user. This prevent a use-after-free when FS_IOC_SETFSLABEL replaces the vol->volume_label and FS_IOC_GETTSLABEL reads it concurrently. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: fix off-by-one in mapping pairs decoding bounds checksRon de Bruijn1-3/+3
In ntfs_mapping_pairs_decompress(), attr_end points one byte past the end of the attribute record: attr_end = (u8 *)attr + le32_to_cpu(attr->length); The two bounds checks validating that mapping pair data bytes fit within the attribute use strict greater-than (>), which allows a one-byte out-of-bounds read when the data extends exactly to attr_end: b = *buf & 0xf; if (b) { if (unlikely(buf + b > attr_end)) // off-by-one goto io_error; for (deltaxcn = (s8)buf[b--]; b; b--) deltaxcn = (deltaxcn << 8) + buf[b]; } When buf + b == attr_end, the check evaluates to false and buf[b] reads one byte past the valid attribute boundary. The same pattern appears in the LCN delta bytes check. Fix both checks to use >= so that buf[b] at exactly attr_end is correctly rejected as out of bounds. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: Ron de Bruijn <rmbruijn@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: not change 0-byte $DATA attribute to non-residentHyunchul Lee1-2/+5
When ntfs_resident_attr_resize() cannot grow a resident attribute in place, it retries after converting other resident attributes to non-resident to free space in the MFT recrord. Do not select zero-length resident $DATA attributes for this conversion. fsck treats 0-byte non-resident $DATA attribute as corruptions. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: Fix spelling mistake "etnry" -> "entry"Colin Ian King1-1/+1
There is a spelling mistake in a ntfs_error message. Fix it. Signed-off-by: Colin Ian King <colin.i.king@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: free link name from ntfs_name_cacheDaeMyung Kang1-3/+2
ntfs_link() converts the new link name with ntfs_nlstoucs() using NTFS_MAX_NAME_LEN. In this case ntfs_nlstoucs() allocates the result from ntfs_name_cache, and its contract requires callers to release the buffer with kmem_cache_free(ntfs_name_cache, ...). All other ntfs_nlstoucs() callers in namei.c do that, but ntfs_link() uses kfree(), which mismatches the allocator for successfully converted names. The conversion failure path reaches the common out label with uname == NULL. That was harmless for kfree(), but kmem_cache_free() does not provide the same NULL contract. Return directly on conversion failure and free successful conversions with ntfs_name_cache. Fixes: af0db57d4293 ("ntfs: update inode operations") Signed-off-by: DaeMyung Kang <charsyam@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: remove unnecessary NULL checks before kfreeNamjae Jeon2-5/+3
NULL check before kfree() is unnecessary and triggers coccinelle warnings. Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: remove unnecessary ternary boolean conversionNamjae Jeon1-6/+6
Coccinelle warned about unnecessary patterns when assigning to bool variables. Simply assign the condition directly. Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: remove unsupported quota handlingDaeMyung Kang5-226/+2
The ntfs driver does not implement quota accounting. It creates new inodes with the NTFS 1.2 $STANDARD_INFORMATION layout and does not maintain the NTFS 3.x owner_id/quota_charged fields or the $Quota usage records that Windows would need for meaningful quota accounting. The only runtime quota path left in the driver is the remount-rw code that tries to mark $Quota/$Q out of date, plus the mount-time code that loads $Quota and its $Q index solely to support that marker. Since the driver does not maintain the per-file quota metadata, setting QUOTA_FLAG_OUT_OF_DATE does not make the quota state meaningful, and failures in this unsupported path can unnecessarily block remount-rw or force a mount read-only. Remove the quota marker, the $Quota/$Q loading state, and the unused quota volume flag. Keep the on-disk quota layout definitions in layout.h so the documented NTFS structures remain available. Suggested-by: Hyunchul Lee <hyc.lee@gmail.com> Link: https://lore.kernel.org/all/CANFS6bYTzioqZjYt=51Kb9RdR3MKXaez_fh_WCLoym093VxFmg@mail.gmail.com/ Signed-off-by: DaeMyung Kang <charsyam@gmail.com> Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: use str_plural in ntfs_attr_make_non_residentThorsten Blum1-1/+2
Replace the manual ternary "s" pluralization with str_plural() to simplify the code. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: add bounds check before accessing EA entriesHyunchul Lee1-8/+8
in ntfs_ea_lookup and ntfs_listxattr, this verifies that there is enough space in the EA entry before accessing the next_entry_offset field of the EA entry. Cc: stable@vger.kernel.org # v7.1 Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-06-06ntfs: validate index entries on readingHyunchul Lee4-68/+60
Validate index entries immediately after reading an index root or index block from disk. This eliminates repeated checks in lookup and readdir, and reduce the risk of missing checks in those paths. Cc: stable@vger.kernel.org # v7.1 Tested-by: woot000 <woot000@woot000.com> Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>