a set of small smb3 fixes, some fixing various crediting issues discovered during xfstest runs, five for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAlxLV8IACgkQiiy9cAdy T1HRIgv/fieDI6HBXAoK9mXzVLJXCZ1IxVZTygC3Xn/bCaxHerS+QSe88w0r1QTZ KLCoT7pBBy06uTowX4/cAF0IYTStsYWngBsH3+HL4EEchkZAVe02wAJ8QOCXs9YU UjoMvNLmcyrzwNt8EduNM2jUUpOL8EHiZOQKUvLt1Vdo3xBtyB3Nkttji92YLOQb Cxs0RJdKNaalMphOQwAtbdbZwlL79KGSA0gMm9W2VD744YKMjQ3uGXaTuoe6+w19 voYKVTSelgyZg51yzF20x1Pl3OV/8L6tWgN1BIcKZbfGBshJhhcD93Pef7bmhxNS Y2yF3SPr/zcdgEkwigVlNs1uBCBBeU04/yQr+YvJwNcjsRTcTKOMuquxq4gXM1P8 7f8gA1u0n1H70YKK29sd3sl7Iu8rHVacwlxjfoAcCjMe0VQvOJtR+V/zwP2uWr8T IjX05unBe/B1v+NXqNdkOpE6ZaiJtt2ny5NDZhfeubOouBLsey7/g/gSx48ICrq+ U20kKsb6 =CCH2 -----END PGP SIGNATURE----- Merge tag '5.0-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull smb3 fixes from Steve French: "A set of small smb3 fixes, some fixing various crediting issues discovered during xfstest runs, five for stable" * tag '5.0-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: print CIFSMaxBufSize as part of /proc/fs/cifs/DebugData smb3: add credits we receive from oplock/break PDUs CIFS: Fix mounts if the client is low on credits CIFS: Do not assume one credit for async responses CIFS: Fix credit calculations in compound mid callback CIFS: Fix credit calculation for encrypted reads with errors CIFS: Fix credits calculations for reads with errors CIFS: Do not reconnect TCP session in add_credits() smb3: Cleanup license mess CIFS: Fix possible hang during async MTU reads and writes cifs: fix memory leak of an allocated cifs_ntsd structure
This commit is contained in:
commit
7c2614bf7a
|
@ -252,6 +252,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
||||||
seq_printf(m, ",ACL");
|
seq_printf(m, ",ACL");
|
||||||
#endif
|
#endif
|
||||||
seq_putc(m, '\n');
|
seq_putc(m, '\n');
|
||||||
|
seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize);
|
||||||
seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
|
seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
|
||||||
seq_printf(m, "Servers:");
|
seq_printf(m, "Servers:");
|
||||||
|
|
||||||
|
|
|
@ -1549,18 +1549,26 @@ cifs_discard_remaining_data(struct TCP_Server_Info *server)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
__cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
||||||
|
bool malformed)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
struct cifs_readdata *rdata = mid->callback_data;
|
|
||||||
|
|
||||||
length = cifs_discard_remaining_data(server);
|
length = cifs_discard_remaining_data(server);
|
||||||
dequeue_mid(mid, rdata->result);
|
dequeue_mid(mid, malformed);
|
||||||
mid->resp_buf = server->smallbuf;
|
mid->resp_buf = server->smallbuf;
|
||||||
server->smallbuf = NULL;
|
server->smallbuf = NULL;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||||
|
{
|
||||||
|
struct cifs_readdata *rdata = mid->callback_data;
|
||||||
|
|
||||||
|
return __cifs_readv_discard(server, mid, rdata->result);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||||
{
|
{
|
||||||
|
@ -1602,12 +1610,23 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set up first two iov for signature check and 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 = server->total_read - 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);
|
||||||
|
|
||||||
/* Was the SMB read successful? */
|
/* Was the SMB read successful? */
|
||||||
rdata->result = server->ops->map_error(buf, false);
|
rdata->result = server->ops->map_error(buf, false);
|
||||||
if (rdata->result != 0) {
|
if (rdata->result != 0) {
|
||||||
cifs_dbg(FYI, "%s: server returned error %d\n",
|
cifs_dbg(FYI, "%s: server returned error %d\n",
|
||||||
__func__, rdata->result);
|
__func__, rdata->result);
|
||||||
return cifs_readv_discard(server, mid);
|
/* normal error on read response */
|
||||||
|
return __cifs_readv_discard(server, mid, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is there enough to get to the rest of the READ_RSP header? */
|
/* Is there enough to get to the rest of the READ_RSP header? */
|
||||||
|
@ -1651,14 +1670,6 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||||
server->total_read += length;
|
server->total_read += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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->total_read - 4;
|
|
||||||
cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
|
|
||||||
rdata->iov[0].iov_base, server->total_read);
|
|
||||||
|
|
||||||
/* how much data is in the response? */
|
/* how much data is in the response? */
|
||||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||||
use_rdma_mr = rdata->mr;
|
use_rdma_mr = rdata->mr;
|
||||||
|
|
|
@ -720,6 +720,21 @@ server_unresponsive(struct TCP_Server_Info *server)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
zero_credits(struct TCP_Server_Info *server)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
|
||||||
|
spin_lock(&server->req_lock);
|
||||||
|
val = server->credits + server->echo_credits + server->oplock_credits;
|
||||||
|
if (server->in_flight == 0 && val == 0) {
|
||||||
|
spin_unlock(&server->req_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
spin_unlock(&server->req_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
|
cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
|
||||||
{
|
{
|
||||||
|
@ -732,6 +747,12 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
|
||||||
for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
|
for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
|
||||||
try_to_freeze();
|
try_to_freeze();
|
||||||
|
|
||||||
|
/* reconnect if no credits and no requests in flight */
|
||||||
|
if (zero_credits(server)) {
|
||||||
|
cifs_reconnect(server);
|
||||||
|
return -ECONNABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (server_unresponsive(server))
|
if (server_unresponsive(server))
|
||||||
return -ECONNABORTED;
|
return -ECONNABORTED;
|
||||||
if (cifs_rdma_enabled(server) && server->smbd_conn)
|
if (cifs_rdma_enabled(server) && server->smbd_conn)
|
||||||
|
|
|
@ -293,6 +293,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
int rc;
|
int rc;
|
||||||
struct smb2_file_all_info *smb2_data;
|
struct smb2_file_all_info *smb2_data;
|
||||||
__u32 create_options = 0;
|
__u32 create_options = 0;
|
||||||
|
struct cifs_fid fid;
|
||||||
|
bool no_cached_open = tcon->nohandlecache;
|
||||||
|
|
||||||
*adjust_tz = false;
|
*adjust_tz = false;
|
||||||
*symlink = false;
|
*symlink = false;
|
||||||
|
@ -301,6 +303,21 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (smb2_data == NULL)
|
if (smb2_data == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* If it is a root and its handle is cached then use it */
|
||||||
|
if (!strlen(full_path) && !no_cached_open) {
|
||||||
|
rc = open_shroot(xid, tcon, &fid);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
rc = SMB2_query_info(xid, tcon, fid.persistent_fid,
|
||||||
|
fid.volatile_fid, smb2_data);
|
||||||
|
close_shroot(&tcon->crfid);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
move_smb2_info_to_cifs(data, smb2_data);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (backup_cred(cifs_sb))
|
if (backup_cred(cifs_sb))
|
||||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||||
|
|
||||||
|
|
|
@ -648,6 +648,13 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
|
||||||
if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
|
if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (rsp->sync_hdr.CreditRequest) {
|
||||||
|
spin_lock(&server->req_lock);
|
||||||
|
server->credits += le16_to_cpu(rsp->sync_hdr.CreditRequest);
|
||||||
|
spin_unlock(&server->req_lock);
|
||||||
|
wake_up(&server->request_q);
|
||||||
|
}
|
||||||
|
|
||||||
if (rsp->StructureSize !=
|
if (rsp->StructureSize !=
|
||||||
smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
|
smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
|
||||||
if (le16_to_cpu(rsp->StructureSize) == 44)
|
if (le16_to_cpu(rsp->StructureSize) == 44)
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "cifs_ioctl.h"
|
#include "cifs_ioctl.h"
|
||||||
#include "smbdirect.h"
|
#include "smbdirect.h"
|
||||||
|
|
||||||
|
/* Change credits for different ops and return the total number of credits */
|
||||||
static int
|
static int
|
||||||
change_conf(struct TCP_Server_Info *server)
|
change_conf(struct TCP_Server_Info *server)
|
||||||
{
|
{
|
||||||
|
@ -41,17 +42,15 @@ change_conf(struct TCP_Server_Info *server)
|
||||||
server->oplock_credits = server->echo_credits = 0;
|
server->oplock_credits = server->echo_credits = 0;
|
||||||
switch (server->credits) {
|
switch (server->credits) {
|
||||||
case 0:
|
case 0:
|
||||||
return -1;
|
return 0;
|
||||||
case 1:
|
case 1:
|
||||||
server->echoes = false;
|
server->echoes = false;
|
||||||
server->oplocks = false;
|
server->oplocks = false;
|
||||||
cifs_dbg(VFS, "disabling echoes and oplocks\n");
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
server->echoes = true;
|
server->echoes = true;
|
||||||
server->oplocks = false;
|
server->oplocks = false;
|
||||||
server->echo_credits = 1;
|
server->echo_credits = 1;
|
||||||
cifs_dbg(FYI, "disabling oplocks\n");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
server->echoes = true;
|
server->echoes = true;
|
||||||
|
@ -64,14 +63,15 @@ change_conf(struct TCP_Server_Info *server)
|
||||||
server->echo_credits = 1;
|
server->echo_credits = 1;
|
||||||
}
|
}
|
||||||
server->credits -= server->echo_credits + server->oplock_credits;
|
server->credits -= server->echo_credits + server->oplock_credits;
|
||||||
return 0;
|
return server->credits + server->echo_credits + server->oplock_credits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
|
smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
|
||||||
const int optype)
|
const int optype)
|
||||||
{
|
{
|
||||||
int *val, rc = 0;
|
int *val, rc = -1;
|
||||||
|
|
||||||
spin_lock(&server->req_lock);
|
spin_lock(&server->req_lock);
|
||||||
val = server->ops->get_credits_field(server, optype);
|
val = server->ops->get_credits_field(server, optype);
|
||||||
|
|
||||||
|
@ -101,8 +101,26 @@ smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
|
||||||
}
|
}
|
||||||
spin_unlock(&server->req_lock);
|
spin_unlock(&server->req_lock);
|
||||||
wake_up(&server->request_q);
|
wake_up(&server->request_q);
|
||||||
if (rc)
|
|
||||||
cifs_reconnect(server);
|
if (server->tcpStatus == CifsNeedReconnect)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (rc) {
|
||||||
|
case -1:
|
||||||
|
/* change_conf hasn't been executed */
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
cifs_dbg(VFS, "Possible client or server bug - zero credits\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cifs_dbg(VFS, "disabling echoes and oplocks\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cifs_dbg(FYI, "disabling oplocks\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cifs_dbg(FYI, "add %u credits total=%d\n", add, rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -136,7 +154,11 @@ smb2_get_credits(struct mid_q_entry *mid)
|
||||||
{
|
{
|
||||||
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf;
|
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf;
|
||||||
|
|
||||||
return le16_to_cpu(shdr->CreditRequest);
|
if (mid->mid_state == MID_RESPONSE_RECEIVED
|
||||||
|
|| mid->mid_state == MID_RESPONSE_MALFORMED)
|
||||||
|
return le16_to_cpu(shdr->CreditRequest);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -165,14 +187,14 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
|
||||||
|
|
||||||
scredits = server->credits;
|
scredits = server->credits;
|
||||||
/* can deadlock with reopen */
|
/* can deadlock with reopen */
|
||||||
if (scredits == 1) {
|
if (scredits <= 8) {
|
||||||
*num = SMB2_MAX_BUFFER_SIZE;
|
*num = SMB2_MAX_BUFFER_SIZE;
|
||||||
*credits = 0;
|
*credits = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* leave one credit for a possible reopen */
|
/* leave some credits for reopen and other ops */
|
||||||
scredits--;
|
scredits -= 8;
|
||||||
*num = min_t(unsigned int, size,
|
*num = min_t(unsigned int, size,
|
||||||
scredits * SMB2_MAX_BUFFER_SIZE);
|
scredits * SMB2_MAX_BUFFER_SIZE);
|
||||||
|
|
||||||
|
@ -3189,11 +3211,23 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
||||||
server->ops->is_status_pending(buf, server, 0))
|
server->ops->is_status_pending(buf, server, 0))
|
||||||
return -1;
|
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) {
|
if (rdata->result != 0) {
|
||||||
cifs_dbg(FYI, "%s: server returned error %d\n",
|
cifs_dbg(FYI, "%s: server returned error %d\n",
|
||||||
__func__, rdata->result);
|
__func__, rdata->result);
|
||||||
dequeue_mid(mid, rdata->result);
|
/* normal error on read response */
|
||||||
|
dequeue_mid(mid, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3266,14 +3300,6 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
||||||
return 0;
|
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);
|
length = rdata->copy_into_pages(server, rdata, &iter);
|
||||||
|
|
||||||
kfree(bvec);
|
kfree(bvec);
|
||||||
|
|
|
@ -2816,6 +2816,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
int resp_buftype = CIFS_NO_BUFFER;
|
int resp_buftype = CIFS_NO_BUFFER;
|
||||||
struct cifs_ses *ses = tcon->ses;
|
struct cifs_ses *ses = tcon->ses;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
bool allocated = false;
|
||||||
|
|
||||||
cifs_dbg(FYI, "Query Info\n");
|
cifs_dbg(FYI, "Query Info\n");
|
||||||
|
|
||||||
|
@ -2855,14 +2856,21 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
"Error %d allocating memory for acl\n",
|
"Error %d allocating memory for acl\n",
|
||||||
rc);
|
rc);
|
||||||
*dlen = 0;
|
*dlen = 0;
|
||||||
|
rc = -ENOMEM;
|
||||||
goto qinf_exit;
|
goto qinf_exit;
|
||||||
}
|
}
|
||||||
|
allocated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = smb2_validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
|
rc = smb2_validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
|
||||||
le32_to_cpu(rsp->OutputBufferLength),
|
le32_to_cpu(rsp->OutputBufferLength),
|
||||||
&rsp_iov, min_len, *data);
|
&rsp_iov, min_len, *data);
|
||||||
|
if (rc && allocated) {
|
||||||
|
kfree(*data);
|
||||||
|
*data = NULL;
|
||||||
|
*dlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
qinf_exit:
|
qinf_exit:
|
||||||
SMB2_query_info_free(&rqst);
|
SMB2_query_info_free(&rqst);
|
||||||
|
@ -2916,9 +2924,10 @@ smb2_echo_callback(struct mid_q_entry *mid)
|
||||||
{
|
{
|
||||||
struct TCP_Server_Info *server = mid->callback_data;
|
struct TCP_Server_Info *server = mid->callback_data;
|
||||||
struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
|
struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
|
||||||
unsigned int credits_received = 1;
|
unsigned int credits_received = 0;
|
||||||
|
|
||||||
if (mid->mid_state == MID_RESPONSE_RECEIVED)
|
if (mid->mid_state == MID_RESPONSE_RECEIVED
|
||||||
|
|| mid->mid_state == MID_RESPONSE_MALFORMED)
|
||||||
credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
|
credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
|
||||||
|
|
||||||
DeleteMidQEntry(mid);
|
DeleteMidQEntry(mid);
|
||||||
|
@ -3175,7 +3184,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
|
||||||
struct TCP_Server_Info *server = tcon->ses->server;
|
struct TCP_Server_Info *server = tcon->ses->server;
|
||||||
struct smb2_sync_hdr *shdr =
|
struct smb2_sync_hdr *shdr =
|
||||||
(struct smb2_sync_hdr *)rdata->iov[0].iov_base;
|
(struct smb2_sync_hdr *)rdata->iov[0].iov_base;
|
||||||
unsigned int credits_received = 1;
|
unsigned int credits_received = 0;
|
||||||
struct smb_rqst rqst = { .rq_iov = rdata->iov,
|
struct smb_rqst rqst = { .rq_iov = rdata->iov,
|
||||||
.rq_nvec = 2,
|
.rq_nvec = 2,
|
||||||
.rq_pages = rdata->pages,
|
.rq_pages = rdata->pages,
|
||||||
|
@ -3214,6 +3223,9 @@ smb2_readv_callback(struct mid_q_entry *mid)
|
||||||
task_io_account_read(rdata->got_bytes);
|
task_io_account_read(rdata->got_bytes);
|
||||||
cifs_stats_bytes_read(tcon, rdata->got_bytes);
|
cifs_stats_bytes_read(tcon, rdata->got_bytes);
|
||||||
break;
|
break;
|
||||||
|
case MID_RESPONSE_MALFORMED:
|
||||||
|
credits_received = le16_to_cpu(shdr->CreditRequest);
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
if (rdata->result != -ENODATA)
|
if (rdata->result != -ENODATA)
|
||||||
rdata->result = -EIO;
|
rdata->result = -EIO;
|
||||||
|
@ -3399,7 +3411,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
|
||||||
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
|
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
|
||||||
unsigned int written;
|
unsigned int written;
|
||||||
struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
|
struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
|
||||||
unsigned int credits_received = 1;
|
unsigned int credits_received = 0;
|
||||||
|
|
||||||
switch (mid->mid_state) {
|
switch (mid->mid_state) {
|
||||||
case MID_RESPONSE_RECEIVED:
|
case MID_RESPONSE_RECEIVED:
|
||||||
|
@ -3427,6 +3439,9 @@ smb2_writev_callback(struct mid_q_entry *mid)
|
||||||
case MID_RETRY_NEEDED:
|
case MID_RETRY_NEEDED:
|
||||||
wdata->result = -EAGAIN;
|
wdata->result = -EAGAIN;
|
||||||
break;
|
break;
|
||||||
|
case MID_RESPONSE_MALFORMED:
|
||||||
|
credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
wdata->result = -EIO;
|
wdata->result = -EIO;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3,16 +3,6 @@
|
||||||
* Copyright (C) 2018, Microsoft Corporation.
|
* Copyright (C) 2018, Microsoft Corporation.
|
||||||
*
|
*
|
||||||
* Author(s): Steve French <stfrench@microsoft.com>
|
* Author(s): Steve French <stfrench@microsoft.com>
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
|
||||||
* the GNU General Public License for more details.
|
|
||||||
*/
|
*/
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
|
@ -3,16 +3,6 @@
|
||||||
* Copyright (C) 2018, Microsoft Corporation.
|
* Copyright (C) 2018, Microsoft Corporation.
|
||||||
*
|
*
|
||||||
* Author(s): Steve French <stfrench@microsoft.com>
|
* Author(s): Steve French <stfrench@microsoft.com>
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
|
||||||
* the GNU General Public License for more details.
|
|
||||||
*/
|
*/
|
||||||
#undef TRACE_SYSTEM
|
#undef TRACE_SYSTEM
|
||||||
#define TRACE_SYSTEM cifs
|
#define TRACE_SYSTEM cifs
|
||||||
|
|
|
@ -786,17 +786,8 @@ static void
|
||||||
cifs_compound_callback(struct mid_q_entry *mid)
|
cifs_compound_callback(struct mid_q_entry *mid)
|
||||||
{
|
{
|
||||||
struct TCP_Server_Info *server = mid->server;
|
struct TCP_Server_Info *server = mid->server;
|
||||||
unsigned int optype = mid->optype;
|
|
||||||
unsigned int credits_received = 0;
|
|
||||||
|
|
||||||
if (mid->mid_state == MID_RESPONSE_RECEIVED) {
|
add_credits(server, server->ops->get_credits(mid), mid->optype);
|
||||||
if (mid->resp_buf)
|
|
||||||
credits_received = server->ops->get_credits(mid);
|
|
||||||
else
|
|
||||||
cifs_dbg(FYI, "Bad state for cancelled MID\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
add_credits(server, credits_received, optype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue