/* check response: verify signature, map error */
int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
bool);
+ /* data offset from read response message */
+ unsigned int (*read_data_offset)(char *);
+ /* data length from read response message */
+ unsigned int (*read_data_length)(char *);
+ /* map smb to linux error */
+ int (*map_error)(char *, bool);
};
struct smb_version_values {
__u32 unlock_lock_type;
size_t header_size;
size_t max_header_size;
+ size_t read_rsp_size;
};
#define HEADER_SIZE(server) (server->vals->header_size)
return 0;
}
-static inline size_t
-read_rsp_size(void)
-{
- return sizeof(READ_RSP);
-}
-
-static inline unsigned int
-read_data_offset(char *buf)
-{
- READ_RSP *rsp = (READ_RSP *)buf;
- return le16_to_cpu(rsp->DataOffset);
-}
-
-static inline unsigned int
-read_data_length(char *buf)
-{
- READ_RSP *rsp = (READ_RSP *)buf;
- return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
- le16_to_cpu(rsp->DataLength);
-}
-
static int
cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
* can if there's not enough data. At this point, we've read down to
* the Mid.
*/
- len = min_t(unsigned int, buflen, read_rsp_size()) -
+ len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
HEADER_SIZE(server) + 1;
rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1;
server->total_read += length;
/* Was the SMB read successful? */
- rdata->result = map_smb_to_linux_error(buf, false);
+ rdata->result = server->ops->map_error(buf, false);
if (rdata->result != 0) {
cFYI(1, "%s: server returned error %d", __func__,
rdata->result);
}
/* Is there enough to get to the rest of the READ_RSP header? */
- if (server->total_read < read_rsp_size()) {
+ if (server->total_read < server->vals->read_rsp_size) {
cFYI(1, "%s: server returned short header. got=%u expected=%zu",
- __func__, server->total_read, read_rsp_size());
+ __func__, server->total_read,
+ server->vals->read_rsp_size);
rdata->result = -EIO;
return cifs_readv_discard(server, mid);
}
- data_offset = read_data_offset(buf) + 4;
+ data_offset = server->ops->read_data_offset(buf) + 4;
if (data_offset < server->total_read) {
/*
* win2k8 sometimes sends an offset of 0 when the read
rdata->iov[0].iov_base, rdata->iov[0].iov_len);
/* how much data is in the response? */
- data_len = read_data_length(buf);
+ data_len = server->ops->read_data_length(buf);
if (data_offset + data_len > buflen) {
/* data_len is corrupt -- discard frame */
rdata->result = -EIO;
return ob1->netfid == ob2->netfid;
}
+static unsigned int
+cifs_read_data_offset(char *buf)
+{
+ READ_RSP *rsp = (READ_RSP *)buf;
+ return le16_to_cpu(rsp->DataOffset);
+}
+
+static unsigned int
+cifs_read_data_length(char *buf)
+{
+ READ_RSP *rsp = (READ_RSP *)buf;
+ return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
+ le16_to_cpu(rsp->DataLength);
+}
+
struct smb_version_operations smb1_operations = {
.send_cancel = send_nt_cancel,
.compare_fids = cifs_compare_fids,
.setup_request = cifs_setup_request,
.check_receive = cifs_check_receive,
+ .read_data_offset = cifs_read_data_offset,
+ .read_data_length = cifs_read_data_length,
+ .map_error = map_smb_to_linux_error,
};
struct smb_version_values smb1_values = {
.unlock_lock_type = 0,
.header_size = sizeof(struct smb_hdr),
.max_header_size = MAX_CIFS_HDR_SIZE,
+ .read_rsp_size = sizeof(READ_RSP),
};