Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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

parent 79944bf7
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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 */
+149 −146
Original line number Diff line number Diff line
@@ -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;