diff --git a/fs/smb/common/smbfsctl.h b/fs/smb/common/smbfsctl.h index d1fcb46a7cde..b1123b0f768d 100644 --- a/fs/smb/common/smbfsctl.h +++ b/fs/smb/common/smbfsctl.h @@ -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 */ diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 7d1c1d2adc19..9279c02bbdb0 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -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 */ diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h index aa06c8c905f1..eadab043bc40 100644 --- a/fs/smb/server/smb2pdu.h +++ b/fs/smb/server/smb2pdu.h @@ -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;