Ver código fonte

[PATCH] cifs: handle termination of cifs oplockd kernel thread

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Steve French 20 anos atrás
pai
commit
57337e42f1
4 arquivos alterados com 23 adições e 15 exclusões
  1. 1 0
      fs/cifs/CHANGES
  2. 1 0
      fs/cifs/cifsfs.c
  3. 6 5
      fs/cifs/connect.c
  4. 15 10
      fs/cifs/misc.c

+ 1 - 0
fs/cifs/CHANGES

@@ -1,6 +1,7 @@
 Version 1.34
 Version 1.34
 ------------
 ------------
 Fix error mapping of the TOO_MANY_LINKS (hardlinks) case.
 Fix error mapping of the TOO_MANY_LINKS (hardlinks) case.
+Do not oops if user kills cifs oplock kernel thread.
 
 
 Version 1.33
 Version 1.33
 ------------
 ------------

+ 1 - 0
fs/cifs/cifsfs.c

@@ -835,6 +835,7 @@ static int cifs_oplock_thread(void * dummyarg)
 		}
 		}
 	} while(!signal_pending(current));
 	} while(!signal_pending(current));
 	complete_and_exit (&cifs_oplock_exited, 0);
 	complete_and_exit (&cifs_oplock_exited, 0);
+	oplockThread = NULL;
 }
 }
 
 
 static int __init
 static int __init

+ 6 - 5
fs/cifs/connect.c

@@ -384,7 +384,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 		if(server->tcpStatus == CifsExiting) {
 		if(server->tcpStatus == CifsExiting) {
 			break;
 			break;
 		} else if (server->tcpStatus == CifsNeedReconnect) {
 		} else if (server->tcpStatus == CifsNeedReconnect) {
-			cFYI(1,("Reconnecting after server stopped responding"));
+			cFYI(1,("Reconnect after server stopped responding"));
 			cifs_reconnect(server);
 			cifs_reconnect(server);
 			cFYI(1,("call to reconnect done"));
 			cFYI(1,("call to reconnect done"));
 			csocket = server->ssocket;
 			csocket = server->ssocket;
@@ -396,7 +396,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 			continue;
 			continue;
 		} else if (length <= 0) {
 		} else if (length <= 0) {
 			if(server->tcpStatus == CifsNew) {
 			if(server->tcpStatus == CifsNew) {
-				cFYI(1,("tcp session abended prematurely (after SMBnegprot)"));
+				cFYI(1,("tcp session abend after SMBnegprot"));
 				/* some servers kill the TCP session rather than
 				/* some servers kill the TCP session rather than
 				   returning an SMB negprot error, in which
 				   returning an SMB negprot error, in which
 				   case reconnecting here is not going to help,
 				   case reconnecting here is not going to help,
@@ -407,14 +407,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 				cFYI(1,("cifsd thread killed"));
 				cFYI(1,("cifsd thread killed"));
 				break;
 				break;
 			}
 			}
-			cFYI(1,("Reconnecting after unexpected peek error %d",length));
+			cFYI(1,("Reconnect after unexpected peek error %d",
+				length));
 			cifs_reconnect(server);
 			cifs_reconnect(server);
 			csocket = server->ssocket;
 			csocket = server->ssocket;
 			wake_up(&server->response_q);
 			wake_up(&server->response_q);
 			continue;
 			continue;
 		} else if (length < 4) {
 		} else if (length < 4) {
 			cFYI(1,
 			cFYI(1,
-			    ("Frame less than four bytes received  %d bytes long.",
+			    ("Frame under four bytes received (%d bytes long)",
 			      length));
 			      length));
 			cifs_reconnect(server);
 			cifs_reconnect(server);
 			csocket = server->ssocket;
 			csocket = server->ssocket;
@@ -593,7 +594,7 @@ multi_t2_fnd:
 					smallbuf = NULL;
 					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)) {                          
 			cERROR(1, ("No task to wake, unknown frame rcvd!"));
 			cERROR(1, ("No task to wake, unknown frame rcvd!"));
 			cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
 			cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));

+ 15 - 10
fs/cifs/misc.c

@@ -452,25 +452,30 @@ is_valid_oplock_break(struct smb_hdr *buf)
 			atomic_inc(&tcon->num_oplock_brks);
 			atomic_inc(&tcon->num_oplock_brks);
 #endif
 #endif
 			list_for_each(tmp1,&tcon->openFileList){
 			list_for_each(tmp1,&tcon->openFileList){
-				netfile = list_entry(tmp1,struct cifsFileInfo,tlist);
+				netfile = list_entry(tmp1,struct cifsFileInfo,
+						     tlist);
 				if(pSMB->Fid == netfile->netfid) {
 				if(pSMB->Fid == netfile->netfid) {
 					struct cifsInodeInfo *pCifsInode;
 					struct cifsInodeInfo *pCifsInode;
 					read_unlock(&GlobalSMBSeslock);
 					read_unlock(&GlobalSMBSeslock);
-					cFYI(1,("Matching file id, processing oplock break"));
+					cFYI(1,("file id match, oplock break"));
 					pCifsInode = 
 					pCifsInode = 
 						CIFS_I(netfile->pInode);
 						CIFS_I(netfile->pInode);
 					pCifsInode->clientCanCacheAll = FALSE;
 					pCifsInode->clientCanCacheAll = FALSE;
 					if(pSMB->OplockLevel == 0)
 					if(pSMB->OplockLevel == 0)
-						pCifsInode->clientCanCacheRead = FALSE;
+						pCifsInode->clientCanCacheRead
+							= FALSE;
 					pCifsInode->oplockPending = TRUE;
 					pCifsInode->oplockPending = TRUE;
-					AllocOplockQEntry(netfile->pInode, netfile->netfid, tcon);
+					AllocOplockQEntry(netfile->pInode,
+							  netfile->netfid,
+							  tcon);
 					cFYI(1,("about to wake up oplock thd"));
 					cFYI(1,("about to wake up oplock thd"));
-					wake_up_process(oplockThread);               
+					if(oplockThread)
+					    wake_up_process(oplockThread);
 					return TRUE;
 					return TRUE;
 				}
 				}
 			}
 			}
 			read_unlock(&GlobalSMBSeslock);
 			read_unlock(&GlobalSMBSeslock);
-			cFYI(1,("No matching file for oplock break on connection"));
+			cFYI(1,("No matching file for oplock break"));
 			return TRUE;
 			return TRUE;
 		}
 		}
 	}
 	}
@@ -491,7 +496,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
 
 
 	buffer = (unsigned char *) smb_buf;
 	buffer = (unsigned char *) smb_buf;
 	for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
 	for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
-		if (i % 8 == 0) {	/* we have reached the beginning of line  */
+		if (i % 8 == 0) {	/* have reached the beginning of line */
 			printk(KERN_DEBUG "| ");
 			printk(KERN_DEBUG "| ");
 			j = 0;
 			j = 0;
 		}
 		}
@@ -502,7 +507,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
 		else
 		else
 			debug_line[1 + (2 * j)] = '_';
 			debug_line[1 + (2 * j)] = '_';
 
 
-		if (i % 8 == 7) {	/* we have reached end of line, time to print ascii */
+		if (i % 8 == 7) { /* reached end of line, time to print ascii */
 			debug_line[16] = 0;
 			debug_line[16] = 0;
 			printk(" | %s\n", debug_line);
 			printk(" | %s\n", debug_line);
 		}
 		}
@@ -577,7 +582,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
 				}
 				}
 		}
 		}
 		j++;
 		j++;
-		/* check to make sure we do not overrun callers allocated temp buffer */
+		/* make sure we do not overrun callers allocated temp buffer */
 		if(j >= (2 * NAME_MAX))
 		if(j >= (2 * NAME_MAX))
 			break;
 			break;
 	}
 	}
@@ -599,7 +604,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
 	char src_char;
 	char src_char;
 
 
 	if(!mapChars) 
 	if(!mapChars) 
-		return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);	
+		return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
 
 
 	for(i = 0, j = 0; i < maxlen; j++) {
 	for(i = 0, j = 0; i < maxlen; j++) {
 		src_char = source[i];
 		src_char = source[i];