ksmbd: provide zero as a unique ID to the Mac client

[ Upstream commit 571781eb7ffefa65b0e922c8031e42b4411a40d4 ]

The Mac SMB client code seems to expect the on-disk file identifier
to have the semantics of HFS+ Catalog Node Identifier (CNID).
ksmbd provides the inode number as a unique ID to the client,
but in the case of subvolumes of btrfs, there are cases where different
files have the same inode number, so the mac smb client treats it
as an error. There is a report that a similar problem occurs
when the share is ZFS.
Returning UniqueId of zero will make the Mac client to stop using and
trusting the file id returned from the server.

Reported-by: Justin Turner Arthur <justinarthur@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Namjae Jeon
2025-05-21 09:02:29 +09:00
committed by Greg Kroah-Hartman
parent f72093f270
commit efe5db9d98
3 changed files with 21 additions and 2 deletions

View File

@@ -107,6 +107,7 @@ struct ksmbd_conn {
__le16 signing_algorithm; __le16 signing_algorithm;
bool binding; bool binding;
atomic_t refcnt; atomic_t refcnt;
bool is_aapl;
}; };
struct ksmbd_conn_ops { struct ksmbd_conn_ops {

View File

@@ -3527,6 +3527,15 @@ int smb2_open(struct ksmbd_work *work)
ksmbd_debug(SMB, "get query on disk id context\n"); ksmbd_debug(SMB, "get query on disk id context\n");
query_disk_id = 1; query_disk_id = 1;
} }
if (conn->is_aapl == false) {
context = smb2_find_context_vals(req, SMB2_CREATE_AAPL, 4);
if (IS_ERR(context)) {
rc = PTR_ERR(context);
goto err_out1;
} else if (context)
conn->is_aapl = true;
}
} }
rc = ksmbd_vfs_getattr(&path, &stat); rc = ksmbd_vfs_getattr(&path, &stat);
@@ -3965,7 +3974,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
if (dinfo->EaSize) if (dinfo->EaSize)
dinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE; dinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
dinfo->Reserved = 0; dinfo->Reserved = 0;
dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); if (conn->is_aapl)
dinfo->UniqueId = 0;
else
dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
if (d_info->hide_dot_file && d_info->name[0] == '.') if (d_info->hide_dot_file && d_info->name[0] == '.')
dinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE; dinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
memcpy(dinfo->FileName, conv_name, conv_len); memcpy(dinfo->FileName, conv_name, conv_len);
@@ -3982,7 +3994,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode); smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
if (fibdinfo->EaSize) if (fibdinfo->EaSize)
fibdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE; fibdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); if (conn->is_aapl)
fibdinfo->UniqueId = 0;
else
fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
fibdinfo->ShortNameLength = 0; fibdinfo->ShortNameLength = 0;
fibdinfo->Reserved = 0; fibdinfo->Reserved = 0;
fibdinfo->Reserved2 = cpu_to_le16(0); fibdinfo->Reserved2 = cpu_to_le16(0);

View File

@@ -63,6 +63,9 @@ struct preauth_integrity_info {
#define SMB2_SESSION_TIMEOUT (10 * HZ) #define SMB2_SESSION_TIMEOUT (10 * HZ)
/* Apple Defined Contexts */
#define SMB2_CREATE_AAPL "AAPL"
struct create_durable_req_v2 { struct create_durable_req_v2 {
struct create_context_hdr ccontext; struct create_context_hdr ccontext;
__u8 Name[8]; __u8 Name[8];