Quellcode durchsuchen

[PATCH] cifs: Handle case of multiple trans2 responses for one SMB request (part 2 of 2)

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Steve French vor 20 Jahren
Ursprung
Commit
cd63499cbe
3 geänderte Dateien mit 23 neuen und 20 gelöschten Zeilen
  1. 2 0
      fs/cifs/CHANGES
  2. 11 11
      fs/cifs/cifssmb.c
  3. 10 9
      fs/cifs/connect.c

+ 2 - 0
fs/cifs/CHANGES

@@ -4,6 +4,8 @@ Fix caching problem, in which readdir of directory containing a file
 which was cached could cause the file's time stamp to be updated
 which was cached could cause the file's time stamp to be updated
 without invalidating the readahead data (so we could get stale
 without invalidating the readahead data (so we could get stale
 file data on the client for that file even as the server copy changed).
 file data on the client for that file even as the server copy changed).
+Cleanup response processing so cifsd can not loop when abnormally
+terminated.
 
 
 
 
 Version 1.32
 Version 1.32

+ 11 - 11
fs/cifs/cifssmb.c

@@ -470,7 +470,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
 		return rc;
 		return rc;
 	} else {
 	} else {
 		smb_buffer_response = smb_buffer; /* BB removeme BB */
 		smb_buffer_response = smb_buffer; /* BB removeme BB */
-    }
+	}
 	rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
 	rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
 			 &length, 0);
 			 &length, 0);
 	if (rc)
 	if (rc)
@@ -2517,9 +2517,6 @@ findFirstRetry:
 			psrch_inf->srch_entries_start = 
 			psrch_inf->srch_entries_start = 
 				(char *) &pSMBr->hdr.Protocol + 
 				(char *) &pSMBr->hdr.Protocol + 
 					le16_to_cpu(pSMBr->t2.DataOffset);
 					le16_to_cpu(pSMBr->t2.DataOffset);
-/* if(le16_to_cpu(pSMBr->t2.DataCount) != le16_to_cpu(pSMBr->t2.TotalDataCount)) {  
-	cERROR(1,("DC: %d TDC: %d",pSMBr->t2.DataCount,pSMBr->t2.TotalDataCount));
-} */ /* BB removeme BB */
 			parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
 			parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
 			       le16_to_cpu(pSMBr->t2.ParameterOffset));
 			       le16_to_cpu(pSMBr->t2.ParameterOffset));
 
 
@@ -2531,7 +2528,6 @@ findFirstRetry:
 			psrch_inf->entries_in_buffer  = le16_to_cpu(parms->SearchCount);
 			psrch_inf->entries_in_buffer  = le16_to_cpu(parms->SearchCount);
 			psrch_inf->index_of_last_entry = 
 			psrch_inf->index_of_last_entry = 
 				psrch_inf->entries_in_buffer;
 				psrch_inf->entries_in_buffer;
-/*cFYI(1,("entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry));  */ /* BB removeme BB */
 			*pnetfid = parms->SearchHandle;
 			*pnetfid = parms->SearchHandle;
 		} else {
 		} else {
 			cifs_buf_release(pSMB);
 			cifs_buf_release(pSMB);
@@ -3451,11 +3447,13 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
 
 
 	cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
 	cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
 			(long long)size));
 			(long long)size));
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
+	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
+
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
 
 
+	pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
+
 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
     
     
@@ -3515,7 +3513,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
 	}
 	}
 
 
 	if (pSMB)
 	if (pSMB)
-		cifs_buf_release(pSMB);
+		cifs_small_buf_release(pSMB);
 
 
 	/* Note: On -EAGAIN error only caller can retry on handle based calls 
 	/* Note: On -EAGAIN error only caller can retry on handle based calls 
 		since file handle passed in no longer valid */
 		since file handle passed in no longer valid */
@@ -3541,11 +3539,13 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
 	__u16 params, param_offset, offset, byte_count, count;
 	__u16 params, param_offset, offset, byte_count, count;
 
 
 	cFYI(1, ("Set Times (via SetFileInfo)"));
 	cFYI(1, ("Set Times (via SetFileInfo)"));
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
+	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
+
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
 
 
+	pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
+
 	/* At this point there is no need to override the current pid
 	/* At this point there is no need to override the current pid
 	with the pid of the opener, but that could change if we someday
 	with the pid of the opener, but that could change if we someday
 	use an existing handle (rather than opening one on the fly) */
 	use an existing handle (rather than opening one on the fly) */
@@ -3591,7 +3591,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
 		cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc));
 		cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc));
 	}
 	}
 
 
-	cifs_buf_release(pSMB);
+	cifs_small_buf_release(pSMB);
 
 
 	/* Note: On -EAGAIN error only caller can retry on handle based calls 
 	/* Note: On -EAGAIN error only caller can retry on handle based calls 
 		since file handle passed in no longer valid */
 		since file handle passed in no longer valid */

+ 10 - 9
fs/cifs/connect.c

@@ -544,15 +544,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 			if ((mid_entry->mid == smb_buffer->Mid) && 
 			if ((mid_entry->mid == smb_buffer->Mid) && 
 			    (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
 			    (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
 			    (mid_entry->command == smb_buffer->Command)) {
 			    (mid_entry->command == smb_buffer->Command)) {
-				cFYI(1,("Found Mid 0x%x wake", mid_entry->mid));
-					
 				if(check2ndT2(smb_buffer,server->maxBuf) > 0) {
 				if(check2ndT2(smb_buffer,server->maxBuf) > 0) {
 					/* We have a multipart transact2 resp */
 					/* We have a multipart transact2 resp */
+					isMultiRsp = TRUE;
 					if(mid_entry->resp_buf) {
 					if(mid_entry->resp_buf) {
 						/* merge response - fix up 1st*/
 						/* merge response - fix up 1st*/
 						if(coalesce_t2(smb_buffer, 
 						if(coalesce_t2(smb_buffer, 
 							mid_entry->resp_buf)) {
 							mid_entry->resp_buf)) {
-							isMultiRsp = TRUE;
 							break;
 							break;
 						} else {
 						} else {
 							/* all parts received */
 							/* all parts received */
@@ -564,10 +562,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 					/* BB maybe we can fix this up,  switch
 					/* BB maybe we can fix this up,  switch
 				   	   to already allocated large buffer? */
 				   	   to already allocated large buffer? */
 						} else {
 						} else {
+							/* Have first buffer */
 							mid_entry->resp_buf =
 							mid_entry->resp_buf =
 								 smb_buffer;
 								 smb_buffer;
 							mid_entry->largeBuf = 1;
 							mid_entry->largeBuf = 1;
-							isMultiRsp = TRUE;
 							bigbuf = NULL;
 							bigbuf = NULL;
 						}
 						}
 					}
 					}
@@ -586,11 +584,14 @@ multi_t2_fnd:
 		}
 		}
 		spin_unlock(&GlobalMid_Lock);
 		spin_unlock(&GlobalMid_Lock);
 		if (task_to_wake) {
 		if (task_to_wake) {
-			if(isLargeBuf)
-				bigbuf = NULL;
-			else
-				smallbuf = NULL;
-			/* smb buffer freed by user thread when done */
+			/* Was previous buf put in mpx struct for multi-rsp? */
+			if(!isMultiRsp) {
+				/* smb buffer will be freed by user thread */
+				if(isLargeBuf) {
+					bigbuf = NULL;
+				} else
+					smallbuf = NULL;
+			}
 			wake_up_process(task_to_wake);
 			wake_up_process(task_to_wake);
 		} else if ((is_valid_oplock_break(smb_buffer) == FALSE) 
 		} else if ((is_valid_oplock_break(smb_buffer) == FALSE) 
 		    && (isMultiRsp == FALSE)) {                          
 		    && (isMultiRsp == FALSE)) {