提交 eb378711 编写于 作者: P Pavel Shilovsky 提交者: Pavel Shilovsky

CIFS: Move protocol specific part from cifs_readv_receive to ops struct

Acked-by: NShirish Pargaonkar <shirishpargaonkar@gmail.com>
Reviewed-by: NJeff Layton <jlayton@redhat.com>
Signed-off-by: NPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: NSteve French <sfrench@us.ibm.com>
上级 1887f601
...@@ -169,6 +169,12 @@ struct smb_version_operations { ...@@ -169,6 +169,12 @@ struct smb_version_operations {
/* check response: verify signature, map error */ /* check response: verify signature, map error */
int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
bool); 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 { struct smb_version_values {
...@@ -179,6 +185,7 @@ struct smb_version_values { ...@@ -179,6 +185,7 @@ struct smb_version_values {
__u32 unlock_lock_type; __u32 unlock_lock_type;
size_t header_size; size_t header_size;
size_t max_header_size; size_t max_header_size;
size_t read_rsp_size;
}; };
#define HEADER_SIZE(server) (server->vals->header_size) #define HEADER_SIZE(server) (server->vals->header_size)
......
...@@ -1411,27 +1411,6 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1411,27 +1411,6 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
return 0; 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 static int
cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{ {
...@@ -1449,7 +1428,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1449,7 +1428,7 @@ 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 * can if there's not enough data. At this point, we've read down to
* the Mid. * 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; HEADER_SIZE(server) + 1;
rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1; rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1;
...@@ -1461,7 +1440,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1461,7 +1440,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
server->total_read += length; server->total_read += length;
/* Was the SMB read successful? */ /* 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) { if (rdata->result != 0) {
cFYI(1, "%s: server returned error %d", __func__, cFYI(1, "%s: server returned error %d", __func__,
rdata->result); rdata->result);
...@@ -1469,14 +1448,15 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1469,14 +1448,15 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
} }
/* Is there enough to get to the rest of the READ_RSP header? */ /* 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", 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; rdata->result = -EIO;
return cifs_readv_discard(server, mid); 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) { if (data_offset < server->total_read) {
/* /*
* win2k8 sometimes sends an offset of 0 when the read * win2k8 sometimes sends an offset of 0 when the read
...@@ -1515,7 +1495,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1515,7 +1495,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
rdata->iov[0].iov_base, rdata->iov[0].iov_len); rdata->iov[0].iov_base, rdata->iov[0].iov_len);
/* how much data is in the response? */ /* 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) { if (data_offset + data_len > buflen) {
/* data_len is corrupt -- discard frame */ /* data_len is corrupt -- discard frame */
rdata->result = -EIO; rdata->result = -EIO;
......
...@@ -66,11 +66,29 @@ cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2) ...@@ -66,11 +66,29 @@ cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
return ob1->netfid == ob2->netfid; 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 = { struct smb_version_operations smb1_operations = {
.send_cancel = send_nt_cancel, .send_cancel = send_nt_cancel,
.compare_fids = cifs_compare_fids, .compare_fids = cifs_compare_fids,
.setup_request = cifs_setup_request, .setup_request = cifs_setup_request,
.check_receive = cifs_check_receive, .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 = { struct smb_version_values smb1_values = {
...@@ -81,4 +99,5 @@ struct smb_version_values smb1_values = { ...@@ -81,4 +99,5 @@ struct smb_version_values smb1_values = {
.unlock_lock_type = 0, .unlock_lock_type = 0,
.header_size = sizeof(struct smb_hdr), .header_size = sizeof(struct smb_hdr),
.max_header_size = MAX_CIFS_HDR_SIZE, .max_header_size = MAX_CIFS_HDR_SIZE,
.read_rsp_size = sizeof(READ_RSP),
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册