@@ -453,6 +453,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
}
server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
+ /* maxReq must be at least 2, almost all servers set to 50,
+ some old non-MS servers set incorrectly so set to default
+ (otherwise oplock break e.g. would fail */
+ if (server->maxReq < 2)
+ server->maxReq = CIFS_MAX_REQ; /* 50 */
server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
(__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
@@ -560,6 +565,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
/* one byte, so no need to convert this or EncryptionKeyLen from
little endian */
server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
+ /* maxReq must be at least 2, almost all servers set to 50,
+ some old non-MS servers set incorrectly so set to default
+ (otherwise oplock break e.g. would fail */
+ if (server->maxReq < 2)
+ server->maxReq = CIFS_MAX_REQ; /* 50 */
/* probably no need to store and check maxvcs */
server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize),
(__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
@@ -95,7 +95,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
spin_unlock(&GlobalMid_Lock);
server->maxBuf = 0;
- cFYI(1, "Reconnecting tcp session");
+ cERROR(1, "Reconnecting tcp session in flight %d",
atomic_read(&server->inFlight)); /* BB FIXME */
/* before reconnecting the tcp session, mark the smb session (uid)
and the tid bad so they are not used until reconnected */
@@ -264,7 +264,12 @@ static int wait_for_free_request(struct
TCP_Server_Info *server,
spin_lock(&GlobalMid_Lock);
while (1) {
- if (atomic_read(&server->inFlight) >= cifs_max_pending) {
+ /* We must check that don't exceed maxReq but on SMB Negotiate
+ it is not initted yet (maxReq must be at least two) */
+ if ((atomic_read(&server->inFlight) >= cifs_max_pending) ||
+ ((atomic_read(&server->inFlight) >= server->maxReq) &&
+ (server->maxReq > 1))) {
spin_unlock(&GlobalMid_Lock);
#ifdef CONFIG_CIFS_STATS2
atomic_inc(&server->num_waiters);