Commit 46810cbf authored by Steve French's avatar Steve French Committed by Linus Torvalds

[PATCH] cifs: Ease memory pressure, do not use large buffers in byte range lock requests.

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 79944bf7
......@@ -1023,11 +1023,13 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
__u16 count;
cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock));
rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,
(void **) &pSMBr);
rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
if (rc)
return rc;
pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
timeout = -1; /* no response expected */
pSMB->Timeout = 0;
......@@ -1065,7 +1067,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
if (rc) {
cFYI(1, ("Send error in Lock = %d", rc));
}
cifs_buf_release(pSMB);
cifs_small_buf_release(pSMB);
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
......
......@@ -294,21 +294,27 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
csocket = server->ssocket;
wake_up(&server->response_q);
continue;
} else if (length > 3) {
} else if (length < 4) {
cFYI(1,
("Frame less than four bytes received %d bytes long.",
length));
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
continue;
}
/* the right amount was read from socket - 4 bytes */
pdu_length = ntohl(smb_buffer->smb_buf_length);
/* Only read pdu_length after below checks for too short (due
to e.g. int overflow) and too long ie beyond end of buf */
cFYI(1,("rfc1002 length(big endian)0x%x)",
pdu_length+4));
cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4));
temp = (char *) smb_buffer;
if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
cFYI(0,("Received 4 byte keep alive packet"));
} else if (temp[0] ==
(char) RFC1002_POSITIVE_SESSION_RESPONSE) {
} else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
cFYI(1,("Good RFC 1002 session rsp"));
} else if (temp[0] ==
(char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
} else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
/* we get this from Windows 98 instead of
an error on SMB negprot response */
cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4]));
......@@ -339,7 +345,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
cifs_reconnect(server);
csocket = server->ssocket;
continue;
} else {
} else { /* we have an SMB response */
if((pdu_length > CIFSMaxBufSize +
MAX_CIFS_HDR_SIZE - 4) ||
(pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
......@@ -351,6 +357,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
wake_up(&server->response_q);
continue;
} else { /* length ok */
int reconnect = 0;
if(pdu_length > MAX_CIFS_HDR_SIZE - 4) {
isLargeBuf = TRUE;
memcpy(bigbuf, smallbuf, 4);
......@@ -368,14 +376,16 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
if((server->tcpStatus == CifsExiting) ||
(length == -EINTR)) {
/* then will exit */
goto dmx_loop_end;
reconnect = 2;
break;
} else if (server->tcpStatus ==
CifsNeedReconnect) {
cifs_reconnect(server);
csocket = server->ssocket;
/* Reconnect wakes up rspns q */
/* Now we will reread sock */
goto dmx_loop_end;
reconnect = 1;
break;
} else if ((length == -ERESTARTSYS) ||
(length == -EAGAIN)) {
msleep(1); /* minimum sleep to prevent looping
......@@ -383,14 +393,19 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
tcpStatus CifsNeedReconnect if server hung */
continue;
} else if (length <= 0) {
cERROR(1,
("Received no data, expecting %d",
cERROR(1,("Received no data, expecting %d",
pdu_length - total_read));
cifs_reconnect(server);
csocket = server->ssocket;
goto dmx_loop_end;
reconnect = 1;
break;
}
}
if(reconnect == 2)
break;
else if(reconnect == 1)
continue;
length += 4; /* account for rfc1002 hdr */
}
......@@ -401,13 +416,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
continue;
}
/* BB FIXME - add checkTrans2SMBSecondary() */
task_to_wake = NULL;
spin_lock(&GlobalMid_Lock);
list_for_each(tmp, &server->pending_mid_q) {
mid_entry = list_entry(tmp, struct
mid_q_entry,
mid_entry = list_entry(tmp, struct mid_q_entry,
qhead);
if ((mid_entry->mid == smb_buffer->Mid)
......@@ -417,6 +430,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
smb_buffer->Command)) {
cFYI(1,("Found Mid 0x%x wake up"
,mid_entry->mid));
/* BB FIXME - missing code here BB */
/* check_2nd_t2(smb_buffer); */
task_to_wake = mid_entry->tsk;
mid_entry->resp_buf =
smb_buffer;
......@@ -441,18 +456,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
}
}
} else {
cFYI(1,
("Frame less than four bytes received %d bytes long.",
length));
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
continue;
}
dmx_loop_end:
cFYI(1,("Exiting cifsd loop"));
}
spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment