SMB xfstests generic/004

1 Issue description

When using ksmbd as the server, xfstests generic/004 test case fails.

2 Environment

Please refer to “How to Test SMB”.

3 C reproducer

3.1 test.c

test.c is as follows:

#define _GNU_SOURCE

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
        int fd;

        fd = openat(AT_FDCWD, "/tmp/test", O_RDWR | O_TMPFILE, 0600);
        if (fd < 0) {
                perror("openat");
                return 1;
        }

        printf("File opened successfully with O_TMPFILE, fd=%d\n", fd);

        close(fd);
        return 0;
}

3.2 Test Steps

The test fails when KSMBD is used as the server:

# server 192.168.53.210
mkdir -p /tmp/s_test
systemctl stop smbd.service # debian
systemctl stop smb.service # fedora
systemctl restart ksmbd

# client
mkdir -p /tmp/test
mount -t cifs -o username=root,password=1 //192.168.53.210/test /tmp/test
gcc test.c
echo 3 > /proc/sys/vm/drop_caches
./a.out # report error: No such file or directory

The test succeeds when Samba is used as the server:

# server 192.168.53.210
mkdir -p /tmp/s_test
systemctl stop ksmbd
systemctl start smbd.service # debian
systemctl start smb.service # fedora

# client
mkdir -p /tmp/test
mount -t cifs -o username=root,password=1 //192.168.53.210/test /tmp/test
gcc test.c
echo 3 > /proc/sys/vm/drop_caches
./a.out # File opened successfully with O_TMPFILE, fd=3

4 shell reproducer

The test fails when KSMBD is used as the server:

# server 192.168.53.210
mkdir -p /tmp/s_test
systemctl stop smbd.service # debian
systemctl stop smb.service # fedora
systemctl restart ksmbd

# client
mkdir /tmp/test
mount -t cifs -o username=root,password=1 //192.168.53.210/test /tmp/test
rm -rf /tmp/test/tst-tmpfile-flink
/usr/sbin/xfs_io -i -T -c "pwrite 0 4096" -c "pread 0 4096" -c "flink /tmp/test/tst-tmpfile-flink" /tmp/test # failed
umount /tmp/test

# or run xfstests test case on the client
./check generic/004 # failed

The test succeeds when Samba is used as the server:

# server 192.168.53.210
mkdir -p /tmp/s_test
systemctl stop ksmbd
systemctl start smbd.service # debian
systemctl start smb.service # fedora

# client
mkdir -p /tmp/test
mount -t cifs -o username=root,password=1 //192.168.53.210/test /tmp/test
rm -rf /tmp/test/tst-tmpfile-flink
/usr/sbin/xfs_io -i -T -c "pwrite 0 4096" -c "pread 0 4096" -c "flink /tmp/test/tst-tmpfile-flink" /tmp/test # successful
umount /tmp/test

# or run xfstests test case on the client
./check generic/004 # successful

5 Solution

[PATCH] smb/server: promote S_DEL_ON_CLS to S_DEL_PENDING when close

5.1 Test Results of xfstests

Run generic/004 test case:

./check generic/004

FSTYP         -- cifs
PLATFORM      -- Linux/x86_64 gnu 7.1.0-rc3+ #43 SMP PREEMPT_DYNAMIC Mon May 18 04:12:31 UTC 2026
MKFS_OPTIONS  -- //192.168.53.209/test2
MOUNT_OPTIONS -- -o username=root,password=1 //192.168.53.209/test2 /tmp/test2

generic/004  0s ...  1s
Ran: generic/004
Passed all 1 tests

5.2 Test Results of smbtorture

Run smb2.oplock.doc test case:

smbtorture //192.168.53.209/test3/ -Uroot%1 smb2.oplock.doc

smbtorture 4.25.0pre1-GIT-dcd9bedc4b9
Using seed 1779096561
time: 2026-05-18 09:29:21.074101
test: doc
time: 2026-05-18 09:29:21.074517
open a file with a batch oplock
Set delete on close
2nd open should not break and get DELETE_PENDING
time: 2026-05-18 09:29:21.110553
success: doc