From: Chuck Lever <[email protected]>

ksmbd hard-codes FILE_CASE_SENSITIVE_SEARCH and
FILE_CASE_PRESERVED_NAMES in FS_ATTRIBUTE_INFORMATION responses,
incorrectly indicating all exports are case-sensitive. This breaks
clients accessing case-insensitive filesystems like exFAT or
ext4/f2fs directories with casefold enabled.

Query actual case behavior via vfs_fileattr_get() and report accurate
attributes to SMB clients. Filesystems without ->fileattr_get continue
reporting default POSIX behavior (case-sensitive, case-preserving).

SMB's FS_ATTRIBUTE_INFORMATION reports per-share attributes from the
share root, not per-file. Shares mixing casefold and non-casefold
directories report the root directory's behavior.

Acked-by: Namjae Jeon <[email protected]>
Signed-off-by: Chuck Lever <[email protected]>
---
 fs/smb/server/smb2pdu.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 2fcd0d4d1fb0..f579093bb418 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -13,6 +13,7 @@
 #include <linux/falloc.h>
 #include <linux/mount.h>
 #include <linux/filelock.h>
+#include <linux/fileattr.h>
 
 #include "glob.h"
 #include "smbfsctl.h"
@@ -5486,16 +5487,28 @@ static int smb2_get_info_filesystem(struct ksmbd_work 
*work,
        case FS_ATTRIBUTE_INFORMATION:
        {
                FILE_SYSTEM_ATTRIBUTE_INFO *info;
+               struct file_kattr fa = {};
                size_t sz;
+               u32 attrs;
+               int err;
 
                info = (FILE_SYSTEM_ATTRIBUTE_INFO *)rsp->Buffer;
-               info->Attributes = cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS |
-                                              FILE_PERSISTENT_ACLS |
-                                              FILE_UNICODE_ON_DISK |
-                                              FILE_CASE_PRESERVED_NAMES |
-                                              FILE_CASE_SENSITIVE_SEARCH |
-                                              FILE_SUPPORTS_BLOCK_REFCOUNTING);
+               attrs = FILE_SUPPORTS_OBJECT_IDS |
+                       FILE_PERSISTENT_ACLS |
+                       FILE_UNICODE_ON_DISK |
+                       FILE_SUPPORTS_BLOCK_REFCOUNTING;
 
+               err = vfs_fileattr_get(path.dentry, &fa);
+               if (err && err != -ENOIOCTLCMD) {
+                       path_put(&path);
+                       return err;
+               }
+               if (!fa.case_insensitive)
+                       attrs |= FILE_CASE_SENSITIVE_SEARCH;
+               if (!fa.case_nonpreserving)
+                       attrs |= FILE_CASE_PRESERVED_NAMES;
+
+               info->Attributes = cpu_to_le32(attrs);
                info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
 
                if (test_share_config_flag(work->tcon->share_conf,
-- 
2.52.0



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to