aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2pdu.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:30 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:28 -0400
commitd8e050398d23ef7c019c96200b80d73f4e5cec0c (patch)
tree3ba9c436c4c8c6850ae3e5b1e29b86842ef3dc15 /fs/cifs/smb2pdu.c
parentf9c6e234c3ca64b8d49336908df99948518d6261 (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.c51
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
1332int
1333SMB2_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.