[PATCH 0/4] ksmbd: implement Continuously Available (CA) share support
From: Yunseong Kim
Date: Sun Aug 23 2026 - 20:56:59 EST
Enable the Continuously Available (CA) share infrastructure in ksmbd,
allowing SMB clients to request and use persistent handles on configured shares.
Background
==========
KSMBD already has a complete in-memory durable handle v1/v2
implementation including the persistent handle data model
(fp->is_persistent), protocol parsing (DH2Q with
SMB2_DHANDLE_FLAG_PERSISTENT), and reconnect validation (DH2C). However,
the server never advertises SMB2_GLOBAL_CAP_PERSISTENT_HANDLES or sets
SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY, making this code path unreachable
by clients.
Per MS-SMB2, a client can only request a persistent handle on a share
that advertises SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY. This creates a
chicken-and-egg: we cannot test persistent handles without first
advertising the CA capability.
Implementation Approach
=======================
I chose a top-down approach: enable the CA share capability first,
validate with real clients using Samba smbtorture, and then layer on-disk
state persistence in a follow-up series. This allows us to:
1. Get end-to-end protocol validation immediately with smbtorture
2. Discover client behavioral expectations before building persistence
3. Deliver incremental value (fencing + write-through + disconnect
resilience) before the harder persistence work
Note: at this stage, handles survive connection/session loss but NOT full
server crash. On-disk state persistence and startup recovery will be
addressed in a follow-up series.
Patches
=======
Patch 1: Advertise SMB2_GLOBAL_CAP_PERSISTENT_HANDLES in negotiate
response when durable handles are enabled globally.
Patch 2: Set SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY in tree connect
response for shares with 'continuous availability = yes'.
Patch 3: Add STATUS_FILE_NOT_AVAILABLE fencing: block conflicting
opens from other clients while a persistent handle is in
disconnected state (MS-SMB2 3.3.5.9).
Patch 4: Enforce FILE_WRITE_THROUGH on all opens to CA shares to
ensure data commits to stable storage (MS-SMB2 3.3.5.9).
The corresponding ksmbd-tools patch that adds the 'continuous availability'
share configuration parameter is submitted:
https://github.com/namjaejeon/ksmbd-tools/pull/205
Testing
=======
Build the kernel with debug sanitizers enabled:
$ vng --build --force \
--configitem CONFIG_SMB_SERVER=y \
--configitem CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y \
--configitem CONFIG_SMB_SERVER_KERBEROS5=y \
--configitem CONFIG_CIFS=y \
--configitem CONFIG_CIFS_XATTR=y \
--configitem CONFIG_CIFS_POSIX=y \
--configitem CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y \
--configitem CONFIG_CIFS_DEBUG=y \
--configitem CONFIG_DEBUG_KERNEL=y \
--configitem CONFIG_KASAN=y \
--configitem CONFIG_KASAN_GENERIC=y \
--configitem CONFIG_KASAN_INLINE=y \
--configitem CONFIG_UBSAN=y \
--configitem CONFIG_LOCKDEP=y \
--configitem CONFIG_LOCK_DEBUGGING_SUPPORT=y \
--configitem CONFIG_PROVE_LOCKING=y \
--configitem CONFIG_DEBUG_SPINLOCK=y
Run the CA-specific smbtorture tests inside virtme-ng:
$ vng --memory 4G --exec '
mkdir -p /tmp/ksmbd_share /tmp/ksmbd_ca /tmp/ksmbd_conf
chmod 777 /tmp/ksmbd_share /tmp/ksmbd_ca
useradd -u 4242 -M fuzz 2>/dev/null || true
ksmbd.adduser -C ksmbd-sandbox.config \
-P /tmp/ksmbd_conf/ksmbdpwd.db -a fuzz -p fuzz
ksmbd.mountd -C ksmbd-sandbox.config \
-P /tmp/ksmbd_conf/ksmbdpwd.db -n &
sleep 3
T=/path/to/samba/bin/smbtorture
$T //127.0.0.1/ca_share -U fuzz%fuzz \
smb2.durable-v2-open.persistent-open-oplock
$T //127.0.0.1/ca_share -U fuzz%fuzz \
smb2.durable-v2-open.persistent-open-lease
$T //127.0.0.1/ca_share -U fuzz%fuzz \
smb2.durable-v2-open.reopen1
dmesg | grep -E "BUG:|KASAN:|UBSAN:|WARNING:.*ksmbd"
'
Key smbtorture tests for CA validation:
smb2.durable-v2-open.persistent-open-oplock
- Connects to CA share, verifies SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY
- Opens file with DH2Q + SMB2_DHANDLE_FLAG_PERSISTENT + batch oplock
- Verifies server grants persistent handle (response has flag 0x02)
- Tests various oplock level combinations with persistent flag
smb2.durable-v2-open.persistent-open-lease
- Same as above but with lease (RWH) instead of oplock
- Disconnects TCP, reconnects with DH2C, verifies handle survives
- Tests lease level combinations with persistent flag
smb2.durable-v2-open.reopen1
- Basic durable v2 disconnect/reconnect lifecycle
- Opens file with batch oplock + DH2Q
- Disconnects session, establishes new session
- Reconnects via DH2C with CreateGuid matching
- Verifies file access resumes after reconnect
smb2.durable-v2-open.purge-disconnected-rwh-with-rwh-open
- Tests conflict resolution: a new RWH open from a different client
should purge (close) a disconnected durable handle with RWH lease
- Verifies the server correctly resolves lease conflicts
Results on KASAN/UBSAN/LOCKDEP kernel:
smb2.durable-v2-open.persistent-open-oplock: PASS
smb2.durable-v2-open.persistent-open-lease: PASS
smb2.durable-v2-open.reopen1: PASS
smb2.durable-v2-open.purge-disconnected-rwh-with-rwh-open: PASS
Zero KASAN/UBSAN/lockdep findings
Signed-off-by: Yunseong Kim <yunseong.kim@xxxxxxxx>
---
Yunseong Kim (4):
ksmbd: advertise SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
ksmbd: set SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY in tree connect
ksmbd: add fencing for disconnected persistent handles
ksmbd: enforce write-through on CA share opens
fs/smb/server/smb2ops.c | 10 +++++-----
fs/smb/server/smb2pdu.c | 33 +++++++++++++++++++++++++++++----
fs/smb/server/vfs_cache.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
fs/smb/server/vfs_cache.h | 2 ++
4 files changed, 81 insertions(+), 9 deletions(-)
---
base-commit: 4c6320e0ad400d4ee41cfde614c05a0d87f54e1b
change-id: 20260824-b4-ca-ace9405ce4b0
Best regards,
--
Yunseong Kim <yunseong.kim@xxxxxxxx>