CIFS: Fix credit calculation for encrypted reads with errors
authorPavel Shilovsky <pshilov@microsoft.com>
Fri, 18 Jan 2019 23:38:11 +0000 (15:38 -0800)
committerSteve French <stfrench@microsoft.com>
Thu, 24 Jan 2019 20:52:05 +0000 (14:52 -0600)
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>
fs/cifs/smb2ops.c

index fa8d2e1076c8a54a31cfd667bbab6f3695c9de90..73f9c6af406531ace78533e878a2159beb3852a2 100644 (file)
@@ -3207,11 +3207,23 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
                        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;
        }
 
@@ -3284,14 +3296,6 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
                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);