| From ec678eae746dd25766a61c4095e2b649d3b20b09 Mon Sep 17 00:00:00 2001 |
| From: Pavel Shilovsky <pshilov@microsoft.com> |
| Date: Fri, 18 Jan 2019 15:38:11 -0800 |
| Subject: CIFS: Fix credit calculation for encrypted reads with errors |
| |
| From: Pavel Shilovsky <pshilov@microsoft.com> |
| |
| commit ec678eae746dd25766a61c4095e2b649d3b20b09 upstream. |
| |
| We do need to account for credits received in error responses |
| to read requests on encrypted sessions. |
| |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> |
| Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> |
| Signed-off-by: Steve French <stfrench@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/cifs/smb2ops.c | 24 ++++++++++++++---------- |
| 1 file changed, 14 insertions(+), 10 deletions(-) |
| |
| --- a/fs/cifs/smb2ops.c |
| +++ b/fs/cifs/smb2ops.c |
| @@ -3101,11 +3101,23 @@ handle_read_data(struct TCP_Server_Info |
| server->ops->is_status_pending(buf, server, 0)) |
| return -1; |
| |
| - rdata->result = server->ops->map_error(buf, false); |
| + /* set up first two iov to get credits */ |
| + rdata->iov[0].iov_base = buf; |
| + rdata->iov[0].iov_len = 4; |
| + rdata->iov[1].iov_base = buf + 4; |
| + rdata->iov[1].iov_len = |
| + min_t(unsigned int, buf_len, server->vals->read_rsp_size) - 4; |
| + cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n", |
| + rdata->iov[0].iov_base, rdata->iov[0].iov_len); |
| + cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n", |
| + rdata->iov[1].iov_base, rdata->iov[1].iov_len); |
| + |
| + rdata->result = server->ops->map_error(buf, true); |
| if (rdata->result != 0) { |
| cifs_dbg(FYI, "%s: server returned error %d\n", |
| __func__, rdata->result); |
| - dequeue_mid(mid, rdata->result); |
| + /* normal error on read response */ |
| + dequeue_mid(mid, false); |
| return 0; |
| } |
| |
| @@ -3178,14 +3190,6 @@ handle_read_data(struct TCP_Server_Info |
| return 0; |
| } |
| |
| - /* set up first iov for signature check */ |
| - rdata->iov[0].iov_base = buf; |
| - rdata->iov[0].iov_len = 4; |
| - rdata->iov[1].iov_base = buf + 4; |
| - rdata->iov[1].iov_len = server->vals->read_rsp_size - 4; |
| - cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n", |
| - rdata->iov[0].iov_base, server->vals->read_rsp_size); |
| - |
| length = rdata->copy_into_pages(server, rdata, &iter); |
| |
| kfree(bvec); |