Commit 57337e42 authored by Steve French's avatar Steve French Committed by Linus Torvalds

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

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 11aa0149
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
------------ ------------
......
...@@ -835,6 +835,7 @@ static int cifs_oplock_thread(void * dummyarg) ...@@ -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
......
...@@ -384,7 +384,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -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) ...@@ -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) ...@@ -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 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -593,7 +594,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
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));
......
...@@ -452,25 +452,30 @@ is_valid_oplock_break(struct smb_hdr *buf) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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];
......
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