diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:30 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:28 -0400 |
commit | d8e050398d23ef7c019c96200b80d73f4e5cec0c (patch) | |
tree | 3ba9c436c4c8c6850ae3e5b1e29b86842ef3dc15 /fs/cifs/smb2pdu.c | |
parent | f9c6e234c3ca64b8d49336908df99948518d6261 (diff) |
CIFS: Add readpage support for SMB2
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r-- | fs/cifs/smb2pdu.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index cb6acc7b1ca8..23c569386f32 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1329,6 +1329,57 @@ smb2_async_readv(struct cifs_readdata *rdata) | |||
1329 | return rc; | 1329 | return rc; |
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | int | ||
1333 | SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, | ||
1334 | unsigned int *nbytes, char **buf, int *buf_type) | ||
1335 | { | ||
1336 | int resp_buftype, rc = -EACCES; | ||
1337 | struct smb2_read_rsp *rsp = NULL; | ||
1338 | struct kvec iov[1]; | ||
1339 | |||
1340 | *nbytes = 0; | ||
1341 | rc = smb2_new_read_req(iov, io_parms, 0, 0); | ||
1342 | if (rc) | ||
1343 | return rc; | ||
1344 | |||
1345 | rc = SendReceive2(xid, io_parms->tcon->ses, iov, 1, | ||
1346 | &resp_buftype, CIFS_LOG_ERROR); | ||
1347 | |||
1348 | rsp = (struct smb2_read_rsp *)iov[0].iov_base; | ||
1349 | |||
1350 | if (rsp->hdr.Status == STATUS_END_OF_FILE) { | ||
1351 | free_rsp_buf(resp_buftype, iov[0].iov_base); | ||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | if (rc) { | ||
1356 | cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); | ||
1357 | cERROR(1, "Send error in read = %d", rc); | ||
1358 | } else { | ||
1359 | *nbytes = le32_to_cpu(rsp->DataLength); | ||
1360 | if ((*nbytes > CIFS_MAX_MSGSIZE) || | ||
1361 | (*nbytes > io_parms->length)) { | ||
1362 | cFYI(1, "bad length %d for count %d", *nbytes, | ||
1363 | io_parms->length); | ||
1364 | rc = -EIO; | ||
1365 | *nbytes = 0; | ||
1366 | } | ||
1367 | } | ||
1368 | |||
1369 | if (*buf) { | ||
1370 | memcpy(*buf, (char *)rsp->hdr.ProtocolId + rsp->DataOffset, | ||
1371 | *nbytes); | ||
1372 | free_rsp_buf(resp_buftype, iov[0].iov_base); | ||
1373 | } else if (resp_buftype != CIFS_NO_BUFFER) { | ||
1374 | *buf = iov[0].iov_base; | ||
1375 | if (resp_buftype == CIFS_SMALL_BUFFER) | ||
1376 | *buf_type = CIFS_SMALL_BUFFER; | ||
1377 | else if (resp_buftype == CIFS_LARGE_BUFFER) | ||
1378 | *buf_type = CIFS_LARGE_BUFFER; | ||
1379 | } | ||
1380 | return rc; | ||
1381 | } | ||
1382 | |||
1332 | /* | 1383 | /* |
1333 | * Check the mid_state and signature on received buffer (if any), and queue the | 1384 | * Check the mid_state and signature on received buffer (if any), and queue the |
1334 | * workqueue completion task. | 1385 | * workqueue completion task. |