FAILED: patch "[PATCH] ksmbd: look up stream size by exact xattr name" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 10ea20d6584ecdaf2f7505855412a856a88d8934
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110445-either-jimmy-6232@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 10ea20d6584ecdaf2f7505855412a856a88d8934 Mon Sep 17 00:00:00 2001
From: Gael Blivet <[email protected]>
Date: Mon, 14 Sep 2026 01:26:36 +0200
Subject: [PATCH] ksmbd: look up stream size by exact xattr name
get_file_stream_info() walks the xattr list from a single ksmbd_vfs_listxattr() and sizes each stream it finds with ksmbd_vfs_casexattr_len(), which matches with strncasecmp(). Linux xattr names are case-sensitive, so two streams differing only in case report each other's size.
The loop already holds the exact name, so query it directly with ksmbd_vfs_xattr_len(), which is what casexattr_len() calls once its search succeeds. Make it non-static and declare it in vfs.h, and drop the comment above it, which describes a different bug and no longer matches the code.
This also drops a full listing per stream: casexattr_len() runs its own listxattr on every call, so enumerating a file with N xattrs cost N listings instead of one.
fs/smb/server/smb2pdu.c +2 -11
@@ -6948,17 +6948,8 @@ static int get_file_stream_info(struct ksmbd_work *work, streamlen *=2 ;kfree (stream_buf); file_info->StreamNameLength =cpu_to_le32 (streamlen); -/* -* stream_name_len is the byte length of the xattr's *name*, -* not its value -- same class of bug ksmbd_stream_eof() -* (smb2pdu.c) already fixes for EndOfFile/AllocationSize on -* a stream handle; this enumeration path needs the same -* real xattr value length, not the name length reused as a -* size. -*/ - slen =ksmbd_vfs_casexattr_len (file_mnt_idmap (fp->filp), - path->dentry, stream_name, -strlen (stream_name) +1 ); + slen =ksmbd_vfs_xattr_len (file_mnt_idmap (fp->filp), + path->dentry, stream_name); ssize = slen <0 ?0 : (loff_t )slen; file_info->StreamSize =cpu_to_le64 (ssize); file_info->StreamAllocationSize =cpu_to_le64 (ssize);
fs/smb/server/vfs.c +2 -2
@@ -842,8 +842,8 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)return size; } -static ssize_t ksmbd_vfs_xattr_len (const struct mnt_idmap *idmap, -struct dentry *dentry,char *xattr_name) +ssize_t ksmbd_vfs_xattr_len (const struct mnt_idmap *idmap, +struct dentry *dentry,char *xattr_name) {return vfs_getxattr (idmap, dentry, xattr_name,NULL ,0 ); }
fs/smb/server/vfs.h +2 -0
@@ -108,6 +108,8 @@ ssize_t ksmbd_vfs_getxattr(const struct mnt_idmap *idmap,struct dentry *dentry, char *xattr_name, char **xattr_buf); +ssize_t ksmbd_vfs_xattr_len (const struct mnt_idmap *idmap, +struct dentry *dentry,char *xattr_name);ssize_t ksmbd_vfs_getcasexattr (const struct mnt_idmap *idmap,struct dentry *dentry,char *attr_name,int attr_name_len,char **attr_value);
Sasha Levin
maintainerPATCH 1/1 ksmbd: look up stream size by exact xattr name
From: Gael Blivet <[email protected]>
[ Upstream commit 10ea20d6584ecdaf2f7505855412a856a88d8934 ]
get_file_stream_info() walks the xattr list from a single ksmbd_vfs_listxattr() and sizes each stream it finds with ksmbd_vfs_casexattr_len(), which matches with strncasecmp(). Linux xattr names are case-sensitive, so two streams differing only in case report each other's size.
The loop already holds the exact name, so query it directly with ksmbd_vfs_xattr_len(), which is what casexattr_len() calls once its search succeeds. Make it non-static and declare it in vfs.h, and drop the comment above it, which describes a different bug and no longer matches the code.
This also drops a full listing per stream: casexattr_len() runs its own listxattr on every call, so enumerating a file with N xattrs cost N listings instead of one.
--- fs/smb/server/smb2pdu.c | 13 ++----------- fs/smb/server/vfs.c | 4 ++-- fs/smb/server/vfs.h | 2 ++ 3 files changed, 6 insertions(+), 13 deletions(-)
fs/smb/server/smb2pdu.c +2 -11
@@ -5247,17 +5247,8 @@ static int get_file_stream_info(struct ksmbd_work *work, streamlen *=2 ;kfree (stream_buf); file_info->StreamNameLength =cpu_to_le32 (streamlen); -/* -* stream_name_len is the byte length of the xattr's *name*, -* not its value -- same class of bug ksmbd_stream_eof() -* (smb2pdu.c) already fixes for EndOfFile/AllocationSize on -* a stream handle; this enumeration path needs the same -* real xattr value length, not the name length reused as a -* size. -*/ - slen =ksmbd_vfs_casexattr_len (file_mnt_idmap (fp->filp), - path->dentry, stream_name, -strlen (stream_name) +1 ,NULL ); + slen =ksmbd_vfs_xattr_len (file_mnt_idmap (fp->filp), + path->dentry, stream_name); ssize = slen <0 ?0 : (loff_t )slen; file_info->StreamSize =cpu_to_le64 (ssize); file_info->StreamAllocationSize =cpu_to_le64 (ssize);
fs/smb/server/vfs.c +2 -2
@@ -939,8 +939,8 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)return size; } -static ssize_t ksmbd_vfs_xattr_len (struct mnt_idmap *idmap, -struct dentry *dentry,char *xattr_name) +ssize_t ksmbd_vfs_xattr_len (struct mnt_idmap *idmap, +struct dentry *dentry,char *xattr_name) {return vfs_getxattr (idmap, dentry, xattr_name,NULL ,0 ); }
fs/smb/server/vfs.h +2 -0
@@ -106,6 +106,8 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,struct dentry *dentry, char *xattr_name, char **xattr_buf); +ssize_t ksmbd_vfs_xattr_len (struct mnt_idmap *idmap, +struct dentry *dentry,char *xattr_name);ssize_t ksmbd_vfs_casexattr_len (struct mnt_idmap *idmap,struct dentry *dentry,char *attr_name,int attr_name_len,char *actual_name);
Signature · 1 line
2.53.0