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
------------
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
------------
......
......@@ -595,8 +595,8 @@ static int cifs_oplock_thread(void * dummyarg)
pTcon = oplock_item->tcon;
inode = oplock_item->pinode;
netfid = oplock_item->netfid;
DeleteOplockQEntry(oplock_item);
spin_unlock(&GlobalMid_Lock);
DeleteOplockQEntry(oplock_item);
if (S_ISREG(inode->i_mode))
rc = filemap_fdatawrite(inode->i_mapping);
else
......
......@@ -185,7 +185,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
sizeof (struct smb_hdr) -
1 /* RFC1001 header and SMB header */ ,
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) {
cERROR(1, ("Connection reset by peer "));
cifs_reconnect(server);
......@@ -758,8 +763,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
*csocket = NULL;
return rc;
} 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"));
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,
pCifsFile->pid = current->tgid;
pCifsFile->pInode = newinode;
pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE;
/* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList);
......
......@@ -145,6 +145,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode;
pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE;
write_lock(&file->f_owner.lock);
write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList);
......@@ -325,7 +326,8 @@ int reopen_files(struct cifsTconInfo * pTcon, struct nls_table * nlsinfo)
if(open_file == NULL) {
break;
} else {
if(open_file->invalidHandle == FALSE) {
if((open_file->invalidHandle == FALSE) &&
(open_file->closePend == FALSE)) {
list_move(&open_file->tlist,&pTcon->openFileList);
continue;
}
......@@ -372,8 +374,17 @@ cifs_close(struct inode *inode, struct file *file)
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
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);
write_lock(&file->f_owner.lock);
}
}
list_del(&pSMBFile->flist);
list_del(&pSMBFile->tlist);
write_unlock(&file->f_owner.lock);
......@@ -638,23 +649,27 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
cifsInode = CIFS_I(mapping->host);
read_lock(&GlobalSMBSeslock); /* BB switch to semaphore */
read_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* We check if file is open for writing first */
if((open_file->pfile) &&
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
read_unlock(&GlobalSMBSeslock);
bytes_written = cifs_write(open_file->pfile, write_data,
to-from, &offset);
read_lock(&GlobalSMBSeslock);
/* Does mm or vfs already set times? */
inode->i_atime = inode->i_mtime = CURRENT_TIME;
if ((bytes_written > 0) && (offset)) {
rc = 0;
break;
} else if(bytes_written < 0) {
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) {
cFYI(1,("File instance %p removed",tmp));
......
......@@ -237,6 +237,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
else {
cFYI(1,("No response buffer"));
DeleteMidQEntry(midQ);
ses->server->tcpStatus = CifsNeedReconnect;
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