smb2.streams.create-disposition and smb2.streams.io fail when the SMB2 handle opened for a stream is properly closed before the next CREATE request on the same file.
This bug was referenced in samba master: 95d27f5e7a293262607feeeec6782f11d47f5579 2fc21d87fc88f094b79701e362372f02da98ce02
Reporting a user-visible impact of this regression on a maintained release branch, and requesting a backport. THE IMPACT IS BROADER THAN THE CURRENT TITLE SUGGESTS The title ("Incorrect behavior on stream create-disposition when prior handle is closed") describes the smb2.streams selftest failures. In the field the same defect produces a much more visible failure: A client cannot overwrite or delete an EXISTING file whose basename matches an entry in the SHARE ROOT directory - anywhere in the tree, at any depth. The operation fails with ENOENT (NT_STATUS_OBJECT_NAME_NOT_FOUND). For a share that exports a source tree this breaks git. .git/config has basename "config", so if the share root happens to contain an entry named "config", "git init" stops after writing 36 bytes: error: could not write config file <path>/.git/config: No such file or directory fatal: could not set 'core.filemode' to 'true' Worse, the failed write leaves .git/config half-written and the damage accumulates until every git command fails with "fatal: bad config line N". commit and push still succeed while only the config write fails (e.g. "push -u" sets up the remote but cannot record the upstream), so it is easy to miss until the repository is already broken. Any tool that saves atomically (write temp + rename over the target) hits the same thing, deterministically, for the affected names. ENVIRONMENT Server: Samba 4.23.6-Ubuntu on Ubuntu 26.04, ext4 Share: vfs objects = catia fruit streams_xattr fruit:metadata = stream fruit:resource = file case sensitive = yes store dos attributes = yes Client: macOS 26.6, SMB 3.1.1 Note that vfs_fruit always reports streams, so the trigger does not require the client to have created any stream of its own. Client-side mount options (nostreams, nomdatacache, nodatacache, nonotification, soft, forcenewsession) make no difference. MINIMAL REPRODUCTION Share root /export contains a directory (or file) named "config". mkdir -p /mnt/share/sub : > /mnt/share/sub/config # create - OK : > /mnt/share/sub/src mv -f /mnt/share/sub/src /mnt/share/sub/config # ENOENT rm /mnt/share/sub/config # ENOENT Using any basename that does not exist in the share root works. The first create succeeds; only replacing or removing the now-existing file fails - which is why it looks like "it works once, then never again". Server log with log level = 10: close.c:181(delete_all_streams) delete_all_streams found 2 streams files.c:512(openat_pathref_fsp): smb_fname [config] files.c:2612(file_name_hash): /export/config hash 0x275a5259 <-- resolved at share root close.c:603(close_remove_share_mode) delete_all_streams failed: NT_STATUS_OBJECT_NAME_NOT_FOUND smb2_close.c:111 -> NT_STATUS_OBJECT_NAME_NOT_FOUND The client receives the failure on CLOSE (it had opened the destination with DELETE_ON_CLOSE to replace it) and never sends the rename at all. ROOT CAUSE - ALREADY FIXED IN MASTER regression: 09f49fb56a4 smbd: Simplify delete_all_streams() 2025-01-23 fix: 2fc21d87 s3:vfs_streams_xattr: Use dirfsp in streams_xattr_unlinkat() 2026-06-16 v4-23-stable still has the handle->conn->cwd_fsp form in streams_xattr_unlinkat(), which matches the observed behaviour exactly: if (fsp == NULL) { status = synthetic_pathref(talloc_tos(), handle->conn->cwd_fsp, /* should be dirfsp */ smb_fname->base_name, ... When <share root>/<basename> happens to exist, the wrong object is opened and FREMOVEXATTR fails; when it does not exist, the pathref fails outright. Either way delete_all_streams() aborts and the close fails. REQUEST Please backport 2fc21d87 to the maintained release branches cut between 2025-01-23 and 2026-06-16. Verified affected here: 4.23.6. This bug already records 4.24.3. I do not have editbugs permission, so could someone please add 4.23.6 to the Version field? Happy to test a candidate build - the failure is 100% deterministic and takes seconds to reproduce.
Created attachment 19168 [details] Patch for 4.23 and 4.24 cherry-picked from master
This bug was referenced in samba v4-23-test: d12320449206ee4ea46b613cfad5a8f7230fae6a 920ba1531fbbe9f33d8ea587741ec7621d774c0e
This bug was referenced in samba v4-24-test: 98692e28453a2efba97c6b7b98feefe43d2e7fc5 9fb2d75d65d0d507077673e20e42ef41dff59c32
This bug was referenced in samba v4-23-stable (Release samba-4.23.12): d12320449206ee4ea46b613cfad5a8f7230fae6a 920ba1531fbbe9f33d8ea587741ec7621d774c0e
This bug was referenced in samba v4-24-stable (Release samba-4.24.7): 98692e28453a2efba97c6b7b98feefe43d2e7fc5 9fb2d75d65d0d507077673e20e42ef41dff59c32