]> Gentwo Git Trees - linux/.git/commit
smb: client: handle unlink(2) of files open by different clients
authorPaulo Alcantara <pc@manguebit.org>
Fri, 19 Sep 2025 17:13:15 +0000 (14:13 -0300)
committerSteve French <stfrench@microsoft.com>
Mon, 22 Sep 2025 00:36:27 +0000 (19:36 -0500)
commit1cf9f2a6a544288516a7b9e883a48eba6246bcf2
tree39ecb232a143972fe190eed5a203dc1b301f2d3f
parent07e27ad16399afcd693be20211b0dfae63e0615f
smb: client: handle unlink(2) of files open by different clients

In order to identify whether a certain file is open by a different
client, start the unlink process by sending a compound request of
CREATE(DELETE_ON_CLOSE) + CLOSE with only FILE_SHARE_DELETE bit set in
smb2_create_req::ShareAccess.  If the file is currently open, then the
server will fail the request with STATUS_SHARING_VIOLATION, in which
case we'll map it to -EBUSY, so __cifs_unlink() will fall back to
silly-rename the file.

This fixes the following case where open(O_CREAT) fails with
-ENOENT (STATUS_DELETE_PENDING) due to file still open by a different
client.

* Before patch

$ mount.cifs //srv/share /mnt/1 -o ...,nosharesock
$ mount.cifs //srv/share /mnt/2 -o ...,nosharesock
$ cd /mnt/1
$ touch foo
$ exec 3<>foo
$ cd /mnt/2
$ rm foo
$ touch foo
touch: cannot touch 'foo': No such file or directory
$ exec 3>&-

* After patch

$ mount.cifs //srv/share /mnt/1 -o ...,nosharesock
$ mount.cifs //srv/share /mnt/2 -o ...,nosharesock
$ cd /mnt/1
$ touch foo
$ exec 3<>foo
$ cd /mnt/2
$ rm foo
$ touch foo
$ exec 3>&-

Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Reviewed-by: David Howells <dhowells@redhat.com>
Cc: Frank Sorenson <sorenson@redhat.com>
Cc: linux-cifs@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smb2inode.c