aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2012-05-17 05:02:51 -0400
committerPavel Shilovsky <pshilovsky@samba.org>2012-05-23 04:33:09 -0400
commiteb37871118abfc30629ee2bef11013eddb42c756 (patch)
tree9ee1a048ccda5ce06e626af41a2eb83cbba6fce9 /fs/cifs
parent1887f60103aaeeeb7a3fbf3b366d626043873164 (diff)
CIFS: Move protocol specific part from cifs_readv_receive to ops struct
Acked-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsglob.h7
-rw-r--r--fs/cifs/cifssmb.c34
-rw-r--r--fs/cifs/smb1ops.c19
3 files changed, 33 insertions, 27 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 9ee832d29ec7..825140170b1e 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -169,6 +169,12 @@ struct smb_version_operations {
169 /* check response: verify signature, map error */ 169 /* check response: verify signature, map error */
170 int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, 170 int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
171 bool); 171 bool);
172 /* data offset from read response message */
173 unsigned int (*read_data_offset)(char *);
174 /* data length from read response message */
175 unsigned int (*read_data_length)(char *);
176 /* map smb to linux error */
177 int (*map_error)(char *, bool);
172}; 178};
173 179
174struct smb_version_values { 180struct smb_version_values {
@@ -179,6 +185,7 @@ struct smb_version_values {
179 __u32 unlock_lock_type; 185 __u32 unlock_lock_type;
180 size_t header_size; 186 size_t header_size;
181 size_t max_header_size; 187 size_t max_header_size;
188 size_t read_rsp_size;
182}; 189};
183 190
184#define HEADER_SIZE(server) (server->vals->header_size) 191#define HEADER_SIZE(server) (server->vals->header_size)
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 77463f701f01..b1f375135f48 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1411,27 +1411,6 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1411 return 0; 1411 return 0;
1412} 1412}
1413 1413
1414static inline size_t
1415read_rsp_size(void)
1416{
1417 return sizeof(READ_RSP);
1418}
1419
1420static inline unsigned int
1421read_data_offset(char *buf)
1422{
1423 READ_RSP *rsp = (READ_RSP *)buf;
1424 return le16_to_cpu(rsp->DataOffset);
1425}
1426
1427static inline unsigned int
1428read_data_length(char *buf)
1429{
1430 READ_RSP *rsp = (READ_RSP *)buf;
1431 return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
1432 le16_to_cpu(rsp->DataLength);
1433}
1434
1435static int 1414static int
1436cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1415cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1437{ 1416{
@@ -1449,7 +1428,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1449 * can if there's not enough data. At this point, we've read down to 1428 * can if there's not enough data. At this point, we've read down to
1450 * the Mid. 1429 * the Mid.
1451 */ 1430 */
1452 len = min_t(unsigned int, buflen, read_rsp_size()) - 1431 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1453 HEADER_SIZE(server) + 1; 1432 HEADER_SIZE(server) + 1;
1454 1433
1455 rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1; 1434 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 server->total_read += length; 1440 server->total_read += length;
1462 1441
1463 /* Was the SMB read successful? */ 1442 /* Was the SMB read successful? */
1464 rdata->result = map_smb_to_linux_error(buf, false); 1443 rdata->result = server->ops->map_error(buf, false);
1465 if (rdata->result != 0) { 1444 if (rdata->result != 0) {
1466 cFYI(1, "%s: server returned error %d", __func__, 1445 cFYI(1, "%s: server returned error %d", __func__,
1467 rdata->result); 1446 rdata->result);
@@ -1469,14 +1448,15 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1469 } 1448 }
1470 1449
1471 /* Is there enough to get to the rest of the READ_RSP header? */ 1450 /* Is there enough to get to the rest of the READ_RSP header? */
1472 if (server->total_read < read_rsp_size()) { 1451 if (server->total_read < server->vals->read_rsp_size) {
1473 cFYI(1, "%s: server returned short header. got=%u expected=%zu", 1452 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1474 __func__, server->total_read, read_rsp_size()); 1453 __func__, server->total_read,
1454 server->vals->read_rsp_size);
1475 rdata->result = -EIO; 1455 rdata->result = -EIO;
1476 return cifs_readv_discard(server, mid); 1456 return cifs_readv_discard(server, mid);
1477 } 1457 }
1478 1458
1479 data_offset = read_data_offset(buf) + 4; 1459 data_offset = server->ops->read_data_offset(buf) + 4;
1480 if (data_offset < server->total_read) { 1460 if (data_offset < server->total_read) {
1481 /* 1461 /*
1482 * win2k8 sometimes sends an offset of 0 when the read 1462 * 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 rdata->iov[0].iov_base, rdata->iov[0].iov_len); 1495 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1516 1496
1517 /* how much data is in the response? */ 1497 /* how much data is in the response? */
1518 data_len = read_data_length(buf); 1498 data_len = server->ops->read_data_length(buf);
1519 if (data_offset + data_len > buflen) { 1499 if (data_offset + data_len > buflen) {
1520 /* data_len is corrupt -- discard frame */ 1500 /* data_len is corrupt -- discard frame */
1521 rdata->result = -EIO; 1501 rdata->result = -EIO;
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 3668e81a9d81..daa2edec391e 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -66,11 +66,29 @@ cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
66 return ob1->netfid == ob2->netfid; 66 return ob1->netfid == ob2->netfid;
67} 67}
68 68
69static unsigned int
70cifs_read_data_offset(char *buf)
71{
72 READ_RSP *rsp = (READ_RSP *)buf;
73 return le16_to_cpu(rsp->DataOffset);
74}
75
76static unsigned int
77cifs_read_data_length(char *buf)
78{
79 READ_RSP *rsp = (READ_RSP *)buf;
80 return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
81 le16_to_cpu(rsp->DataLength);
82}
83
69struct smb_version_operations smb1_operations = { 84struct smb_version_operations smb1_operations = {
70 .send_cancel = send_nt_cancel, 85 .send_cancel = send_nt_cancel,
71 .compare_fids = cifs_compare_fids, 86 .compare_fids = cifs_compare_fids,
72 .setup_request = cifs_setup_request, 87 .setup_request = cifs_setup_request,
73 .check_receive = cifs_check_receive, 88 .check_receive = cifs_check_receive,
89 .read_data_offset = cifs_read_data_offset,
90 .read_data_length = cifs_read_data_length,
91 .map_error = map_smb_to_linux_error,
74}; 92};
75 93
76struct smb_version_values smb1_values = { 94struct smb_version_values smb1_values = {
@@ -81,4 +99,5 @@ struct smb_version_values smb1_values = {
81 .unlock_lock_type = 0, 99 .unlock_lock_type = 0,
82 .header_size = sizeof(struct smb_hdr), 100 .header_size = sizeof(struct smb_hdr),
83 .max_header_size = MAX_CIFS_HDR_SIZE, 101 .max_header_size = MAX_CIFS_HDR_SIZE,
102 .read_rsp_size = sizeof(READ_RSP),
84}; 103};