ksmbd: support empty snapshot enumeration

FSCTL_SRV_ENUM_SNAPS is currently unimplemented, causing clients to
treat shadow-copy enumeration as unsupported even when the share simply
has no snapshots.

Handle the count-only SRV_SNAPSHOT_ARRAY request and return a valid
empty snapshot list after validating the file handle and minimum output
buffer size. Report a two-byte empty UTF-16 MULTI_SZ array and zero
snapshot counts.

This allows smb2.ioctl.shadow_copy to run without a snapshot backend.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
Namjae Jeon 2026-07-07 00:31:54 +09:00
parent d112661f95
commit d4ef8821fd
3 changed files with 32 additions and 0 deletions

View File

@ -119,6 +119,7 @@
#define FSCTL_SRV_ENUMERATE_SNAPSHOTS 0x00144064
/* Retrieve an opaque file reference for server-side data movement ie copy */
#define FSCTL_SRV_REQUEST_RESUME_KEY 0x00140078
#define FSCTL_SRV_ENUM_SNAPS 0x00144064
#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4
#define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8 /* BB add struct */
#define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC /* BB add struct */

View File

@ -9154,6 +9154,30 @@ int smb2_ioctl(struct ksmbd_work *work)
in_buf_len = le32_to_cpu(req->InputCount);
switch (cnt_code) {
case FSCTL_SRV_ENUM_SNAPS: {
struct srv_snapshot_array *snap_rsp;
struct ksmbd_file *fp;
if (out_buf_len < sizeof(*snap_rsp)) {
ret = -EINVAL;
goto out;
}
fp = ksmbd_lookup_fd_fast(work, id);
if (!fp) {
ret = -ENOENT;
goto out;
}
ksmbd_fd_put(work, fp);
snap_rsp = (struct srv_snapshot_array *)rsp->Buffer;
snap_rsp->NumberOfSnapShots = 0;
snap_rsp->NumberOfSnapShotsReturned = 0;
snap_rsp->SnapShotArraySize = cpu_to_le32(2);
snap_rsp->Reserved = 0;
nbytes = sizeof(*snap_rsp);
break;
}
case FSCTL_DFS_GET_REFERRALS:
case FSCTL_DFS_GET_REFERRALS_EX:
/* Not support DFS yet */

View File

@ -199,6 +199,13 @@ struct smb2_file_stream_info {
char StreamName[];
} __packed;
struct srv_snapshot_array {
__le32 NumberOfSnapShots;
__le32 NumberOfSnapShotsReturned;
__le32 SnapShotArraySize;
__le32 Reserved;
} __packed;
struct smb2_file_standard_info {
__le64 AllocationSize;
__le64 EndOfFile;