* [PATCH] ksmbd: support FileIdAllExtdBothDirectoryInformation
@ 2026-10-17 1:19 Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdExtdDirectoryInformation Namjae Jeon
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Namjae Jeon @ 2026-10-17 1:19 UTC (permalink / raw)
To: linux-cifs
Cc: senozhatsky, tom, atteh.mailbox, chenxiaosong, chenxiaosong,
Namjae Jeon
Windows SMB clients can request FileIdAllExtdBothDirectoryInformation
(0x51) when enumerating a directory. ksmbd does not implement this
format, requiring the client to retry with an older information class.
Add the packed FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION wire layout from
MS-FSCC section 2.4.20 and support it throughout directory entry
reservation, name retrieval and response encoding. Include the
reparse tag separately from EaSize and retain the file attributes
when marking special files as reparse points.
Use the inode number for the 64-bit file ID, as for existing directory
classes. Set the 128-bit ID to zero because the VFS stat data does not
provide one, as required by MS-FSCC. Return no short name and zero
reserved fields and alignment padding.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/smb2pdu.c | 51 ++++++++++++++++++++++++++++++++++++++
fs/smb/server/smb_common.h | 22 ++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 07e2ef56848e..4d0ced8e1f94 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5444,6 +5444,8 @@ static int readdir_info_level_struct_sz(int info_level)
return sizeof(FILE_ID_FULL_DIR_INFO);
case FILEID_BOTH_DIRECTORY_INFORMATION:
return sizeof(struct file_id_both_directory_info);
+ case FileIdAllExtdBothDirectoryInformation:
+ return sizeof(struct file_id_all_extd_both_directory_info);
case SMB_FIND_FILE_POSIX_INFO:
return sizeof(struct smb2_posix_info);
default:
@@ -5514,6 +5516,16 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
d_info->name_len = le32_to_cpu(fibdinfo->FileNameLength);
return 0;
}
+ case FileIdAllExtdBothDirectoryInformation:
+ {
+ struct file_id_all_extd_both_directory_info *info;
+
+ info = (struct file_id_all_extd_both_directory_info *)d_info->rptr;
+ d_info->rptr += le32_to_cpu(info->NextEntryOffset);
+ d_info->name = info->FileName;
+ d_info->name_len = le32_to_cpu(info->FileNameLength);
+ return 0;
+ }
case SMB_FIND_FILE_POSIX_INFO:
{
struct smb2_posix_info *posix_info;
@@ -5751,6 +5763,33 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileIdAllExtdBothDirectoryInformation:
+ {
+ struct file_id_all_extd_both_directory_info *info;
+
+ info = (struct file_id_all_extd_both_directory_info *)kstat;
+ info->FileNameLength = cpu_to_le32(conv_len);
+ info->EaSize = 0;
+ info->ReparsePointTag =
+ smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
+ if (info->ReparsePointTag)
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT_LE;
+ if (conn->is_aapl)
+ info->FileId = 0;
+ else
+ info->FileId = cpu_to_le64(ksmbd_kstat->kstat->ino);
+ /* The VFS does not provide a 128-bit file ID. */
+ memset(info->FileId128, 0, sizeof(info->FileId128));
+ info->ShortNameLength = 0;
+ info->Reserved1 = 0;
+ memset(info->ShortName, 0, sizeof(info->ShortName));
+ if (d_info->hide_dot_file && d_info->name[0] == '.')
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
+ memcpy(info->FileName, conv_name, conv_len);
+ memset(info->FileName + conv_len, 0, d_info->last_entry_off_align);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case SMB_FIND_FILE_POSIX_INFO:
{
struct smb2_posix_info *posix_info;
@@ -5997,6 +6036,17 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileIdAllExtdBothDirectoryInformation:
+ {
+ struct file_id_all_extd_both_directory_info *info;
+
+ info = (struct file_id_all_extd_both_directory_info *)d_info->wptr;
+ memcpy(info->FileName, d_info->name, d_info->name_len);
+ info->FileName[d_info->name_len] = 0x00;
+ info->FileNameLength = cpu_to_le32(d_info->name_len);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case SMB_FIND_FILE_POSIX_INFO:
{
struct smb2_posix_info *posix_info;
@@ -6058,6 +6108,7 @@ static int verify_info_level(int info_level)
case FILEID_FULL_DIRECTORY_INFORMATION:
case FILEID_BOTH_DIRECTORY_INFORMATION:
case SMB_FIND_FILE_POSIX_INFO:
+ case FileIdAllExtdBothDirectoryInformation:
break;
default:
return -EOPNOTSUPP;
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 7b9c5cfcb63b..6ccfdee3ab19 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -133,6 +133,28 @@ struct file_id_both_directory_info {
char FileName[];
} __packed;
+/* MS-FSCC 2.4.20 FileIdAllExtdBothDirectoryInformation */
+struct file_id_all_extd_both_directory_info {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize;
+ __le32 ReparsePointTag;
+ __le64 FileId;
+ __u8 FileId128[16];
+ __u8 ShortNameLength;
+ __u8 Reserved1;
+ __u8 ShortName[24];
+ char FileName[];
+} __packed;
+
struct smb_version_ops {
u16 (*get_cmd_val)(struct ksmbd_work *swork);
void (*inc_reqs)(unsigned int cmd, __le32 status);
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] ksmbd: support FileIdExtdDirectoryInformation
2026-10-17 1:19 [PATCH] ksmbd: support FileIdAllExtdBothDirectoryInformation Namjae Jeon
@ 2026-10-17 1:19 ` Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileId64ExtdDirectoryInformation Namjae Jeon
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2026-10-17 1:19 UTC (permalink / raw)
To: linux-cifs
Cc: senozhatsky, tom, atteh.mailbox, chenxiaosong, chenxiaosong,
Namjae Jeon
Handle FileIdExtdDirectoryInformation (0x3c) in SMB2 QUERY_DIRECTORY.
Add the packed wire layout specified by MS-FSCC 2.4.23 and support
this class in entry reservation, filename lookup and response encoding.
Return reparse tags separately from the EA size and set the reparse flag
without changing other file attributes. Zero the 128-bit file ID because
the VFS provides only a 64-bit inode number, as permitted by the
specification, and initialize entry padding.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/smb2pdu.c | 44 ++++++++++++++++++++++++++++++++++++++
fs/smb/server/smb_common.h | 18 ++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 4d0ced8e1f94..e1e884f62f2b 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5444,6 +5444,8 @@ static int readdir_info_level_struct_sz(int info_level)
return sizeof(FILE_ID_FULL_DIR_INFO);
case FILEID_BOTH_DIRECTORY_INFORMATION:
return sizeof(struct file_id_both_directory_info);
+ case FILE_ID_EXTD_DIRECTORY_INFORMATION:
+ return sizeof(struct file_id_extd_directory_info);
case FileIdAllExtdBothDirectoryInformation:
return sizeof(struct file_id_all_extd_both_directory_info);
case SMB_FIND_FILE_POSIX_INFO:
@@ -5516,6 +5518,16 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
d_info->name_len = le32_to_cpu(fibdinfo->FileNameLength);
return 0;
}
+ case FILE_ID_EXTD_DIRECTORY_INFORMATION:
+ {
+ struct file_id_extd_directory_info *info;
+
+ info = (struct file_id_extd_directory_info *)d_info->rptr;
+ d_info->rptr += le32_to_cpu(info->NextEntryOffset);
+ d_info->name = info->FileName;
+ d_info->name_len = le32_to_cpu(info->FileNameLength);
+ return 0;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -5763,6 +5775,26 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FILE_ID_EXTD_DIRECTORY_INFORMATION:
+ {
+ struct file_id_extd_directory_info *info;
+
+ info = (struct file_id_extd_directory_info *)kstat;
+ info->FileNameLength = cpu_to_le32(conv_len);
+ info->EaSize = 0;
+ info->ReparsePointTag =
+ smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
+ if (info->ReparsePointTag)
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT_LE;
+ /* The VFS does not provide a 128-bit file ID. */
+ memset(info->FileId, 0, sizeof(info->FileId));
+ if (d_info->hide_dot_file && d_info->name[0] == '.')
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
+ memcpy(info->FileName, conv_name, conv_len);
+ memset(info->FileName + conv_len, 0, d_info->last_entry_off_align);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6036,6 +6068,17 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FILE_ID_EXTD_DIRECTORY_INFORMATION:
+ {
+ struct file_id_extd_directory_info *info;
+
+ info = (struct file_id_extd_directory_info *)d_info->wptr;
+ memcpy(info->FileName, d_info->name, d_info->name_len);
+ info->FileName[d_info->name_len] = 0x00;
+ info->FileNameLength = cpu_to_le32(d_info->name_len);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6108,6 +6151,7 @@ static int verify_info_level(int info_level)
case FILEID_FULL_DIRECTORY_INFORMATION:
case FILEID_BOTH_DIRECTORY_INFORMATION:
case SMB_FIND_FILE_POSIX_INFO:
+ case FILE_ID_EXTD_DIRECTORY_INFORMATION:
case FileIdAllExtdBothDirectoryInformation:
break;
default:
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 6ccfdee3ab19..458255684f6c 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -133,6 +133,24 @@ struct file_id_both_directory_info {
char FileName[];
} __packed;
+/* MS-FSCC 2.4.23 FileIdExtdDirectoryInformation */
+struct file_id_extd_directory_info {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize;
+ __le32 ReparsePointTag;
+ __u8 FileId[16];
+ char FileName[];
+} __packed;
+
/* MS-FSCC 2.4.20 FileIdAllExtdBothDirectoryInformation */
struct file_id_all_extd_both_directory_info {
__le32 NextEntryOffset;
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] ksmbd: support FileId64ExtdDirectoryInformation
2026-10-17 1:19 [PATCH] ksmbd: support FileIdAllExtdBothDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdExtdDirectoryInformation Namjae Jeon
@ 2026-10-17 1:19 ` Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileId64ExtdBothDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdAllExtdDirectoryInformation Namjae Jeon
3 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2026-10-17 1:19 UTC (permalink / raw)
To: linux-cifs
Cc: senozhatsky, tom, atteh.mailbox, chenxiaosong, chenxiaosong,
Namjae Jeon
Handle FileId64ExtdDirectoryInformation (0x4e) in SMB2 QUERY_DIRECTORY.
Add the packed wire layout specified by MS-FSCC 2.4.19 and support
this class in entry reservation, filename lookup and response encoding.
Use the VFS inode number for the 64-bit file ID and retain the existing
Apple extension behavior of returning a zero ID. Report reparse tags
separately from the EA size, set the reparse flag without changing other
file attributes, and initialize entry padding.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/smb2pdu.c | 46 ++++++++++++++++++++++++++++++++++++++
fs/smb/server/smb_common.h | 18 +++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index e1e884f62f2b..13fc73e38f55 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5446,6 +5446,8 @@ static int readdir_info_level_struct_sz(int info_level)
return sizeof(struct file_id_both_directory_info);
case FILE_ID_EXTD_DIRECTORY_INFORMATION:
return sizeof(struct file_id_extd_directory_info);
+ case FileId64ExtdDirectoryInformation:
+ return sizeof(struct file_id_64_extd_directory_info);
case FileIdAllExtdBothDirectoryInformation:
return sizeof(struct file_id_all_extd_both_directory_info);
case SMB_FIND_FILE_POSIX_INFO:
@@ -5528,6 +5530,16 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
d_info->name_len = le32_to_cpu(info->FileNameLength);
return 0;
}
+ case FileId64ExtdDirectoryInformation:
+ {
+ struct file_id_64_extd_directory_info *info;
+
+ info = (struct file_id_64_extd_directory_info *)d_info->rptr;
+ d_info->rptr += le32_to_cpu(info->NextEntryOffset);
+ d_info->name = info->FileName;
+ d_info->name_len = le32_to_cpu(info->FileNameLength);
+ return 0;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -5795,6 +5807,28 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
info->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileId64ExtdDirectoryInformation:
+ {
+ struct file_id_64_extd_directory_info *info;
+
+ info = (struct file_id_64_extd_directory_info *)kstat;
+ info->FileNameLength = cpu_to_le32(conv_len);
+ info->EaSize = 0;
+ info->ReparsePointTag =
+ smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
+ if (info->ReparsePointTag)
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT_LE;
+ if (conn->is_aapl)
+ info->FileId = 0;
+ else
+ info->FileId = cpu_to_le64(ksmbd_kstat->kstat->ino);
+ if (d_info->hide_dot_file && d_info->name[0] == '.')
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
+ memcpy(info->FileName, conv_name, conv_len);
+ memset(info->FileName + conv_len, 0, d_info->last_entry_off_align);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6079,6 +6113,17 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
info->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileId64ExtdDirectoryInformation:
+ {
+ struct file_id_64_extd_directory_info *info;
+
+ info = (struct file_id_64_extd_directory_info *)d_info->wptr;
+ memcpy(info->FileName, d_info->name, d_info->name_len);
+ info->FileName[d_info->name_len] = 0x00;
+ info->FileNameLength = cpu_to_le32(d_info->name_len);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6152,6 +6197,7 @@ static int verify_info_level(int info_level)
case FILEID_BOTH_DIRECTORY_INFORMATION:
case SMB_FIND_FILE_POSIX_INFO:
case FILE_ID_EXTD_DIRECTORY_INFORMATION:
+ case FileId64ExtdDirectoryInformation:
case FileIdAllExtdBothDirectoryInformation:
break;
default:
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 458255684f6c..bfd0122d972c 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -151,6 +151,24 @@ struct file_id_extd_directory_info {
char FileName[];
} __packed;
+/* MS-FSCC 2.4.19 FileId64ExtdDirectoryInformation */
+struct file_id_64_extd_directory_info {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize;
+ __le32 ReparsePointTag;
+ __le64 FileId;
+ char FileName[];
+} __packed;
+
/* MS-FSCC 2.4.20 FileIdAllExtdBothDirectoryInformation */
struct file_id_all_extd_both_directory_info {
__le32 NextEntryOffset;
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] ksmbd: support FileId64ExtdBothDirectoryInformation
2026-10-17 1:19 [PATCH] ksmbd: support FileIdAllExtdBothDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdExtdDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileId64ExtdDirectoryInformation Namjae Jeon
@ 2026-10-17 1:19 ` Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdAllExtdDirectoryInformation Namjae Jeon
3 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2026-10-17 1:19 UTC (permalink / raw)
To: linux-cifs
Cc: senozhatsky, tom, atteh.mailbox, chenxiaosong, chenxiaosong,
Namjae Jeon
Handle FileId64ExtdBothDirectoryInformation (0x4f) in SMB2 QUERY_DIRECTORY.
Add the packed wire layout specified by MS-FSCC 2.4.18 and support
this class in entry reservation, filename lookup and response encoding.
Use the VFS inode number for the 64-bit file ID and retain the existing
Apple extension behavior of returning a zero ID. Return an empty short
name and zero its storage and the reserved byte. Report reparse tags
separately from the EA size, set the reparse flag without changing other
file attributes, and initialize entry padding.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/smb2pdu.c | 49 ++++++++++++++++++++++++++++++++++++++
fs/smb/server/smb_common.h | 21 ++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 13fc73e38f55..2c0378d306a8 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5448,6 +5448,8 @@ static int readdir_info_level_struct_sz(int info_level)
return sizeof(struct file_id_extd_directory_info);
case FileId64ExtdDirectoryInformation:
return sizeof(struct file_id_64_extd_directory_info);
+ case FileId64ExtdBothDirectoryInformation:
+ return sizeof(struct file_id_64_extd_both_directory_info);
case FileIdAllExtdBothDirectoryInformation:
return sizeof(struct file_id_all_extd_both_directory_info);
case SMB_FIND_FILE_POSIX_INFO:
@@ -5540,6 +5542,16 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
d_info->name_len = le32_to_cpu(info->FileNameLength);
return 0;
}
+ case FileId64ExtdBothDirectoryInformation:
+ {
+ struct file_id_64_extd_both_directory_info *info;
+
+ info = (struct file_id_64_extd_both_directory_info *)d_info->rptr;
+ d_info->rptr += le32_to_cpu(info->NextEntryOffset);
+ d_info->name = info->FileName;
+ d_info->name_len = le32_to_cpu(info->FileNameLength);
+ return 0;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -5829,6 +5841,31 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
info->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileId64ExtdBothDirectoryInformation:
+ {
+ struct file_id_64_extd_both_directory_info *info;
+
+ info = (struct file_id_64_extd_both_directory_info *)kstat;
+ info->FileNameLength = cpu_to_le32(conv_len);
+ info->EaSize = 0;
+ info->ReparsePointTag =
+ smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
+ if (info->ReparsePointTag)
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT_LE;
+ if (conn->is_aapl)
+ info->FileId = 0;
+ else
+ info->FileId = cpu_to_le64(ksmbd_kstat->kstat->ino);
+ info->ShortNameLength = 0;
+ info->Reserved1 = 0;
+ memset(info->ShortName, 0, sizeof(info->ShortName));
+ if (d_info->hide_dot_file && d_info->name[0] == '.')
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
+ memcpy(info->FileName, conv_name, conv_len);
+ memset(info->FileName + conv_len, 0, d_info->last_entry_off_align);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6124,6 +6161,17 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
info->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileId64ExtdBothDirectoryInformation:
+ {
+ struct file_id_64_extd_both_directory_info *info;
+
+ info = (struct file_id_64_extd_both_directory_info *)d_info->wptr;
+ memcpy(info->FileName, d_info->name, d_info->name_len);
+ info->FileName[d_info->name_len] = 0x00;
+ info->FileNameLength = cpu_to_le32(d_info->name_len);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6198,6 +6246,7 @@ static int verify_info_level(int info_level)
case SMB_FIND_FILE_POSIX_INFO:
case FILE_ID_EXTD_DIRECTORY_INFORMATION:
case FileId64ExtdDirectoryInformation:
+ case FileId64ExtdBothDirectoryInformation:
case FileIdAllExtdBothDirectoryInformation:
break;
default:
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index bfd0122d972c..571b0e9e35d2 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -169,6 +169,27 @@ struct file_id_64_extd_directory_info {
char FileName[];
} __packed;
+/* MS-FSCC 2.4.18 FileId64ExtdBothDirectoryInformation */
+struct file_id_64_extd_both_directory_info {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize;
+ __le32 ReparsePointTag;
+ __le64 FileId;
+ __u8 ShortNameLength;
+ __u8 Reserved1;
+ __u8 ShortName[24];
+ char FileName[];
+} __packed;
+
/* MS-FSCC 2.4.20 FileIdAllExtdBothDirectoryInformation */
struct file_id_all_extd_both_directory_info {
__le32 NextEntryOffset;
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] ksmbd: support FileIdAllExtdDirectoryInformation
2026-10-17 1:19 [PATCH] ksmbd: support FileIdAllExtdBothDirectoryInformation Namjae Jeon
` (2 preceding siblings ...)
2026-10-17 1:19 ` [PATCH] ksmbd: support FileId64ExtdBothDirectoryInformation Namjae Jeon
@ 2026-10-17 1:19 ` Namjae Jeon
3 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2026-10-17 1:19 UTC (permalink / raw)
To: linux-cifs
Cc: senozhatsky, tom, atteh.mailbox, chenxiaosong, chenxiaosong,
Namjae Jeon
Handle FileIdAllExtdDirectoryInformation (0x50) in SMB2 QUERY_DIRECTORY.
Add the packed wire layout specified by MS-FSCC 2.4.21 and support
this class in entry reservation, filename lookup and response encoding.
Use the VFS inode number for the 64-bit file ID and retain the existing
Apple extension behavior of returning a zero ID. Zero the 128-bit file
ID because the VFS provides only a 64-bit inode number, as permitted by
the specification. Report reparse tags separately from the EA size, set
the reparse flag without changing other file attributes, and initialize
entry padding.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/smb2pdu.c | 48 ++++++++++++++++++++++++++++++++++++++
fs/smb/server/smb_common.h | 19 +++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 2c0378d306a8..32fd06171cdd 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5450,6 +5450,8 @@ static int readdir_info_level_struct_sz(int info_level)
return sizeof(struct file_id_64_extd_directory_info);
case FileId64ExtdBothDirectoryInformation:
return sizeof(struct file_id_64_extd_both_directory_info);
+ case FileIdAllExtdDirectoryInformation:
+ return sizeof(struct file_id_all_extd_directory_info);
case FileIdAllExtdBothDirectoryInformation:
return sizeof(struct file_id_all_extd_both_directory_info);
case SMB_FIND_FILE_POSIX_INFO:
@@ -5552,6 +5554,16 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
d_info->name_len = le32_to_cpu(info->FileNameLength);
return 0;
}
+ case FileIdAllExtdDirectoryInformation:
+ {
+ struct file_id_all_extd_directory_info *info;
+
+ info = (struct file_id_all_extd_directory_info *)d_info->rptr;
+ d_info->rptr += le32_to_cpu(info->NextEntryOffset);
+ d_info->name = info->FileName;
+ d_info->name_len = le32_to_cpu(info->FileNameLength);
+ return 0;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -5866,6 +5878,30 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
info->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileIdAllExtdDirectoryInformation:
+ {
+ struct file_id_all_extd_directory_info *info;
+
+ info = (struct file_id_all_extd_directory_info *)kstat;
+ info->FileNameLength = cpu_to_le32(conv_len);
+ info->EaSize = 0;
+ info->ReparsePointTag =
+ smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
+ if (info->ReparsePointTag)
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT_LE;
+ if (conn->is_aapl)
+ info->FileId = 0;
+ else
+ info->FileId = cpu_to_le64(ksmbd_kstat->kstat->ino);
+ /* The VFS does not provide a 128-bit file ID. */
+ memset(info->FileId128, 0, sizeof(info->FileId128));
+ if (d_info->hide_dot_file && d_info->name[0] == '.')
+ info->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
+ memcpy(info->FileName, conv_name, conv_len);
+ memset(info->FileName + conv_len, 0, d_info->last_entry_off_align);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6172,6 +6208,17 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
info->NextEntryOffset = cpu_to_le32(next_entry_offset);
break;
}
+ case FileIdAllExtdDirectoryInformation:
+ {
+ struct file_id_all_extd_directory_info *info;
+
+ info = (struct file_id_all_extd_directory_info *)d_info->wptr;
+ memcpy(info->FileName, d_info->name, d_info->name_len);
+ info->FileName[d_info->name_len] = 0x00;
+ info->FileNameLength = cpu_to_le32(d_info->name_len);
+ info->NextEntryOffset = cpu_to_le32(next_entry_offset);
+ break;
+ }
case FileIdAllExtdBothDirectoryInformation:
{
struct file_id_all_extd_both_directory_info *info;
@@ -6247,6 +6294,7 @@ static int verify_info_level(int info_level)
case FILE_ID_EXTD_DIRECTORY_INFORMATION:
case FileId64ExtdDirectoryInformation:
case FileId64ExtdBothDirectoryInformation:
+ case FileIdAllExtdDirectoryInformation:
case FileIdAllExtdBothDirectoryInformation:
break;
default:
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 571b0e9e35d2..a9cc09e31721 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -190,6 +190,25 @@ struct file_id_64_extd_both_directory_info {
char FileName[];
} __packed;
+/* MS-FSCC 2.4.21 FileIdAllExtdDirectoryInformation */
+struct file_id_all_extd_directory_info {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize;
+ __le32 ReparsePointTag;
+ __le64 FileId;
+ __u8 FileId128[16];
+ char FileName[];
+} __packed;
+
/* MS-FSCC 2.4.20 FileIdAllExtdBothDirectoryInformation */
struct file_id_all_extd_both_directory_info {
__le32 NextEntryOffset;
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-17 1:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-17 1:19 [PATCH] ksmbd: support FileIdAllExtdBothDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdExtdDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileId64ExtdDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileId64ExtdBothDirectoryInformation Namjae Jeon
2026-10-17 1:19 ` [PATCH] ksmbd: support FileIdAllExtdDirectoryInformation Namjae Jeon
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.