[PATCH v2 2/6] ksmbd: synthesize empty AFP_AfpInfo xattr on first probe

"Gaël Blivet-Bailly" <[email protected]>
Newsgroups org.kernel.vger.linux-cifs
Message-ID <[email protected]>
From: Gael Blivet <[email protected]>

Once a server advertises the AAPL COPYFILE capability, macOS requires
an AFP_AfpInfo stream on every file it looks at for Finder type/
creator/icon resolution. smb2_set_stream_name_xattr() currently
returns -EBADF (STATUS_OBJECT_NAME_NOT_FOUND) when a client opens
AFP_AfpInfo with FILE_OPEN disposition and the xattr doesn't exist
yet, which macOS treats as fatal for that file: Finder falls back to
showing a generic icon, and file operations that depend on succeeding
against this stream (e.g. Cmd+D duplication) fail.

Synthesize a 60-byte zeroed AFP_AfpInfo xattr (magic 0x00051607,
version 0x00020000, both big-endian per the AFP_AfpInfo wire format)
on first FILE_OPEN probe instead, matching Samba's vfs_fruit module.
type=0/creator=0 tells macOS to fall back to extension-based type
detection, which is correct for files with no explicit Finder
metadata. The synthesized xattr persists on disk, so this only pays
the extra write once per file; a later genuine write from macOS (e.g.
after the user assigns a custom icon) overwrites it normally.

Signed-off-by: Gael Blivet <[email protected]>
---
 fs/smb/server/smb2pdu.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 9c70e97d8..8fed5fd6d 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2864,6 +2864,30 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path,
 		return 0;
 
 	if (fp->cdoption == FILE_OPEN_LE) {
+		if (!strcmp(stream_name, "AFP_AfpInfo") &&
+		    test_share_config_flag(fp->tcon->share_conf,
+					   KSMBD_SHARE_FLAG_TIME_MACHINE)) {
+			/*
+			 * Synthesize an empty AFP_AfpInfo xattr on first access.
+			 * type=0/creator=0 tells macOS to use the file extension
+			 * for icon and type detection. Matches Samba vfs_fruit.
+			 *
+			 * Scoped to TIME_MACHINE shares, matching the rest of
+			 * the AAPL series -- conn->is_aapl alone isn't a safe
+			 * gate here, since the pre-existing narrow UniqueId=0
+			 * path can also set it on ordinary, non-Time-Machine
+			 * shares whenever a Mac client happens to negotiate
+			 * AAPL there too.
+			 */
+			static const u8 afpinfo_empty[60] = {
+				0x00, 0x05, 0x16, 0x07, /* magic  0x00051607 BE */
+				0x00, 0x02, 0x00, 0x00, /* version 0x00020000 BE */
+			};
+			rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name,
+						(void *)afpinfo_empty,
+						sizeof(afpinfo_empty), 0, false);
+			return rc < 0 ? rc : 0;
+		}
 		ksmbd_debug(SMB, "XATTR stream name lookup failed: %d\n", rc);
 		return -EBADF;
 	}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.