--- /dev/null
+From stable+bounces-247797-greg=kroah.com@vger.kernel.org Fri May 15 16:50:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 10:48:20 -0400
+Subject: btrfs: fix double free in create_space_info_sub_group() error path
+To: stable@vger.kernel.org
+Cc: Guangshuo Li <lgs201920130244@gmail.com>, Qu Wenruo <wqu@suse.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515144820.3248893-2-sashal@kernel.org>
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+[ Upstream commit a7449edf96143f192606ec8647e3167e1ecbd728 ]
+
+When kobject_init_and_add() fails, the call chain is:
+
+create_space_info_sub_group()
+-> btrfs_sysfs_add_space_info_type()
+-> kobject_init_and_add()
+-> failure
+-> kobject_put(&sub_group->kobj)
+-> space_info_release()
+-> kfree(sub_group)
+
+Then control returns to create_space_info_sub_group(), where:
+
+btrfs_sysfs_add_space_info_type() returns error
+-> kfree(sub_group)
+
+Thus, sub_group is freed twice.
+
+Keep parent->sub_group[index] = NULL for the failure path, but after
+btrfs_sysfs_add_space_info_type() has called kobject_put(), let the
+kobject release callback handle the cleanup.
+
+Fixes: f92ee31e031c ("btrfs: introduce btrfs_space_info sub-group")
+CC: stable@vger.kernel.org # 6.18+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/space-info.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/fs/btrfs/space-info.c
++++ b/fs/btrfs/space-info.c
+@@ -263,10 +263,8 @@ static int create_space_info_sub_group(s
+ sub_group->subgroup_id = id;
+
+ ret = btrfs_sysfs_add_space_info_type(sub_group);
+- if (ret) {
+- kfree(sub_group);
++ if (ret)
+ parent->sub_group[index] = NULL;
+- }
+ return ret;
+ }
+
--- /dev/null
+From stable+bounces-249090-greg=kroah.com@vger.kernel.org Sun May 17 15:52:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 09:52:04 -0400
+Subject: btrfs: fix missing last_unlink_trans update when removing a directory
+To: stable@vger.kernel.org
+Cc: Filipe Manana <fdmanana@suse.com>, Slava0135 <slava.kovalevskiy.2014@gmail.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260517135204.148250-3-sashal@kernel.org>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 999757231c49376cd1a37308d2c8c4c9932571e1 ]
+
+When removing a directory we are not updating its last_unlink_trans field,
+which can result in incorrect fsync behaviour in case some one fsyncs the
+directory after it was removed because it's holding a file descriptor on
+it.
+
+Example scenario:
+
+ mkdir /mnt/dir1
+ mkdir /mnt/dir1/dir2
+ mkdir /mnt/dir3
+
+ sync -f /mnt
+
+ # Do some change to the directory and fsync it.
+ chmod 700 /mnt/dir1
+ xfs_io -c fsync /mnt/dir1
+
+ # Move dir2 out of dir1 so that dir1 becomes empty.
+ mv /mnt/dir1/dir2 /mnt/dir3/
+
+ open fd on /mnt/dir1
+ call rmdir(2) on path "/mnt/dir1"
+ fsync fd
+
+ <trigger power failure>
+
+When attempting to mount the filesystem, the log replay will fail with
+an -EIO error and dmesg/syslog has the following:
+
+ [445771.626482] BTRFS info (device dm-0): first mount of filesystem 0368bbea-6c5e-44b5-b409-09abe496e650
+ [445771.626486] BTRFS info (device dm-0): using crc32c checksum algorithm
+ [445771.627912] BTRFS info (device dm-0): start tree-log replay
+ [445771.628335] page: refcount:2 mapcount:0 mapping:0000000061443ddc index:0x1d00 pfn:0x7072a5
+ [445771.629453] memcg:ffff89f400351b00
+ [445771.629892] aops:btree_aops [btrfs] ino:1
+ [445771.630737] flags: 0x17fffc00000402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1ffff)
+ [445771.632359] raw: 017fffc00000402a fffff47284d950c8 fffff472907b7c08 ffff89f458e412b8
+ [445771.633713] raw: 0000000000001d00 ffff89f6c51d1a90 00000002ffffffff ffff89f400351b00
+ [445771.635029] page dumped because: eb page dump
+ [445771.635825] BTRFS critical (device dm-0): corrupt leaf: root=5 block=30408704 slot=10 ino=258, invalid nlink: has 2 expect no more than 1 for dir
+ [445771.638088] BTRFS info (device dm-0): leaf 30408704 gen 10 total ptrs 17 free space 14878 owner 5
+ [445771.638091] BTRFS info (device dm-0): refs 4 lock_owner 0 current 3581087
+ [445771.638094] item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
+ [445771.638097] inode generation 3 transid 9 size 16 nbytes 16384
+ [445771.638098] block group 0 mode 40755 links 1 uid 0 gid 0
+ [445771.638100] rdev 0 sequence 2 flags 0x0
+ [445771.638102] atime 1775744884.0
+ [445771.660056] ctime 1775744885.645502983
+ [445771.660058] mtime 1775744885.645502983
+ [445771.660060] otime 1775744884.0
+ [445771.660062] item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
+ [445771.660064] index 0 name_len 2
+ [445771.660066] item 2 key (256 DIR_ITEM 1843588421) itemoff 16077 itemsize 34
+ [445771.660068] location key (259 1 0) type 2
+ [445771.660070] transid 9 data_len 0 name_len 4
+ [445771.660075] item 3 key (256 DIR_ITEM 2363071922) itemoff 16043 itemsize 34
+ [445771.660076] location key (257 1 0) type 2
+ [445771.660077] transid 9 data_len 0 name_len 4
+ [445771.660078] item 4 key (256 DIR_INDEX 2) itemoff 16009 itemsize 34
+ [445771.660079] location key (257 1 0) type 2
+ [445771.660080] transid 9 data_len 0 name_len 4
+ [445771.660081] item 5 key (256 DIR_INDEX 3) itemoff 15975 itemsize 34
+ [445771.660082] location key (259 1 0) type 2
+ [445771.660083] transid 9 data_len 0 name_len 4
+ [445771.660084] item 6 key (257 INODE_ITEM 0) itemoff 15815 itemsize 160
+ [445771.660086] inode generation 9 transid 9 size 8 nbytes 0
+ [445771.660087] block group 0 mode 40777 links 1 uid 0 gid 0
+ [445771.660088] rdev 0 sequence 2 flags 0x0
+ [445771.660089] atime 1775744885.641174097
+ [445771.660090] ctime 1775744885.645502983
+ [445771.660091] mtime 1775744885.645502983
+ [445771.660105] otime 1775744885.641174097
+ [445771.660106] item 7 key (257 INODE_REF 256) itemoff 15801 itemsize 14
+ [445771.660107] index 2 name_len 4
+ [445771.660108] item 8 key (257 DIR_ITEM 2676584006) itemoff 15767 itemsize 34
+ [445771.660109] location key (258 1 0) type 2
+ [445771.660110] transid 9 data_len 0 name_len 4
+ [445771.660111] item 9 key (257 DIR_INDEX 2) itemoff 15733 itemsize 34
+ [445771.660112] location key (258 1 0) type 2
+ [445771.660113] transid 9 data_len 0 name_len 4
+ [445771.660114] item 10 key (258 INODE_ITEM 0) itemoff 15573 itemsize 160
+ [445771.660115] inode generation 9 transid 10 size 0 nbytes 0
+ [445771.660116] block group 0 mode 40755 links 2 uid 0 gid 0
+ [445771.660117] rdev 0 sequence 0 flags 0x0
+ [445771.660118] atime 1775744885.645502983
+ [445771.660119] ctime 1775744885.645502983
+ [445771.660120] mtime 1775744885.645502983
+ [445771.660121] otime 1775744885.645502983
+ [445771.660122] item 11 key (258 INODE_REF 257) itemoff 15559 itemsize 14
+ [445771.660123] index 2 name_len 4
+ [445771.660124] item 12 key (258 INODE_REF 259) itemoff 15545 itemsize 14
+ [445771.660125] index 2 name_len 4
+ [445771.660126] item 13 key (259 INODE_ITEM 0) itemoff 15385 itemsize 160
+ [445771.660127] inode generation 9 transid 10 size 8 nbytes 0
+ [445771.660128] block group 0 mode 40755 links 1 uid 0 gid 0
+ [445771.660129] rdev 0 sequence 1 flags 0x0
+ [445771.660130] atime 1775744885.645502983
+ [445771.660130] ctime 1775744885.645502983
+ [445771.660131] mtime 1775744885.645502983
+ [445771.660132] otime 1775744885.645502983
+ [445771.660133] item 14 key (259 INODE_REF 256) itemoff 15371 itemsize 14
+ [445771.660134] index 3 name_len 4
+ [445771.660135] item 15 key (259 DIR_ITEM 2676584006) itemoff 15337 itemsize 34
+ [445771.660136] location key (258 1 0) type 2
+ [445771.660137] transid 10 data_len 0 name_len 4
+ [445771.660138] item 16 key (259 DIR_INDEX 2) itemoff 15303 itemsize 34
+ [445771.660139] location key (258 1 0) type 2
+ [445771.660140] transid 10 data_len 0 name_len 4
+ [445771.660144] BTRFS error (device dm-0): block=30408704 write time tree block corruption detected
+ [445771.661650] ------------[ cut here ]------------
+ [445771.662358] WARNING: fs/btrfs/disk-io.c:326 at btree_csum_one_bio+0x217/0x230 [btrfs], CPU#8: mount/3581087
+ [445771.663588] Modules linked in: btrfs f2fs xfs (...)
+ [445771.671229] CPU: 8 UID: 0 PID: 3581087 Comm: mount Tainted: G W 7.0.0-rc6-btrfs-next-230+ #2 PREEMPT(full)
+ [445771.672575] Tainted: [W]=WARN
+ [445771.672987] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
+ [445771.674460] RIP: 0010:btree_csum_one_bio+0x217/0x230 [btrfs]
+ [445771.675222] Code: 89 44 24 (...)
+ [445771.677364] RSP: 0018:ffffd23882247660 EFLAGS: 00010246
+ [445771.678029] RAX: 0000000000000000 RBX: ffff89f6c51d1a90 RCX: 0000000000000000
+ [445771.678975] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff89f406020000
+ [445771.679983] RBP: ffff89f821204000 R08: 0000000000000000 R09: 00000000ffefffff
+ [445771.680905] R10: ffffd23882247448 R11: 0000000000000003 R12: ffffd23882247668
+ [445771.681978] R13: ffff89f458e40fc0 R14: ffff89f737f4f500 R15: ffff89f737f4f500
+ [445771.682912] FS: 00007f0447a98840(0000) GS:ffff89fb9771d000(0000) knlGS:0000000000000000
+ [445771.684393] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ [445771.685230] CR2: 00007f0447bf1330 CR3: 000000017cb02002 CR4: 0000000000370ef0
+ [445771.686273] Call Trace:
+ [445771.686646] <TASK>
+ [445771.686969] btrfs_submit_bbio+0x83f/0x860 [btrfs]
+ [445771.687750] ? write_one_eb+0x28f/0x340 [btrfs]
+ [445771.688428] btree_writepages+0x2e3/0x550 [btrfs]
+ [445771.689180] ? kmem_cache_alloc_noprof+0x12a/0x490
+ [445771.689963] ? alloc_extent_state+0x19/0x120 [btrfs]
+ [445771.690801] ? kmem_cache_free+0x135/0x380
+ [445771.691328] ? preempt_count_add+0x69/0xa0
+ [445771.691831] ? set_extent_bit+0x252/0x8e0 [btrfs]
+ [445771.692468] ? xas_load+0x9/0xc0
+ [445771.692873] ? xas_find+0x14d/0x1a0
+ [445771.693304] do_writepages+0xc6/0x160
+ [445771.693756] filemap_writeback+0xb8/0xe0
+ [445771.694274] btrfs_write_marked_extents+0x61/0x170 [btrfs]
+ [445771.694999] btrfs_write_and_wait_transaction+0x4e/0xc0 [btrfs]
+ [445771.695818] btrfs_commit_transaction+0x5c8/0xd10 [btrfs]
+ [445771.696530] ? kmem_cache_free+0x135/0x380
+ [445771.697120] ? release_extent_buffer+0x34/0x160 [btrfs]
+ [445771.697786] btrfs_recover_log_trees+0x7be/0x7e0 [btrfs]
+ [445771.698525] ? __pfx_replay_one_buffer+0x10/0x10 [btrfs]
+ [445771.699206] open_ctree+0x11e5/0x1810 [btrfs]
+ [445771.699776] btrfs_get_tree.cold+0xb/0x162 [btrfs]
+ [445771.700463] ? fscontext_read+0x165/0x180
+ [445771.701146] ? rw_verify_area+0x50/0x180
+ [445771.701866] vfs_get_tree+0x25/0xd0
+ [445771.702491] vfs_cmd_create+0x59/0xe0
+ [445771.703125] __do_sys_fsconfig+0x303/0x610
+ [445771.703603] do_syscall_64+0xe9/0xf20
+ [445771.703974] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+ [445771.704700] RIP: 0033:0x7f0447cbd4aa
+ [445771.705108] Code: 73 01 c3 (...)
+ [445771.707263] RSP: 002b:00007ffc4e528318 EFLAGS: 00000246 ORIG_RAX: 00000000000001af
+ [445771.708107] RAX: ffffffffffffffda RBX: 00005561585d8c20 RCX: 00007f0447cbd4aa
+ [445771.708931] RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003
+ [445771.709744] RBP: 00005561585d9120 R08: 0000000000000000 R09: 0000000000000000
+ [445771.710674] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ [445771.711477] R13: 00007f0447e4f580 R14: 00007f0447e5126c R15: 00007f0447e36a23
+ [445771.712277] </TASK>
+ [445771.712541] ---[ end trace 0000000000000000 ]---
+ [445771.713382] BTRFS error (device dm-0): error while writing out transaction: -5
+ [445771.714679] BTRFS warning (device dm-0): Skipping commit of aborted transaction.
+ [445771.715562] BTRFS error (device dm-0 state A): Transaction aborted (error -5)
+ [445771.716459] BTRFS: error (device dm-0 state A) in cleanup_transaction:2068: errno=-5 IO failure
+ [445771.717936] BTRFS error (device dm-0 state EA): failed to recover log trees with error: -5
+ [445771.719681] BTRFS error (device dm-0 state EA): open_ctree failed: -5
+
+The problem is that such a fsync should have result in a fallback to a
+transaction commit, but that did not happen because through the
+btrfs_rmdir() we never update the directory's last_unlink_trans field.
+Any inode that had a link removed must have its last_unlink_trans updated
+to the ID of transaction used for the operation, otherwise fsync and log
+replay will not work correctly.
+
+btrfs_rmdir() calls btrfs_unlink_inode() and through that call chain we
+never call btrfs_record_unlink_dir() in order to update last_unlink_trans.
+However btrfs_unlink(), which is used for unlinking regular files, calls
+btrfs_record_unlink_dir() and then calls btrfs_unlink_inode(). So fix
+this by moving the call to btrfs_record_unlink_dir() from btrfs_unlink()
+to btrfs_unlink_inode().
+
+A test case for fstests will follow soon.
+
+Reported-by: Slava0135 <slava.kovalevskiy.2014@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/CAAJYhww5ov62Hm+n+tmhcL-e_4cBobg+OWogKjOJxVUXivC=MQ@mail.gmail.com/
+CC: stable@vger.kernel.org
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4681,6 +4681,8 @@ static int btrfs_rmdir(struct inode *vfs
+ if (ret)
+ goto out;
+
++ btrfs_record_unlink_dir(trans, dir, inode, false);
++
+ /* now the directory is empty */
+ ret = btrfs_unlink_inode(trans, dir, inode, &fname.disk_name);
+ if (!ret)
--- /dev/null
+From stable+bounces-247796-greg=kroah.com@vger.kernel.org Fri May 15 16:50:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 10:48:19 -0400
+Subject: btrfs: remove fs_info argument from btrfs_sysfs_add_space_info_type()
+To: stable@vger.kernel.org
+Cc: Filipe Manana <fdmanana@suse.com>, Johannes Thumshirn <johannes.thumshirn@wdc.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515144820.3248893-1-sashal@kernel.org>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 771af6ff72e0ed0eb8bf97e5ae4fa5094e0c5d1d ]
+
+We don't need it since we can grab fs_info from the given space_info.
+So remove the fs_info argument.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: a7449edf9614 ("btrfs: fix double free in create_space_info_sub_group() error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/space-info.c | 4 ++--
+ fs/btrfs/sysfs.c | 5 ++---
+ fs/btrfs/sysfs.h | 3 +--
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+--- a/fs/btrfs/space-info.c
++++ b/fs/btrfs/space-info.c
+@@ -262,7 +262,7 @@ static int create_space_info_sub_group(s
+ sub_group->parent = parent;
+ sub_group->subgroup_id = id;
+
+- ret = btrfs_sysfs_add_space_info_type(fs_info, sub_group);
++ ret = btrfs_sysfs_add_space_info_type(sub_group);
+ if (ret) {
+ kfree(sub_group);
+ parent->sub_group[index] = NULL;
+@@ -291,7 +291,7 @@ static int create_space_info(struct btrf
+ goto out_free;
+ }
+
+- ret = btrfs_sysfs_add_space_info_type(info, space_info);
++ ret = btrfs_sysfs_add_space_info_type(space_info);
+ if (ret)
+ return ret;
+
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -1674,13 +1674,12 @@ static const char *alloc_name(struct btr
+ * Create a sysfs entry for a space info type at path
+ * /sys/fs/btrfs/UUID/allocation/TYPE
+ */
+-int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
+- struct btrfs_space_info *space_info)
++int btrfs_sysfs_add_space_info_type(struct btrfs_space_info *space_info)
+ {
+ int ret;
+
+ ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype,
+- fs_info->space_info_kobj, "%s",
++ space_info->fs_info->space_info_kobj, "%s",
+ alloc_name(space_info));
+ if (ret) {
+ kobject_put(&space_info->kobj);
+--- a/fs/btrfs/sysfs.h
++++ b/fs/btrfs/sysfs.h
+@@ -27,8 +27,7 @@ void __cold btrfs_exit_sysfs(void);
+ int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info);
+ void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
+ void btrfs_sysfs_add_block_group_type(struct btrfs_block_group *cache);
+-int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
+- struct btrfs_space_info *space_info);
++int btrfs_sysfs_add_space_info_type(struct btrfs_space_info *space_info);
+ void btrfs_sysfs_remove_space_info(struct btrfs_space_info *space_info);
+ void btrfs_sysfs_update_devid(struct btrfs_device *device);
+
--- /dev/null
+From stable+bounces-249089-greg=kroah.com@vger.kernel.org Sun May 17 15:52:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 09:52:03 -0400
+Subject: btrfs: use btrfs inodes in btrfs_rmdir() to avoid so much usage of BTRFS_I()
+To: stable@vger.kernel.org
+Cc: Filipe Manana <fdmanana@suse.com>, Johannes Thumshirn <johannes.thumshirn@wdc.com>, Qu Wenruo <wqu@suse.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260517135204.148250-2-sashal@kernel.org>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 98060e1611177ddc842601a58258876ab435fdbf ]
+
+Almost everywhere we want to use a btrfs inode and therefore we have a
+lot of calls to BTRFS_I(), making the code more verbose. Instead use btrfs
+inode local variables to avoid so much use of BTRFS_I().
+
+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>
+Stable-dep-of: 999757231c49 ("btrfs: fix missing last_unlink_trans update when removing a directory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c | 31 ++++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4623,32 +4623,33 @@ out_up_write:
+ return ret;
+ }
+
+-static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
++static int btrfs_rmdir(struct inode *vfs_dir, struct dentry *dentry)
+ {
+- struct inode *inode = d_inode(dentry);
+- struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
++ struct btrfs_inode *dir = BTRFS_I(vfs_dir);
++ struct btrfs_inode *inode = BTRFS_I(d_inode(dentry));
++ struct btrfs_fs_info *fs_info = inode->root->fs_info;
+ int ret = 0;
+ struct btrfs_trans_handle *trans;
+ struct fscrypt_name fname;
+
+- if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
++ if (inode->vfs_inode.i_size > BTRFS_EMPTY_DIR_SIZE)
+ return -ENOTEMPTY;
+- if (btrfs_ino(BTRFS_I(inode)) == BTRFS_FIRST_FREE_OBJECTID) {
++ if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) {
+ if (unlikely(btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))) {
+ btrfs_err(fs_info,
+ "extent tree v2 doesn't support snapshot deletion yet");
+ return -EOPNOTSUPP;
+ }
+- return btrfs_delete_subvolume(BTRFS_I(dir), dentry);
++ return btrfs_delete_subvolume(dir, dentry);
+ }
+
+- ret = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname);
++ ret = fscrypt_setup_filename(vfs_dir, &dentry->d_name, 1, &fname);
+ if (ret)
+ return ret;
+
+ /* This needs to handle no-key deletions later on */
+
+- trans = __unlink_start_trans(BTRFS_I(dir));
++ trans = __unlink_start_trans(dir);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ goto out_notrans;
+@@ -4668,22 +4669,22 @@ static int btrfs_rmdir(struct inode *dir
+ * This is because we can't unlink other roots when replaying the dir
+ * deletes for directory foo.
+ */
+- if (BTRFS_I(inode)->last_unlink_trans >= trans->transid)
+- btrfs_record_snapshot_destroy(trans, BTRFS_I(dir));
++ if (inode->last_unlink_trans >= trans->transid)
++ btrfs_record_snapshot_destroy(trans, dir);
+
+- if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
+- ret = btrfs_unlink_subvol(trans, BTRFS_I(dir), dentry);
++ if (unlikely(btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
++ ret = btrfs_unlink_subvol(trans, dir, dentry);
+ goto out;
+ }
+
+- ret = btrfs_orphan_add(trans, BTRFS_I(inode));
++ ret = btrfs_orphan_add(trans, inode);
+ if (ret)
+ goto out;
+
+ /* now the directory is empty */
+- ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(inode), &fname.disk_name);
++ ret = btrfs_unlink_inode(trans, dir, inode, &fname.disk_name);
+ if (!ret)
+- btrfs_i_size_write(BTRFS_I(inode), 0);
++ btrfs_i_size_write(inode, 0);
+ out:
+ btrfs_end_transaction(trans);
+ out_notrans:
--- /dev/null
+From stable+bounces-249088-greg=kroah.com@vger.kernel.org Sun May 17 15:52:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 09:52:02 -0400
+Subject: btrfs: use inode already stored in local variable at btrfs_rmdir()
+To: stable@vger.kernel.org
+Cc: Filipe Manana <fdmanana@suse.com>, Johannes Thumshirn <johannes.thumshirn@wdc.com>, Qu Wenruo <wqu@suse.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260517135204.148250-1-sashal@kernel.org>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 9f82a4ed34d870b5719f9b95f7da4f74d3325a6f ]
+
+There's no need to call d_inode(dentry) when calling btrfs_unlink_inode()
+since we have already stored that in a local inode variable. So just use
+the local variable to make the code less verbose.
+
+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>
+Stable-dep-of: 999757231c49 ("btrfs: fix missing last_unlink_trans update when removing a directory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4681,8 +4681,7 @@ static int btrfs_rmdir(struct inode *dir
+ goto out;
+
+ /* now the directory is empty */
+- ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)),
+- &fname.disk_name);
++ ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(inode), &fname.disk_name);
+ if (!ret)
+ btrfs_i_size_write(BTRFS_I(inode), 0);
+ out:
--- /dev/null
+From stable+bounces-248914-greg=kroah.com@vger.kernel.org Fri May 15 22:52:26 2026
+From: "MaÃra Canal" <mcanal@igalia.com>
+Date: Fri, 15 May 2026 17:51:58 -0300
+Subject: drm/v3d: Reject empty multisync extension to prevent infinite loop
+To: stable@vger.kernel.org
+Cc: kernel-dev@igalia.com, "Ashutosh Desai" <ashutoshdesai993@gmail.com>, "MaÃra Canal" <mcanal@igalia.com>
+Message-ID: <20260515205157.2325306-2-mcanal@igalia.com>
+
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+
+v3d_get_extensions() walks a userspace-provided singly-linked list of
+ioctl extensions without any bound on the chain length. A local user
+can craft a self-referential extension (ext->next == &ext) with zero
+in_sync_count and out_sync_count, which bypasses the existing duplicate-
+extension guard:
+
+ if (se->in_sync_count || se->out_sync_count)
+ return -EINVAL;
+
+The guard never fires because v3d_get_multisync_post_deps() returns
+immediately when count is zero, leaving both fields at zero on every
+iteration. The result is an infinite loop in kernel context, blocking
+the calling thread and pegging a CPU core indefinitely.
+
+Fix this by rejecting a multisync extension where both in_sync_count
+and out_sync_count are zero in v3d_get_multisync_submit_deps(). An
+empty multisync carries no synchronization information and serves no
+useful purpose, so returning -EINVAL for such an extension is the
+correct defense against this attack vector.
+
+Fixes: e4165ae8304e ("drm/v3d: add multiple syncobjs support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
+Link: https://patch.msgid.link/20260415050000.3816128-1-ashutoshdesai993@gmail.com
+Signed-off-by: MaÃra Canal <mcanal@igalia.com>
+(cherry picked from commit fb44d589bf3148e13452185a6e772a7efbf2d684)
+Signed-off-by: MaÃra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/v3d/v3d_gem.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/v3d/v3d_gem.c
++++ b/drivers/gpu/drm/v3d/v3d_gem.c
+@@ -597,6 +597,11 @@ v3d_get_multisync_submit_deps(struct drm
+ if (multisync.pad)
+ return -EINVAL;
+
++ if (!multisync.in_sync_count && !multisync.out_sync_count) {
++ DRM_DEBUG("Empty multisync extension\n");
++ return -EINVAL;
++ }
++
+ ret = v3d_get_multisync_post_deps(file_priv, data, multisync.out_sync_count,
+ multisync.out_syncs);
+ if (ret)
--- /dev/null
+From stable+bounces-248463-greg=kroah.com@vger.kernel.org Fri May 15 18:46:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 12:16:33 -0400
+Subject: eventfs: Use list_add_tail_rcu() for SRCU-protected children list
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515161633.3376096-1-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit f67950b2887fa10df50c4317a1fe98a65bc6875b ]
+
+Commit d2603279c7d6 ("eventfs: Use list_del_rcu() for SRCU protected
+list variable") converted the removal side to pair with the
+list_for_each_entry_srcu() walker in eventfs_iterate(). The insertion
+in eventfs_create_dir() was left as a plain list_add_tail(), which on
+weakly-ordered architectures can expose a new entry to the SRCU reader
+before its list pointers and fields are observable.
+
+Use list_add_tail_rcu() so the publication pairs with the existing
+list_del_rcu() and list_for_each_entry_srcu().
+
+Fixes: 43aa6f97c2d0 ("eventfs: Get rid of dentry pointers without refcounts")
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260418152251.199343-1-devnexen@gmail.com
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+[ adapted scoped_guard(mutex, &eventfs_mutex) block to explicit mutex_lock()/mutex_unlock() pair ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/tracefs/event_inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -802,7 +802,7 @@ struct eventfs_inode *eventfs_create_dir
+
+ mutex_lock(&eventfs_mutex);
+ if (!parent->is_freed)
+- list_add_tail(&ei->list, &parent->children);
++ list_add_tail_rcu(&ei->list, &parent->children);
+ mutex_unlock(&eventfs_mutex);
+
+ /* Was the parent freed? */
--- /dev/null
+From stable+bounces-249818-greg=kroah.com@vger.kernel.org Wed May 20 13:23:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 07:17:33 -0400
+Subject: f2fs: fix false alarm of lockdep on cp_global_sem lock
+To: stable@vger.kernel.org
+Cc: Chao Yu <chao@kernel.org>, stable@kernel.org, Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>, Jaegeuk Kim <jaegeuk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520111733.3419315-1-sashal@kernel.org>
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 6a5e3de9c2bb0b691d16789a5d19e9276a09b308 ]
+
+lockdep reported a potential deadlock:
+
+a) TCMU device removal context:
+ - call del_gendisk() to get q->q_usage_counter
+ - call start_flush_work() to get work_completion of wb->dwork
+b) f2fs writeback context:
+ - in wb_workfn(), which holds work_completion of wb->dwork
+ - call f2fs_balance_fs() to get sbi->gc_lock
+c) f2fs vfs_write context:
+ - call f2fs_gc() to get sbi->gc_lock
+ - call f2fs_write_checkpoint() to get sbi->cp_global_sem
+d) f2fs mount context:
+ - call recover_fsync_data() to get sbi->cp_global_sem
+ - call f2fs_check_and_fix_write_pointer() to call blkdev_report_zones()
+ that goes down to blk_mq_alloc_request and get q->q_usage_counter
+
+Original callstack is in Closes tag.
+
+However, I think this is a false alarm due to before mount returns
+successfully (context d), we can not access file therein via vfs_write
+(context c).
+
+Let's introduce per-sb cp_global_sem_key, and assign the key for
+cp_global_sem, so that lockdep can recognize cp_global_sem from
+different super block correctly.
+
+A lot of work are done by Shin'ichiro Kawasaki, thanks a lot for
+the work.
+
+Fixes: c426d99127b1 ("f2fs: Check write pointer consistency of open zones")
+Cc: stable@kernel.org
+Reported-and-tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Closes: https://lore.kernel.org/linux-f2fs-devel/20260218125237.3340441-1-shinichiro.kawasaki@wdc.com
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+[ re-anchored lockdep_register_key after init_f2fs_rwsem and placed lockdep_unregister_key before kfree(sbi) in f2fs_put_super instead of kill_f2fs_super ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/f2fs.h | 3 +++
+ fs/f2fs/super.c | 11 +++++++++++
+ 2 files changed, 14 insertions(+)
+
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1824,6 +1824,9 @@ struct f2fs_sb_info {
+ spinlock_t iostat_lat_lock;
+ struct iostat_lat_info *iostat_io_lat;
+ #endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++ struct lock_class_key cp_global_sem_key;
++#endif
+ };
+
+ /* Definitions to access f2fs_sb_info */
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1695,6 +1695,9 @@ static void f2fs_put_super(struct super_
+ #if IS_ENABLED(CONFIG_UNICODE)
+ utf8_unload(sb->s_encoding);
+ #endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++ lockdep_unregister_key(&sbi->cp_global_sem_key);
++#endif
+ kfree(sbi);
+ }
+
+@@ -4380,6 +4383,11 @@ try_onemore:
+ init_f2fs_rwsem(&sbi->gc_lock);
+ mutex_init(&sbi->writepages);
+ init_f2fs_rwsem(&sbi->cp_global_sem);
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++ lockdep_register_key(&sbi->cp_global_sem_key);
++ lockdep_set_class(&sbi->cp_global_sem.internal_rwsem,
++ &sbi->cp_global_sem_key);
++#endif
+ init_f2fs_rwsem(&sbi->node_write);
+ init_f2fs_rwsem(&sbi->node_change);
+ spin_lock_init(&sbi->stat_lock);
+@@ -4838,6 +4846,9 @@ free_sb_buf:
+ free_sbi:
+ if (sbi->s_chksum_driver)
+ crypto_free_shash(sbi->s_chksum_driver);
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++ lockdep_unregister_key(&sbi->cp_global_sem_key);
++#endif
+ kfree(sbi);
+
+ /* give only one another chance */
--- /dev/null
+From stable+bounces-249638-greg=kroah.com@vger.kernel.org Tue May 19 18:26:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:18:07 -0400
+Subject: f2fs: fix incorrect file address mapping when inline inode is unwritten
+To: stable@vger.kernel.org
+Cc: Yongpeng Yang <yangyongpeng@xiaomi.com>, stable@kernel.org, Chao Yu <chao@kernel.org>, Jaegeuk Kim <jaegeuk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260519161807.2778184-1-sashal@kernel.org>
+
+From: Yongpeng Yang <yangyongpeng@xiaomi.com>
+
+[ Upstream commit 68a0178981a0f493295afa29f8880246e561494c ]
+
+When `fileinfo->fi_flags` does not have the `FIEMAP_FLAG_SYNC` bit set
+and inline data has not been persisted yet, the physical address of the
+extent is calculated incorrectly for unwritten inline inodes.
+
+root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
+root@vm:/mnt/f2fs# f2fs_io fiemap 0 100 data.3k
+Fiemap: offset = 0 len = 100
+ logical addr. physical addr. length flags
+0 0000000000000000 00000ffffffff16c 0000000000000c00 00000301
+
+This patch fixes the issue by checking if the inode's address is valid.
+If the inline inode is unwritten, set the physical address to 0 and
+mark the extent with `FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC`
+flags.
+
+Cc: stable@kernel.org
+Fixes: 67f8cf3cee6f ("f2fs: support fiemap for inline_data")
+Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+[ renamed `ifolio` to `ipage` in `inline_data_addr()` and `F2FS_INODE()` calls ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/inline.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/fs/f2fs/inline.c
++++ b/fs/f2fs/inline.c
+@@ -791,7 +791,7 @@ int f2fs_read_inline_dir(struct file *fi
+ int f2fs_inline_data_fiemap(struct inode *inode,
+ struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
+ {
+- __u64 byteaddr, ilen;
++ __u64 byteaddr = 0, ilen;
+ __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
+ FIEMAP_EXTENT_LAST;
+ struct node_info ni;
+@@ -824,9 +824,14 @@ int f2fs_inline_data_fiemap(struct inode
+ if (err)
+ goto out;
+
+- byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
+- byteaddr += (char *)inline_data_addr(inode, ipage) -
+- (char *)F2FS_INODE(ipage);
++ if (__is_valid_data_blkaddr(ni.blk_addr)) {
++ byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
++ byteaddr += (char *)inline_data_addr(inode, ipage) -
++ (char *)F2FS_INODE(ipage);
++ } else {
++ f2fs_bug_on(F2FS_I_SB(inode), ni.blk_addr != NEW_ADDR);
++ flags |= FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN;
++ }
+ err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags);
+ trace_f2fs_fiemap(inode, start, byteaddr, ilen, flags, err);
+ out:
--- /dev/null
+From stable+bounces-249899-greg=kroah.com@vger.kernel.org Wed May 20 14:11:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 07:54:35 -0400
+Subject: ksmbd: validate inherited ACE SID length
+To: stable@vger.kernel.org
+Cc: Shota Zaizen <s@zaizen.me>, Namjae Jeon <linkinjeon@kernel.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520115435.3487594-1-sashal@kernel.org>
+
+From: Shota Zaizen <s@zaizen.me>
+
+[ Upstream commit 996454bc0da84d5a1dedb1a7861823087e01a7ae ]
+
+smb_inherit_dacl() walks the parent directory DACL loaded from the
+security descriptor xattr. It verifies that each ACE contains the fixed
+SID header before using it, but does not verify that the variable-length
+SID described by sid.num_subauth is fully contained in the ACE.
+
+A malformed inheritable ACE can advertise more subauthorities than are
+present in the ACE. compare_sids() may then read past the ACE.
+smb_set_ace() also clamps the copied destination SID, but used the
+unchecked source SID count to compute the inherited ACE size. That could
+advance the temporary inherited ACE buffer pointer and nt_size accounting
+past the allocated buffer.
+
+Fix this by validating the parent ACE SID count and SID length before
+using the SID during inheritance. Compute the inherited ACE size from the
+copied SID so the size matches the bounded destination SID. Reject the
+inherited DACL if size accumulation would overflow smb_acl.size or the
+security descriptor allocation size.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Signed-off-by: Shota Zaizen <s@zaizen.me>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/smbacl.c | 66 ++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 52 insertions(+), 14 deletions(-)
+
+--- a/fs/smb/server/smbacl.c
++++ b/fs/smb/server/smbacl.c
+@@ -1025,7 +1025,26 @@ static void smb_set_ace(struct smb_ace *
+ ace->flags = flags;
+ ace->access_req = access_req;
+ smb_copy_sid(&ace->sid, sid);
+- ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
++ ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 +
++ (ace->sid.num_subauth * 4));
++}
++
++static int smb_append_inherited_ace(struct smb_ace **ace, int *nt_size,
++ u16 *ace_cnt, const struct smb_sid *sid,
++ u8 type, u8 flags, __le32 access_req)
++{
++ int ace_size;
++
++ smb_set_ace(*ace, sid, type, flags, access_req);
++ ace_size = le16_to_cpu((*ace)->size);
++ /* pdacl->size is __le16 and includes struct smb_acl. */
++ if (check_add_overflow(*nt_size, ace_size, nt_size) ||
++ *nt_size > U16_MAX - (int)sizeof(struct smb_acl))
++ return -EINVAL;
++
++ (*ace_cnt)++;
++ *ace = (struct smb_ace *)((char *)*ace + ace_size);
++ return 0;
+ }
+
+ int smb_inherit_dacl(struct ksmbd_conn *conn,
+@@ -1090,6 +1109,12 @@ int smb_inherit_dacl(struct ksmbd_conn *
+ if (pace_size > aces_size)
+ break;
+
++ if (parent_aces->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
++ pace_size < offsetof(struct smb_ace, sid) +
++ CIFS_SID_BASE_SIZE +
++ sizeof(__le32) * parent_aces->sid.num_subauth)
++ break;
++
+ aces_size -= pace_size;
+
+ flags = parent_aces->flags;
+@@ -1119,22 +1144,24 @@ int smb_inherit_dacl(struct ksmbd_conn *
+ }
+
+ if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
+- smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
+- parent_aces->access_req);
+- nt_size += le16_to_cpu(aces->size);
+- ace_cnt++;
+- aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
++ rc = smb_append_inherited_ace(&aces, &nt_size, &ace_cnt,
++ psid, parent_aces->type,
++ inherited_flags,
++ parent_aces->access_req);
++ if (rc)
++ goto free_aces_base;
+ flags |= INHERIT_ONLY_ACE;
+ psid = creator;
+ } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
+ psid = &parent_aces->sid;
+ }
+
+- smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
+- parent_aces->access_req);
+- nt_size += le16_to_cpu(aces->size);
+- aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
+- ace_cnt++;
++ rc = smb_append_inherited_ace(&aces, &nt_size, &ace_cnt, psid,
++ parent_aces->type,
++ flags | inherited_flags,
++ parent_aces->access_req);
++ if (rc)
++ goto free_aces_base;
+ pass:
+ parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
+ }
+@@ -1144,7 +1171,7 @@ pass:
+ struct smb_acl *pdacl;
+ struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
+ int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
+- int pntsd_alloc_size;
++ size_t pntsd_alloc_size;
+
+ if (parent_pntsd->osidoffset) {
+ powner_sid = (struct smb_sid *)((char *)parent_pntsd +
+@@ -1157,8 +1184,19 @@ pass:
+ pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
+ }
+
+- pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size +
+- pgroup_sid_size + sizeof(struct smb_acl) + nt_size;
++ if (check_add_overflow(sizeof(struct smb_ntsd),
++ (size_t)powner_sid_size,
++ &pntsd_alloc_size) ||
++ check_add_overflow(pntsd_alloc_size,
++ (size_t)pgroup_sid_size,
++ &pntsd_alloc_size) ||
++ check_add_overflow(pntsd_alloc_size, sizeof(struct smb_acl),
++ &pntsd_alloc_size) ||
++ check_add_overflow(pntsd_alloc_size, (size_t)nt_size,
++ &pntsd_alloc_size)) {
++ rc = -EINVAL;
++ goto free_aces_base;
++ }
+
+ pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL);
+ if (!pntsd) {
--- /dev/null
+From stable+bounces-249912-greg=kroah.com@vger.kernel.org Wed May 20 15:02:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 08:56:20 -0400
+Subject: media: nxp: imx8-isi: Reduce minimum queued buffers from 2 to 0
+To: stable@vger.kernel.org
+Cc: Guoniu Zhou <guoniu.zhou@nxp.com>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Hans Verkuil <hverkuil+cisco@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520125620.3537083-1-sashal@kernel.org>
+
+From: Guoniu Zhou <guoniu.zhou@nxp.com>
+
+[ Upstream commit 2f38622d0f85f317be9e6b131da6cd511db94fd2 ]
+
+Fix a hang issue when capturing a single frame with applications like cam
+in libcamera. It would hang waiting for the driver to complete the buffer,
+but streaming never starts because min_queued_buffers was set to 2.
+
+The ISI module uses a ping-pong buffer mechanism that requires two buffers
+to be programmed at all times. However, when fewer than 2 user buffers are
+available, the driver use internal discard buffers to fill the remaining
+slot(s). Reduce minimum queued buffers from 2 to 0 allows streaming to
+start without any queued buffers.
+
+Fixes: cf21f328fcaf ("media: nxp: Add i.MX8 ISI driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://patch.msgid.link/20260312-isi_min_buffers-v2-1-d5ea1c79ad81@nxp.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+[ renamed `min_queued_buffers` to `min_buffers_needed` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
++++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
+@@ -1456,7 +1456,7 @@ int mxc_isi_video_register(struct mxc_is
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct mxc_isi_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+- q->min_buffers_needed = 2;
++ q->min_buffers_needed = 0;
+ q->lock = &video->lock;
+ q->dev = pipe->isi->dev;
+
--- /dev/null
+From stable+bounces-249275-greg=kroah.com@vger.kernel.org Mon May 18 15:09:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 09:05:08 -0400
+Subject: mptcp: drop __mptcp_fastopen_gen_msk_ackseq()
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518130509.978083-1-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit f03afb3aeb9d81f6c5ab728a61a040012923e3b3 ]
+
+When we will move the whole RX path under the msk socket lock, updating
+the already queued skb for passive fastopen socket at 3rd ack time will
+be extremely painful and race prone
+
+The map_seq for already enqueued skbs is used only to allow correct
+coalescing with later data; preventing collapsing to the first skb of
+a fastopen connect we can completely remove the
+__mptcp_fastopen_gen_msk_ackseq() helper.
+
+Before dropping this helper, a new item had to be added to the
+mptcp_skb_cb structure. Because this item will be frequently tested in
+the fast path -- almost on every packet -- and because there is free
+space there, a single byte is used instead of a bitfield. This micro
+optimisation slightly reduces the number of CPU operations to do the
+associated check.
+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20250218-net-next-mptcp-rx-path-refactor-v1-2-4a47d90d7998@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6254a16d6f0c ("mptcp: fix rx timestamp corruption on fastopen")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/fastopen.c | 24 ++----------------------
+ net/mptcp/protocol.c | 4 +++-
+ net/mptcp/protocol.h | 5 ++---
+ net/mptcp/subflow.c | 3 ---
+ 4 files changed, 7 insertions(+), 29 deletions(-)
+
+--- a/net/mptcp/fastopen.c
++++ b/net/mptcp/fastopen.c
+@@ -40,13 +40,12 @@ void mptcp_fastopen_subflow_synack_set_p
+ tp->copied_seq += skb->len;
+ subflow->ssn_offset += skb->len;
+
+- /* initialize a dummy sequence number, we will update it at MPC
+- * completion, if needed
+- */
++ /* Only the sequence delta is relevant */
+ MPTCP_SKB_CB(skb)->map_seq = -skb->len;
+ MPTCP_SKB_CB(skb)->end_seq = 0;
+ MPTCP_SKB_CB(skb)->offset = 0;
+ MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
++ MPTCP_SKB_CB(skb)->cant_coalesce = 1;
+
+ mptcp_data_lock(sk);
+
+@@ -58,22 +57,3 @@ void mptcp_fastopen_subflow_synack_set_p
+
+ mptcp_data_unlock(sk);
+ }
+-
+-void __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+- const struct mptcp_options_received *mp_opt)
+-{
+- struct sock *sk = (struct sock *)msk;
+- struct sk_buff *skb;
+-
+- skb = skb_peek_tail(&sk->sk_receive_queue);
+- if (skb) {
+- WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq);
+- pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx\n", sk,
+- MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq,
+- MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq);
+- MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq;
+- MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq;
+- }
+-
+- pr_debug("msk=%p ack_seq=%llx\n", msk, msk->ack_seq);
+-}
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -139,7 +139,8 @@ static bool mptcp_try_coalesce(struct so
+ bool fragstolen;
+ int delta;
+
+- if (MPTCP_SKB_CB(from)->offset ||
++ if (unlikely(MPTCP_SKB_CB(to)->cant_coalesce) ||
++ MPTCP_SKB_CB(from)->offset ||
+ ((to->len + from->len) > (sk->sk_rcvbuf >> 3)) ||
+ !skb_try_coalesce(to, from, &fragstolen, &delta))
+ return false;
+@@ -370,6 +371,7 @@ static bool __mptcp_move_skb(struct mptc
+ MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + copy_len;
+ MPTCP_SKB_CB(skb)->offset = offset;
+ MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
++ MPTCP_SKB_CB(skb)->cant_coalesce = 0;
+
+ if (MPTCP_SKB_CB(skb)->map_seq == msk->ack_seq) {
+ /* in sequence */
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -129,7 +129,8 @@ struct mptcp_skb_cb {
+ u64 map_seq;
+ u64 end_seq;
+ u32 offset;
+- u8 has_rxtstamp:1;
++ u8 has_rxtstamp;
++ u8 cant_coalesce;
+ };
+
+ #define MPTCP_SKB_CB(__skb) ((struct mptcp_skb_cb *)&((__skb)->cb[0]))
+@@ -988,8 +989,6 @@ void mptcp_event_pm_listener(const struc
+ enum mptcp_event_type event);
+ bool mptcp_userspace_pm_active(const struct mptcp_sock *msk);
+
+-void __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+- const struct mptcp_options_received *mp_opt);
+ void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
+ struct request_sock *req);
+
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -778,9 +778,6 @@ void __mptcp_subflow_fully_established(s
+ subflow_set_remote_key(msk, subflow, mp_opt);
+ subflow->fully_established = 1;
+ WRITE_ONCE(msk->fully_established, true);
+-
+- if (subflow->is_mptfo)
+- __mptcp_fastopen_gen_msk_ackseq(msk, subflow, mp_opt);
+ }
+
+ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
--- /dev/null
+From stable+bounces-249276-greg=kroah.com@vger.kernel.org Mon May 18 15:09:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 09:05:09 -0400
+Subject: mptcp: fix rx timestamp corruption on fastopen
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518130509.978083-2-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 6254a16d6f0c672e3809ca5d7c9a28a55d71f764 ]
+
+The skb cb offset containing the timestamp presence flag is cleared
+before loading such information. Cache such value before MPTCP CB
+initialization.
+
+Fixes: 36b122baf6a8 ("mptcp: add subflow_v(4,6)_send_synack()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260501-net-mptcp-misc-fixes-7-1-rc3-v1-3-b70118df778e@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/fastopen.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/fastopen.c
++++ b/net/mptcp/fastopen.c
+@@ -12,6 +12,7 @@ void mptcp_fastopen_subflow_synack_set_p
+ struct sock *sk, *ssk;
+ struct sk_buff *skb;
+ struct tcp_sock *tp;
++ bool has_rxtstamp;
+
+ /* on early fallback the subflow context is deleted by
+ * subflow_syn_recv_sock()
+@@ -39,12 +40,13 @@ void mptcp_fastopen_subflow_synack_set_p
+ */
+ tp->copied_seq += skb->len;
+ subflow->ssn_offset += skb->len;
++ has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
+
+ /* Only the sequence delta is relevant */
+ MPTCP_SKB_CB(skb)->map_seq = -skb->len;
+ MPTCP_SKB_CB(skb)->end_seq = 0;
+ MPTCP_SKB_CB(skb)->offset = 0;
+- MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
++ MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
+ MPTCP_SKB_CB(skb)->cant_coalesce = 1;
+
+ mptcp_data_lock(sk);
--- /dev/null
+From stable+bounces-249305-greg=kroah.com@vger.kernel.org Mon May 18 16:24:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 10:23:36 -0400
+Subject: mptcp: pm: ADD_ADDR rtx: fix potential data-race
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518142336.1308295-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 5cd6e0ad79d2615264f63929f8b457ad97ae550d ]
+
+This mptcp_pm_add_timer() helper is executed as a timer callback in
+softirq context. To avoid any data races, the socket lock needs to be
+held with bh_lock_sock().
+
+If the socket is in use, retry again soon after, similar to what is done
+with the keepalive timer.
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-3-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied hunk to `net/mptcp/pm_netlink.c` instead of `net/mptcp/pm.c` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -308,6 +308,13 @@ static void mptcp_pm_add_timer(struct ti
+ if (!entry->addr.id)
+ return;
+
++ bh_lock_sock(sk);
++ if (sock_owned_by_user(sk)) {
++ /* Try again later. */
++ sk_reset_timer(sk, timer, jiffies + HZ / 20);
++ goto out;
++ }
++
+ if (mptcp_pm_should_add_signal_addr(msk)) {
+ sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
+ goto out;
+@@ -336,6 +343,7 @@ static void mptcp_pm_add_timer(struct ti
+ mptcp_pm_subflow_established(msk);
+
+ out:
++ bh_unlock_sock(sk);
+ __sock_put(sk);
+ }
+
--- /dev/null
+From stable+bounces-249566-greg=kroah.com@vger.kernel.org Tue May 19 13:56:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 07:52:19 -0400
+Subject: mptcp: pm: ADD_ADDR rtx: resched blocked ADD_ADDR quicker
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260519115219.2240625-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 3cf12492891c4b5ff54dda404a2de4ec54c9e1b5 ]
+
+When an ADD_ADDR needs to be retransmitted and another one has already
+been prepared -- e.g. multiple ADD_ADDRs have been sent in a row and
+need to be retransmitted later -- this additional retransmission will
+need to wait.
+
+In this case, the timer was reset to TCP_RTO_MAX / 8, which is ~15
+seconds. This delay is unnecessary long: it should just be rescheduled
+at the next opportunity, e.g. after the retransmission timeout.
+
+Without this modification, some issues can be seen from time to time in
+the selftests when multiple ADD_ADDRs are sent, and the host takes time
+to process them, e.g. the "signal addresses, ADD_ADDR timeout" MPTCP
+Join selftest, especially with a debug kernel config.
+
+Note that on older kernels, 'timeout' is not available. It should be
+enough to replace it by one second (HZ).
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-6-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ replaced `TCP_RTO_MAX / 8` with `HZ` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -316,7 +316,7 @@ static void mptcp_pm_add_timer(struct ti
+ }
+
+ if (mptcp_pm_should_add_signal_addr(msk)) {
+- sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
++ sk_reset_timer(sk, timer, jiffies + HZ);
+ goto out;
+ }
+
--- /dev/null
+From stable+bounces-249291-greg=kroah.com@vger.kernel.org Mon May 18 15:52:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 09:45:28 -0400
+Subject: mptcp: pm: kernel: correctly retransmit ADD_ADDR ID 0
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518134529.1135588-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit b12014d2d36eaed4e4bec5f1ac7e91110eeb100d ]
+
+When adding the ADD_ADDR to the list, the address including the IP, port
+and ID are copied. On the other hand, when the endpoint corresponds to
+the one from the initial subflow, the ID is set to 0, as specified by
+the MPTCP protocol.
+
+The issue is that the ID was reset after having copied the ID in the
+ADD_ADDR entry. So the retransmission was done, but using a different ID
+than the initial one.
+
+Fixes: 8b8ed1b429f8 ("mptcp: pm: reuse ID 0 after delete and re-add")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-1-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied to net/mptcp/pm_netlink.c instead of upstream's pm_kernel.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -591,6 +591,8 @@ static void mptcp_pm_create_subflow_or_s
+
+ /* check first for announce */
+ if (msk->pm.add_addr_signaled < add_addr_signal_max) {
++ u8 endp_id;
++
+ /* due to racing events on both ends we can reach here while
+ * previous add address is still running: if we invoke now
+ * mptcp_pm_announce_addr(), that will fail and the
+@@ -604,19 +606,20 @@ static void mptcp_pm_create_subflow_or_s
+ if (!select_signal_address(pernet, msk, &local))
+ goto subflow;
+
++ /* Special case for ID0: set the correct ID */
++ endp_id = local.addr.id;
++ if (endp_id == msk->mpc_endpoint_id)
++ local.addr.id = 0;
++
+ /* If the alloc fails, we are on memory pressure, not worth
+ * continuing, and trying to create subflows.
+ */
+ if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
+ return;
+
+- __clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
++ __clear_bit(endp_id, msk->pm.id_avail_bitmap);
+ msk->pm.add_addr_signaled++;
+
+- /* Special case for ID0: set the correct ID */
+- if (local.addr.id == msk->mpc_endpoint_id)
+- local.addr.id = 0;
+-
+ mptcp_pm_announce_addr(msk, &local.addr, false);
+ mptcp_pm_nl_addr_send_ack(msk);
+
--- /dev/null
+From stable+bounces-249274-greg=kroah.com@vger.kernel.org Mon May 18 15:13:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 09:04:57 -0400
+Subject: mptcp: pm: prio: skip closed subflows
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518130457.973971-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 166b78344031bf7ac9f55cb5282776cfd85f220e ]
+
+When sending an MP_PRIO, closed subflows need to be skipped.
+
+This fixes the case where the initial subflow got closed, re-opened
+later, then an MP_PRIO is needed for the same local address.
+
+Note that explicit MP_PRIO cannot be sent during the 3WHS, so it is fine
+to use __mptcp_subflow_active().
+
+Fixes: 067065422fcd ("mptcp: add the outgoing MP_PRIO support")
+Cc: stable@vger.kernel.org
+Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-9-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied to renamed function `mptcp_pm_nl_mp_prio_send_ack()` in `pm_netlink.c` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -923,6 +923,9 @@ int mptcp_pm_nl_mp_prio_send_ack(struct
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+ struct mptcp_addr_info local, remote;
+
++ if (!__mptcp_subflow_active(subflow))
++ continue;
++
+ mptcp_local_address((struct sock_common *)ssk, &local);
+ if (!mptcp_addresses_equal(&local, addr, addr->port))
+ continue;
--- /dev/null
+From stable+bounces-247822-greg=kroah.com@vger.kernel.org Fri May 15 17:31:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 11:20:34 -0400
+Subject: pmdomain: core: Fix detach procedure for virtual devices in genpd
+To: stable@vger.kernel.org
+Cc: Ulf Hansson <ulf.hansson@linaro.org>, Geert Uytterhoeven <geert@linux-m68k.org>, Geert Uytterhoeven <geert+renesas@glider.be>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515152034.3277396-1-sashal@kernel.org>
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 26735dfdd8930d9ef1fa92e590a9bf77726efdf6 ]
+
+If a device is attached to a PM domain through genpd_dev_pm_attach_by_id(),
+genpd calls pm_runtime_enable() for the corresponding virtual device that
+it registers. While this avoids boilerplate code in drivers, there is no
+corresponding call to pm_runtime_disable() in genpd_dev_pm_detach().
+
+This means these virtual devices are typically detached from its genpd,
+while runtime PM remains enabled for them, which is not how things are
+designed to work. In worst cases it may lead to critical errors, like a
+NULL pointer dereference bug in genpd_runtime_suspend(), which was recently
+reported. For another case, we may end up keeping an unnecessary vote for a
+performance state for the device.
+
+To fix these problems, let's add this missing call to pm_runtime_disable()
+in genpd_dev_pm_detach().
+
+Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Closes: https://lore.kernel.org/all/CAMuHMdWapT40hV3c+CSBqFOW05aWcV1a6v_NiJYgoYi0i9_PDQ@mail.gmail.com/
+Fixes: 3c095f32a92b ("PM / Domains: Add support for multi PM domains per device to genpd")
+Cc: stable@vger.kernel.org
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/power/domain.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2676,6 +2676,7 @@ static struct bus_type genpd_bus_type =
+ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
+ {
+ struct generic_pm_domain *pd;
++ bool is_virt_dev;
+ unsigned int i;
+ int ret = 0;
+
+@@ -2685,6 +2686,13 @@ static void genpd_dev_pm_detach(struct d
+
+ dev_dbg(dev, "removing from PM domain %s\n", pd->name);
+
++ /* Check if the device was created by genpd at attach. */
++ is_virt_dev = dev->bus == &genpd_bus_type;
++
++ /* Disable runtime PM if we enabled it at attach. */
++ if (is_virt_dev)
++ pm_runtime_disable(dev);
++
+ /* Drop the default performance state */
+ if (dev_gpd_data(dev)->default_pstate) {
+ dev_pm_genpd_set_performance_state(dev, 0);
+@@ -2710,7 +2718,7 @@ static void genpd_dev_pm_detach(struct d
+ genpd_queue_power_off_work(pd);
+
+ /* Unregister the device if it was created by genpd. */
+- if (dev->bus == &genpd_bus_type)
++ if (is_virt_dev)
+ device_unregister(dev);
+ }
+
--- /dev/null
+From stable+bounces-249896-greg=kroah.com@vger.kernel.org Wed May 20 13:55:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 07:47:30 -0400
+Subject: RDMA/mana: Fix error unwind in mana_ib_create_qp_rss()
+To: stable@vger.kernel.org
+Cc: Jason Gunthorpe <jgg@nvidia.com>, Long Li <longli@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520114730.3470533-1-sashal@kernel.org>
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 6aaa978c6b6218cfac15fe1dab17c76fe229ce3f ]
+
+Sashiko points out that mana_ib_cfg_vport_steering() is leaked, the normal
+destroy path cleans it up.
+
+Cc: stable@vger.kernel.org
+Fixes: 0266a177631d ("RDMA/mana_ib: Add a driver for Microsoft Azure Network Adapter")
+Link: https://sashiko.dev/#/patchset/0-v1-e911b76a94d1%2B65d95-rdma_udata_rep_jgg%40nvidia.com?part=4
+Link: https://patch.msgid.link/r/7-v1-41f3135e5565+9d2-rdma_ai_fixes1_jgg@nvidia.com
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/mana/qp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/mana/qp.c
++++ b/drivers/infiniband/hw/mana/qp.c
+@@ -237,13 +237,15 @@ static int mana_ib_create_qp_rss(struct
+ ibdev_dbg(&mdev->ib_dev,
+ "Failed to copy to udata create rss-qp, %d\n",
+ ret);
+- goto fail;
++ goto err_disable_vport_rx;
+ }
+
+ kfree(mana_ind_table);
+
+ return 0;
+
++err_disable_vport_rx:
++ mana_disable_vport_rx(mpc);
+ fail:
+ while (i-- > 0) {
+ ibwq = ind_tbl->ind_tbl[i];
--- /dev/null
+From stable+bounces-249178-greg=kroah.com@vger.kernel.org Mon May 18 05:28:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 23:28:24 -0400
+Subject: RDMA/mana: Validate rx_hash_key_len
+To: stable@vger.kernel.org
+Cc: Jason Gunthorpe <jgg@nvidia.com>, Long Li <longli@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518032824.588408-1-sashal@kernel.org>
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 6dd2d4ad9c8429523b1c220c5132bd551c006425 ]
+
+Sashiko points out that rx_hash_key_len comes from a uAPI structure and is
+blindly passed to memcpy, allowing the userspace to trash kernel
+memory. Bounds check it so the memcpy cannot overflow.
+
+Cc: stable@vger.kernel.org
+Fixes: 0266a177631d ("RDMA/mana_ib: Add a driver for Microsoft Azure Network Adapter")
+Link: https://sashiko.dev/#/patchset/0-v2-1c49eeb88c48%2B91-rdma_udata_rep_jgg%40nvidia.com?part=1
+Link: https://patch.msgid.link/r/4-v1-41f3135e5565+9d2-rdma_ai_fixes1_jgg@nvidia.com
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+[ kept the stable branch's existing `req_buf_size` calculation instead of upstream's `struct_size(req, indir_tab, ...)` form ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/mana/qp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/infiniband/hw/mana/qp.c
++++ b/drivers/infiniband/hw/mana/qp.c
+@@ -24,6 +24,9 @@ static int mana_ib_cfg_vport_steering(st
+ mdev = dev->gdma_dev;
+ gc = mdev->gdma_context;
+
++ if (rx_hash_key_len > sizeof(req->hashkey))
++ return -EINVAL;
++
+ req_buf_size =
+ sizeof(*req) + sizeof(mana_handle_t) * MANA_INDIRECT_TABLE_SIZE;
+ req = kzalloc(req_buf_size, GFP_KERNEL);
drm-gma500-oaktrail_hdmi-fix-i2c-adapter-leak-on-setup.patch
drm-gma500-oaktrail_lvds-fix-hang-on-init-failure.patch
drm-gma500-oaktrail_lvds-fix-i2c-adapter-leaks-on-init.patch
+pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch
+btrfs-remove-fs_info-argument-from-btrfs_sysfs_add_space_info_type.patch
+btrfs-fix-double-free-in-create_space_info_sub_group-error-path.patch
+eventfs-use-list_add_tail_rcu-for-srcu-protected-children-list.patch
+drm-v3d-reject-empty-multisync-extension-to-prevent-infinite-loop.patch
+smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
+btrfs-use-inode-already-stored-in-local-variable-at-btrfs_rmdir.patch
+btrfs-use-btrfs-inodes-in-btrfs_rmdir-to-avoid-so-much-usage-of-btrfs_i.patch
+btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch
+rdma-mana-validate-rx_hash_key_len.patch
+mptcp-drop-__mptcp_fastopen_gen_msk_ackseq.patch
+mptcp-fix-rx-timestamp-corruption-on-fastopen.patch
+mptcp-pm-prio-skip-closed-subflows.patch
+mptcp-pm-kernel-correctly-retransmit-add_addr-id-0.patch
+f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch
+f2fs-fix-false-alarm-of-lockdep-on-cp_global_sem-lock.patch
+rdma-mana-fix-error-unwind-in-mana_ib_create_qp_rss.patch
+ksmbd-validate-inherited-ace-sid-length.patch
+spi-st-ssc4-switch-to-use-modern-name.patch
+spi-st-ssc4-fix-controller-deregistration.patch
+media-nxp-imx8-isi-reduce-minimum-queued-buffers-from-2-to-0.patch
+spi-sifive-simplify-clock-handling-with-devm_clk_get_enabled.patch
+spi-sifive-fix-controller-deregistration.patch
+mptcp-pm-add_addr-rtx-fix-potential-data-race.patch
+mptcp-pm-add_addr-rtx-resched-blocked-add_addr-quicker.patch
--- /dev/null
+From stable+bounces-249085-greg=kroah.com@vger.kernel.org Sun May 17 15:51:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 09:51:43 -0400
+Subject: smb: client: Use FullSessionKey for AES-256 encryption key derivation
+To: stable@vger.kernel.org
+Cc: Piyush Sachdeva <s.piyush1024@gmail.com>, Bharath SM <bharathsm@microsoft.com>, Piyush Sachdeva <psachdeva@microsoft.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260517135143.147448-1-sashal@kernel.org>
+
+From: Piyush Sachdeva <s.piyush1024@gmail.com>
+
+[ Upstream commit 5be7a0cef3229fb3b63a07c0d289daf752545424 ]
+
+When Kerberos authentication is used with AES-256 encryption (AES-256-CCM
+or AES-256-GCM), the SMB3 encryption and decryption keys must be derived
+using the full session key (Session.FullSessionKey) rather than just the
+first 16 bytes (Session.SessionKey).
+
+Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and
+Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey
+must be set to the full cryptographic key from the GSS authentication
+context. The encryption and decryption key derivation (SMBC2SCipherKey,
+SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The
+signing key derivation continues to use Session.SessionKey (first 16
+bytes) in all cases.
+
+Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the
+HMAC-SHA256 key input length for all derivations. When Kerberos with
+AES-256 provides a 32-byte session key, the KDF for encryption/decryption
+was using only the first 16 bytes, producing keys that did not match the
+server's, causing mount failures with sec=krb5 and require_gcm_256=1.
+
+Add a full_key_size parameter to generate_key() and pass the appropriate
+size from generate_smb3signingkey():
+ - Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
+ - Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
+
+Also fix cifs_dump_full_key() to report the actual session key length for
+AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools
+like Wireshark receive the correct key for decryption.
+
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Signed-off-by: Piyush Sachdeva <psachdeva@microsoft.com>
+Signed-off-by: Piyush Sachdeva <s.piyush1024@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ adapted upstream's void/hmac_sha256_init_usingrawkey-based generate_key() to 6.12's int-return crypto_shash_* form while threading full_key_size through all callers. ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/ioctl.c | 2 +-
+ fs/smb/client/smb2transport.c | 32 +++++++++++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 8 deletions(-)
+
+--- a/fs/smb/client/ioctl.c
++++ b/fs/smb/client/ioctl.c
+@@ -280,7 +280,7 @@ search_end:
+ break;
+ case SMB2_ENCRYPTION_AES256_CCM:
+ case SMB2_ENCRYPTION_AES256_GCM:
+- out.session_key_length = CIFS_SESS_KEY_SIZE;
++ out.session_key_length = ses->auth_key.len;
+ out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE;
+ break;
+ default:
+--- a/fs/smb/client/smb2transport.c
++++ b/fs/smb/client/smb2transport.c
+@@ -334,7 +334,8 @@ out:
+ }
+
+ static int generate_key(struct cifs_ses *ses, struct kvec label,
+- struct kvec context, __u8 *key, unsigned int key_size)
++ struct kvec context, __u8 *key, unsigned int key_size,
++ unsigned int full_key_size)
+ {
+ unsigned char zero = 0x0;
+ __u8 i[4] = {0, 0, 0, 1};
+@@ -355,7 +356,7 @@ static int generate_key(struct cifs_ses
+ }
+
+ rc = crypto_shash_setkey(server->secmech.hmacsha256->tfm,
+- ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
++ ses->auth_key.response, full_key_size);
+ if (rc) {
+ cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
+ goto smb3signkey_ret;
+@@ -430,6 +431,7 @@ generate_smb3signingkey(struct cifs_ses
+ struct TCP_Server_Info *server,
+ const struct derivation_triplet *ptriplet)
+ {
++ unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;
+ int rc;
+ bool is_binding = false;
+ int chan_index = 0;
+@@ -464,17 +466,31 @@ generate_smb3signingkey(struct cifs_ses
+ rc = generate_key(ses, ptriplet->signing.label,
+ ptriplet->signing.context,
+ ses->chans[chan_index].signkey,
+- SMB3_SIGN_KEY_SIZE);
++ SMB3_SIGN_KEY_SIZE,
++ SMB2_NTLMV2_SESSKEY_SIZE);
+ if (rc)
+ return rc;
+ } else {
+ rc = generate_key(ses, ptriplet->signing.label,
+ ptriplet->signing.context,
+ ses->smb3signingkey,
+- SMB3_SIGN_KEY_SIZE);
++ SMB3_SIGN_KEY_SIZE,
++ SMB2_NTLMV2_SESSKEY_SIZE);
+ if (rc)
+ return rc;
+
++ /*
++ * Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey
++ * (first 16 bytes). Encryption/decryption keys use
++ * Session.FullSessionKey when dialect is 3.1.1 and cipher is
++ * AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey.
++ */
++
++ if (server->dialect == SMB311_PROT_ID &&
++ (server->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
++ server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
++ full_key_size = ses->auth_key.len;
++
+ /* safe to access primary channel, since it will never go away */
+ spin_lock(&ses->chan_lock);
+ memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
+@@ -484,13 +500,15 @@ generate_smb3signingkey(struct cifs_ses
+ rc = generate_key(ses, ptriplet->encryption.label,
+ ptriplet->encryption.context,
+ ses->smb3encryptionkey,
+- SMB3_ENC_DEC_KEY_SIZE);
++ SMB3_ENC_DEC_KEY_SIZE,
++ full_key_size);
+ if (rc)
+ return rc;
+ rc = generate_key(ses, ptriplet->decryption.label,
+ ptriplet->decryption.context,
+ ses->smb3decryptionkey,
+- SMB3_ENC_DEC_KEY_SIZE);
++ SMB3_ENC_DEC_KEY_SIZE,
++ full_key_size);
+ if (rc)
+ return rc;
+ }
+@@ -505,7 +523,7 @@ generate_smb3signingkey(struct cifs_ses
+ &ses->Suid);
+ cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
+ cifs_dbg(VFS, "Session Key %*ph\n",
+- SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
++ (int)ses->auth_key.len, ses->auth_key.response);
+ cifs_dbg(VFS, "Signing Key %*ph\n",
+ SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
+ if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
--- /dev/null
+From stable+bounces-250011-greg=kroah.com@vger.kernel.org Wed May 20 17:35:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 11:18:18 -0400
+Subject: spi: sifive: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Yash Shah <yash.shah@sifive.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520151818.3912903-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 0f25236694a2854627c1597465a071e6bb6fe572 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like interrupts during driver unbind.
+
+Note that clocks were also disabled before the recent commit
+140039c23aca ("spi: sifive: Simplify clock handling with
+devm_clk_get_enabled()").
+
+Fixes: 484a9a68d669 ("spi: sifive: Add driver for the SiFive SPI controller")
+Cc: stable@vger.kernel.org # 5.1
+Cc: Yash Shah <yash.shah@sifive.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-15-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sifive.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-sifive.c
++++ b/drivers/spi/spi-sifive.c
+@@ -393,7 +393,7 @@ static int sifive_spi_probe(struct platf
+ dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
+ irq, host->num_chipselect);
+
+- ret = devm_spi_register_controller(&pdev->dev, host);
++ ret = spi_register_controller(host);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "spi_register_host failed\n");
+ goto put_host;
+@@ -412,8 +412,14 @@ static void sifive_spi_remove(struct pla
+ struct spi_controller *host = platform_get_drvdata(pdev);
+ struct sifive_spi *spi = spi_controller_get_devdata(host);
+
++ spi_controller_get(host);
++
++ spi_unregister_controller(host);
++
+ /* Disable all the interrupts just in case */
+ sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
++
++ spi_controller_put(host);
+ }
+
+ static int sifive_spi_suspend(struct device *dev)
--- /dev/null
+From stable+bounces-250010-greg=kroah.com@vger.kernel.org Wed May 20 17:24:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 11:18:17 -0400
+Subject: spi: sifive: Simplify clock handling with devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Pei Xiao <xiaopei01@kylinos.cn>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520151818.3912903-1-sashal@kernel.org>
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit 140039c23aca067b9ff0242e3c0ce96276bb95f3 ]
+
+Replace devm_clk_get() followed by clk_prepare_enable() with
+devm_clk_get_enabled() for the bus clock. This reduces boilerplate code
+and error handling, as the managed API automatically disables the clock
+when the device is removed or if probe fails.
+
+Remove the now-unnecessary clk_disable_unprepare() calls from the probe
+error path and the remove callback. Adjust the error handling to use the
+existing put_host label.
+
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Link: https://patch.msgid.link/73d0d8ecb4e1af5a558d6a7866c0f886d94fe3d1.1773885292.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0f25236694a2 ("spi: sifive: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sifive.c | 21 ++++++---------------
+ 1 file changed, 6 insertions(+), 15 deletions(-)
+
+--- a/drivers/spi/spi-sifive.c
++++ b/drivers/spi/spi-sifive.c
+@@ -312,7 +312,8 @@ static int sifive_spi_probe(struct platf
+ goto put_host;
+ }
+
+- spi->clk = devm_clk_get(&pdev->dev, NULL);
++ /* Spin up the bus clock before hitting registers */
++ spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(spi->clk)) {
+ dev_err(&pdev->dev, "Unable to find bus clock\n");
+ ret = PTR_ERR(spi->clk);
+@@ -342,13 +343,6 @@ static int sifive_spi_probe(struct platf
+ goto put_host;
+ }
+
+- /* Spin up the bus clock before hitting registers */
+- ret = clk_prepare_enable(spi->clk);
+- if (ret) {
+- dev_err(&pdev->dev, "Unable to enable bus clock\n");
+- goto put_host;
+- }
+-
+ /* probe the number of CS lines */
+ spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
+ sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU);
+@@ -357,14 +351,14 @@ static int sifive_spi_probe(struct platf
+ if (!cs_bits) {
+ dev_err(&pdev->dev, "Could not auto probe CS lines\n");
+ ret = -EINVAL;
+- goto disable_clk;
++ goto put_host;
+ }
+
+ num_cs = ilog2(cs_bits) + 1;
+ if (num_cs > SIFIVE_SPI_MAX_CS) {
+ dev_err(&pdev->dev, "Invalid number of spi targets\n");
+ ret = -EINVAL;
+- goto disable_clk;
++ goto put_host;
+ }
+
+ /* Define our host */
+@@ -393,7 +387,7 @@ static int sifive_spi_probe(struct platf
+ dev_name(&pdev->dev), spi);
+ if (ret) {
+ dev_err(&pdev->dev, "Unable to bind to interrupt\n");
+- goto disable_clk;
++ goto put_host;
+ }
+
+ dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
+@@ -402,13 +396,11 @@ static int sifive_spi_probe(struct platf
+ ret = devm_spi_register_controller(&pdev->dev, host);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "spi_register_host failed\n");
+- goto disable_clk;
++ goto put_host;
+ }
+
+ return 0;
+
+-disable_clk:
+- clk_disable_unprepare(spi->clk);
+ put_host:
+ spi_controller_put(host);
+
+@@ -422,7 +414,6 @@ static void sifive_spi_remove(struct pla
+
+ /* Disable all the interrupts just in case */
+ sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
+- clk_disable_unprepare(spi->clk);
+ }
+
+ static int sifive_spi_suspend(struct device *dev)
--- /dev/null
+From stable+bounces-249911-greg=kroah.com@vger.kernel.org Wed May 20 15:01:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 08:55:48 -0400
+Subject: spi: st-ssc4: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Lee Jones <lee@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520125548.3536474-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 19857374010d06ca6a2f7c2c53464122eb804df0 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: 9e862375c542 ("spi: Add new driver for STMicroelectronics' SPI Controller")
+Cc: stable@vger.kernel.org # 4.0
+Cc: Lee Jones <lee@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-18-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-st-ssc4.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-st-ssc4.c
++++ b/drivers/spi/spi-st-ssc4.c
+@@ -349,7 +349,7 @@ static int spi_st_probe(struct platform_
+
+ platform_set_drvdata(pdev, host);
+
+- ret = devm_spi_register_controller(&pdev->dev, host);
++ ret = spi_register_controller(host);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register host\n");
+ goto rpm_disable;
+@@ -371,10 +371,16 @@ static void spi_st_remove(struct platfor
+ struct spi_controller *host = platform_get_drvdata(pdev);
+ struct spi_st *spi_st = spi_controller_get_devdata(host);
+
++ spi_controller_get(host);
++
++ spi_unregister_controller(host);
++
+ pm_runtime_disable(&pdev->dev);
+
+ clk_disable_unprepare(spi_st->clk);
+
++ spi_controller_put(host);
++
+ pinctrl_pm_select_sleep_state(&pdev->dev);
+ }
+
--- /dev/null
+From stable+bounces-249910-greg=kroah.com@vger.kernel.org Wed May 20 15:01:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 08:55:47 -0400
+Subject: spi: st-ssc4: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520125548.3536474-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e6b7e64cb11966b26646a362677ca5a08481157e ]
+
+Change legacy name master/slave to modern name host/target or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-4-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 19857374010d ("spi: st-ssc4: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-st-ssc4.c | 70 +++++++++++++++++++++++-----------------------
+ 1 file changed, 35 insertions(+), 35 deletions(-)
+
+--- a/drivers/spi/spi-st-ssc4.c
++++ b/drivers/spi/spi-st-ssc4.c
+@@ -6,7 +6,7 @@
+ * Patrice Chotard <patrice.chotard@st.com>
+ * Lee Jones <lee.jones@linaro.org>
+ *
+- * SPI master mode controller driver, used in STMicroelectronics devices.
++ * SPI host mode controller driver, used in STMicroelectronics devices.
+ */
+
+ #include <linux/clk.h>
+@@ -115,10 +115,10 @@ static void ssc_read_rx_fifo(struct spi_
+ spi_st->words_remaining -= count;
+ }
+
+-static int spi_st_transfer_one(struct spi_master *master,
++static int spi_st_transfer_one(struct spi_controller *host,
+ struct spi_device *spi, struct spi_transfer *t)
+ {
+- struct spi_st *spi_st = spi_master_get_devdata(master);
++ struct spi_st *spi_st = spi_controller_get_devdata(host);
+ uint32_t ctl = 0;
+
+ /* Setup transfer */
+@@ -165,7 +165,7 @@ static int spi_st_transfer_one(struct sp
+ if (ctl)
+ writel_relaxed(ctl, spi_st->base + SSC_CTL);
+
+- spi_finalize_current_transfer(spi->master);
++ spi_finalize_current_transfer(spi->controller);
+
+ return t->len;
+ }
+@@ -174,7 +174,7 @@ static int spi_st_transfer_one(struct sp
+ #define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH)
+ static int spi_st_setup(struct spi_device *spi)
+ {
+- struct spi_st *spi_st = spi_master_get_devdata(spi->master);
++ struct spi_st *spi_st = spi_controller_get_devdata(spi->controller);
+ u32 spi_st_clk, sscbrg, var;
+ u32 hz = spi->max_speed_hz;
+
+@@ -274,35 +274,35 @@ static irqreturn_t spi_st_irq(int irq, v
+ static int spi_st_probe(struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+- struct spi_master *master;
++ struct spi_controller *host;
+ struct spi_st *spi_st;
+ int irq, ret = 0;
+ u32 var;
+
+- master = spi_alloc_master(&pdev->dev, sizeof(*spi_st));
+- if (!master)
++ host = spi_alloc_host(&pdev->dev, sizeof(*spi_st));
++ if (!host)
+ return -ENOMEM;
+
+- master->dev.of_node = np;
+- master->mode_bits = MODEBITS;
+- master->setup = spi_st_setup;
+- master->transfer_one = spi_st_transfer_one;
+- master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+- master->auto_runtime_pm = true;
+- master->bus_num = pdev->id;
+- master->use_gpio_descriptors = true;
+- spi_st = spi_master_get_devdata(master);
++ host->dev.of_node = np;
++ host->mode_bits = MODEBITS;
++ host->setup = spi_st_setup;
++ host->transfer_one = spi_st_transfer_one;
++ host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
++ host->auto_runtime_pm = true;
++ host->bus_num = pdev->id;
++ host->use_gpio_descriptors = true;
++ spi_st = spi_controller_get_devdata(host);
+
+ spi_st->clk = devm_clk_get(&pdev->dev, "ssc");
+ if (IS_ERR(spi_st->clk)) {
+ dev_err(&pdev->dev, "Unable to request clock\n");
+ ret = PTR_ERR(spi_st->clk);
+- goto put_master;
++ goto put_host;
+ }
+
+ ret = clk_prepare_enable(spi_st->clk);
+ if (ret)
+- goto put_master;
++ goto put_host;
+
+ init_completion(&spi_st->done);
+
+@@ -324,7 +324,7 @@ static int spi_st_probe(struct platform_
+ var &= ~SSC_CTL_SR;
+ writel_relaxed(var, spi_st->base + SSC_CTL);
+
+- /* Set SSC into slave mode before reconfiguring PIO pins */
++ /* Set SSC into target mode before reconfiguring PIO pins */
+ var = readl_relaxed(spi_st->base + SSC_CTL);
+ var &= ~SSC_CTL_MS;
+ writel_relaxed(var, spi_st->base + SSC_CTL);
+@@ -347,11 +347,11 @@ static int spi_st_probe(struct platform_
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+- platform_set_drvdata(pdev, master);
++ platform_set_drvdata(pdev, host);
+
+- ret = devm_spi_register_master(&pdev->dev, master);
++ ret = devm_spi_register_controller(&pdev->dev, host);
+ if (ret) {
+- dev_err(&pdev->dev, "Failed to register master\n");
++ dev_err(&pdev->dev, "Failed to register host\n");
+ goto rpm_disable;
+ }
+
+@@ -361,15 +361,15 @@ rpm_disable:
+ pm_runtime_disable(&pdev->dev);
+ clk_disable:
+ clk_disable_unprepare(spi_st->clk);
+-put_master:
+- spi_master_put(master);
++put_host:
++ spi_controller_put(host);
+ return ret;
+ }
+
+ static void spi_st_remove(struct platform_device *pdev)
+ {
+- struct spi_master *master = platform_get_drvdata(pdev);
+- struct spi_st *spi_st = spi_master_get_devdata(master);
++ struct spi_controller *host = platform_get_drvdata(pdev);
++ struct spi_st *spi_st = spi_controller_get_devdata(host);
+
+ pm_runtime_disable(&pdev->dev);
+
+@@ -381,8 +381,8 @@ static void spi_st_remove(struct platfor
+ #ifdef CONFIG_PM
+ static int spi_st_runtime_suspend(struct device *dev)
+ {
+- struct spi_master *master = dev_get_drvdata(dev);
+- struct spi_st *spi_st = spi_master_get_devdata(master);
++ struct spi_controller *host = dev_get_drvdata(dev);
++ struct spi_st *spi_st = spi_controller_get_devdata(host);
+
+ writel_relaxed(0, spi_st->base + SSC_IEN);
+ pinctrl_pm_select_sleep_state(dev);
+@@ -394,8 +394,8 @@ static int spi_st_runtime_suspend(struct
+
+ static int spi_st_runtime_resume(struct device *dev)
+ {
+- struct spi_master *master = dev_get_drvdata(dev);
+- struct spi_st *spi_st = spi_master_get_devdata(master);
++ struct spi_controller *host = dev_get_drvdata(dev);
++ struct spi_st *spi_st = spi_controller_get_devdata(host);
+ int ret;
+
+ ret = clk_prepare_enable(spi_st->clk);
+@@ -408,10 +408,10 @@ static int spi_st_runtime_resume(struct
+ #ifdef CONFIG_PM_SLEEP
+ static int spi_st_suspend(struct device *dev)
+ {
+- struct spi_master *master = dev_get_drvdata(dev);
++ struct spi_controller *host = dev_get_drvdata(dev);
+ int ret;
+
+- ret = spi_master_suspend(master);
++ ret = spi_controller_suspend(host);
+ if (ret)
+ return ret;
+
+@@ -420,10 +420,10 @@ static int spi_st_suspend(struct device
+
+ static int spi_st_resume(struct device *dev)
+ {
+- struct spi_master *master = dev_get_drvdata(dev);
++ struct spi_controller *host = dev_get_drvdata(dev);
+ int ret;
+
+- ret = spi_master_resume(master);
++ ret = spi_controller_resume(host);
+ if (ret)
+ return ret;
+