Commit bc27a5b4 authored by Steve French's avatar Steve French Committed by Steve French

Fix case where server hung but tcpip session still good. Fix double request of same spinlock

parent 46ae59fe
Version 0.94 Version 0.94
------------ ------------
Fix to list processing in reopen_files. Fix to list processing in reopen_files. Fix reconnection when server hung
but tcpip session still alive.
Version 0.93 Version 0.93
------------ ------------
......
...@@ -595,8 +595,8 @@ static int cifs_oplock_thread(void * dummyarg) ...@@ -595,8 +595,8 @@ static int cifs_oplock_thread(void * dummyarg)
pTcon = oplock_item->tcon; pTcon = oplock_item->tcon;
inode = oplock_item->pinode; inode = oplock_item->pinode;
netfid = oplock_item->netfid; netfid = oplock_item->netfid;
DeleteOplockQEntry(oplock_item);
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
DeleteOplockQEntry(oplock_item);
if (S_ISREG(inode->i_mode)) if (S_ISREG(inode->i_mode))
rc = filemap_fdatawrite(inode->i_mapping); rc = filemap_fdatawrite(inode->i_mapping);
else else
......
...@@ -185,7 +185,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -185,7 +185,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
sizeof (struct smb_hdr) - sizeof (struct smb_hdr) -
1 /* RFC1001 header and SMB header */ , 1 /* RFC1001 header and SMB header */ ,
MSG_PEEK /* flags see socket.h */ ); MSG_PEEK /* flags see socket.h */ );
if (length < 0) { if (server->tcpStatus == CifsNeedReconnect) {
cFYI(1,("Reconnecting after server stopped responding"));
cifs_reconnect(server);
csocket = server->ssocket;
continue;
} else if (length < 0) {
if (length == -ECONNRESET) { if (length == -ECONNRESET) {
cERROR(1, ("Connection reset by peer ")); cERROR(1, ("Connection reset by peer "));
cifs_reconnect(server); cifs_reconnect(server);
...@@ -758,8 +763,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ...@@ -758,8 +763,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
*csocket = NULL; *csocket = NULL;
return rc; return rc;
} else { } else {
/* BB other socket options to set KEEPALIVE, timeouts? NODELAY? */ /* BB other socket options to set KEEPALIVE, NODELAY? */
struct timeval tval;
tval.tv_sec = 10;
cFYI(1,("Socket created")); cFYI(1,("Socket created"));
sock_setsockopt(*csocket, SOL_SOCKET, SO_RCVTIMEO,
(char*)&tval, sizeof(struct timeval));
} }
} }
......
...@@ -219,6 +219,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -219,6 +219,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
pCifsFile->pid = current->tgid; pCifsFile->pid = current->tgid;
pCifsFile->pInode = newinode; pCifsFile->pInode = newinode;
pCifsFile->invalidHandle = FALSE; pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE;
/* pCifsFile->pfile = file; */ /* put in at open time */ /* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList); list_add(&pCifsFile->tlist,&pTcon->openFileList);
......
...@@ -145,6 +145,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -145,6 +145,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile->pfile = file; /* needed for writepage */ pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode; pCifsFile->pInode = inode;
pCifsFile->invalidHandle = FALSE; pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE;
write_lock(&file->f_owner.lock); write_lock(&file->f_owner.lock);
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList); list_add(&pCifsFile->tlist,&pTcon->openFileList);
...@@ -325,7 +326,8 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo) ...@@ -325,7 +326,8 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo)
if(open_file == NULL) { if(open_file == NULL) {
break; break;
} else { } else {
if(open_file->invalidHandle == FALSE) { if((open_file->invalidHandle == FALSE) &&
(open_file->closePend == FALSE)) {
list_move(&open_file->tlist,&pTcon->openFileList); list_move(&open_file->tlist,&pTcon->openFileList);
continue; continue;
} }
...@@ -372,8 +374,17 @@ cifs_close(struct inode *inode, struct file *file) ...@@ -372,8 +374,17 @@ cifs_close(struct inode *inode, struct file *file)
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
if (pSMBFile) { if (pSMBFile) {
pSMBFile->closePend = TRUE;
write_lock(&file->f_owner.lock);
if(pTcon) {
/* no sense reconnecting to close a file that is
already closed */
if (pTcon->tidStatus != CifsNeedReconnect) {
write_unlock(&file->f_owner.lock);
rc = CIFSSMBClose(xid,pTcon,pSMBFile->netfid); rc = CIFSSMBClose(xid,pTcon,pSMBFile->netfid);
write_lock(&file->f_owner.lock); write_lock(&file->f_owner.lock);
}
}
list_del(&pSMBFile->flist); list_del(&pSMBFile->flist);
list_del(&pSMBFile->tlist); list_del(&pSMBFile->tlist);
write_unlock(&file->f_owner.lock); write_unlock(&file->f_owner.lock);
...@@ -638,23 +649,27 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to) ...@@ -638,23 +649,27 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
cifsInode = CIFS_I(mapping->host); cifsInode = CIFS_I(mapping->host);
read_lock(&GlobalSMBSeslock); /* BB switch to semaphore */ read_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist); open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* We check if file is open for writing first */ /* We check if file is open for writing first */
if((open_file->pfile) && if((open_file->pfile) &&
((open_file->pfile->f_flags & O_RDWR) || ((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) { (open_file->pfile->f_flags & O_WRONLY))) {
read_unlock(&GlobalSMBSeslock);
bytes_written = cifs_write(open_file->pfile, write_data, bytes_written = cifs_write(open_file->pfile, write_data,
to-from, &offset); to-from, &offset);
read_lock(&GlobalSMBSeslock);
/* Does mm or vfs already set times? */ /* Does mm or vfs already set times? */
inode->i_atime = inode->i_mtime = CURRENT_TIME; inode->i_atime = inode->i_mtime = CURRENT_TIME;
if ((bytes_written > 0) && (offset)) { if ((bytes_written > 0) && (offset)) {
rc = 0; rc = 0;
break;
} else if(bytes_written < 0) { } else if(bytes_written < 0) {
rc = bytes_written; rc = bytes_written;
} }
break; /* now that we found a valid file handle
and tried to write to it we are done, no
sense continuing to loop looking for another */
} }
if(tmp->next == NULL) { if(tmp->next == NULL) {
cFYI(1,("File instance %p removed",tmp)); cFYI(1,("File instance %p removed",tmp));
......
...@@ -237,6 +237,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -237,6 +237,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
else { else {
cFYI(1,("No response buffer")); cFYI(1,("No response buffer"));
DeleteMidQEntry(midQ); DeleteMidQEntry(midQ);
ses->server->tcpStatus = CifsNeedReconnect;
return -EIO; return -EIO;
} }
} }
......
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