Commit cdd29bc2 authored by Steve French's avatar Steve French

correct retry on remaining handles based calls

parent cf24118b
......@@ -88,9 +88,26 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
ses->serverOS, ses->serverNOS, ses->capabilities,ses->status,ses->server->tcpStatus);
buf += length;
if(ses->server)
if(ses->server) {
buf += sprintf(buf, "\n\tLocal Users To Same Server: %d SecMode: 0x%x",
atomic_read(&ses->server->socketUseCount),ses->server->secMode);
/* length = sprintf(buf, "\nMIDs: \n");
buf += length;
spin_lock(&GlobalMid_Lock);
list_for_each(tmp1, &ses->server->pending_mid_q) {
mid_entry = list_entry(tmp1, struct
mid_q_entry,
qhead);
if(mid_entry) {
length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p\n",mid_entry->midState,mid_entry->command,mid_entry->pid,mid_entry->tsk);
buf += length;
}
}
spin_unlock(&GlobalMid_Lock); */
}
}
read_unlock(&GlobalSMBSeslock);
sprintf(buf, "\n");
......@@ -127,8 +144,10 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
buf += sprintf(buf, "\tDISCONNECTED ");
}
read_unlock(&GlobalSMBSeslock);
length = sprintf(buf, "\n");
buf += length;
*eof = 1;
/* BB add code to dump additional info such as TCP session info now */
/*
......@@ -177,6 +196,9 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
item_length =
sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
length += item_length;
buf += item_length;
item_length = sprintf(buf,"%d sessions and %d shares reconnected after failure\n",tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
length += item_length;
return length;
}
......
......@@ -583,7 +583,7 @@ static int cifs_oplock_thread(void * dummyarg)
do {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout(1*HZ);
spin_lock(&GlobalMid_Lock);
if(list_empty(&GlobalOplock_Q)) {
spin_unlock(&GlobalMid_Lock);
......@@ -604,11 +604,20 @@ static int cifs_oplock_thread(void * dummyarg)
if (rc)
CIFS_I(inode)->write_behind_rc = rc;
cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
rc = CIFSSMBLock(0, pTcon, netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
cFYI(1,("Oplock release rc = %d ",rc));
/* releasing a stale oplock after recent reconnection
of smb session using a now incorrect file
handle is not a data integrity issue but do
not bother sending an oplock release if session
to server still is disconnected since oplock
already released by the server in that case */
if(pTcon->tidStatus != CifsNeedReconnect) {
rc = CIFSSMBLock(0, pTcon, netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
cFYI(1,("Oplock release rc = %d ",rc));
}
} else
spin_unlock(&GlobalMid_Lock);
}
......@@ -632,6 +641,9 @@ init_cifs(void)
*/
atomic_set(&sesInfoAllocCount, 0);
atomic_set(&tconInfoAllocCount, 0);
atomic_set(&tcpSesReconnectCount, 0);
atomic_set(&tconInfoReconnectCount, 0);
atomic_set(&bufAllocCount, 0);
atomic_set(&midCount, 0);
GlobalCurrentXid = 0;
......
......@@ -359,6 +359,9 @@ GLOBAL_EXTERN char Local_System_Name[15];
GLOBAL_EXTERN atomic_t sesInfoAllocCount;
GLOBAL_EXTERN atomic_t tconInfoAllocCount;
GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
/* Various Debug counters to remove someday (BB) */
GLOBAL_EXTERN atomic_t bufAllocCount;
GLOBAL_EXTERN atomic_t midCount;
......
......@@ -98,10 +98,27 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon,
nls_codepage);
up(&tcon->ses->sesSem);
if(rc == 0)
atomic_inc(&tconInfoReconnectCount);
cFYI(1, ("reconnect tcon rc = %d", rc));
/* Removed call to reopen open files here -
it is safer (and faster) to reopen files
one at a time as needed in read and write */
/* Check if handle based operation so we
know whether we can continue or not without
returning to caller to reset file handle */
switch(smb_command) {
case SMB_COM_READ_ANDX:
case SMB_COM_WRITE_ANDX:
case SMB_COM_CLOSE:
case SMB_COM_FIND_CLOSE2:
case SMB_COM_LOCKING_ANDX: {
unload_nls(nls_codepage);
return -EAGAIN;
}
}
} else {
up(&tcon->ses->sesSem);
}
......@@ -775,6 +792,8 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
/* do not retry on dead session on close */
rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB,
(void **) &pSMBr);
if(rc == -EAGAIN)
return 0;
if (rc)
return rc;
......@@ -1843,6 +1862,10 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
cFYI(1, ("In CIFSSMBFindClose"));
rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,
(void **) &pSMBr);
/* no sense returning error if session restarted
file handle has been closed */
if(rc == -EAGAIN)
return 0;
if (rc)
return rc;
......
......@@ -148,6 +148,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(3 * HZ);
} else {
atomic_inc(&tcpSesReconnectCount);
server->tcpStatus = CifsGood;
wake_up(&server->response_q);
}
......@@ -321,6 +322,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
wake_up_process(task_to_wake);
} else if (is_valid_oplock_break(smb_buffer) == FALSE) {
cERROR(1, ("No task to wake, unknown frame rcvd!"));
cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
}
}
} else {
......
......@@ -511,7 +511,7 @@ cifs_write(struct file * file, const char *write_data,
if (*poffset > file->f_dentry->d_inode->i_size)
long_op = 2; /* writes past end of file can take a long time */
long_op = 2; /* writes past end of file can take a long time */
else
long_op = 1;
......@@ -542,7 +542,8 @@ cifs_write(struct file * file, const char *write_data,
*poffset += bytes_written;
long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
}
file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
CURRENT_TIME;
if (bytes_written > 0) {
if (*poffset > file->f_dentry->d_inode->i_size)
file->f_dentry->d_inode->i_size = *poffset;
......@@ -709,9 +710,14 @@ cifs_commit_write(struct file *file, struct page *page, unsigned offset,
if(rc != 0)
break;
}
rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
if(!open_file->closePend)
rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
position, open_file->netfid,
open_file->pid,FALSE);
else {
rc = -EBADF;
break;
}
}
cFYI(1,(" SetEOF (commit write) rc = %d",rc));
}
......@@ -836,15 +842,16 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
open_file->netfid,
current_read_size, *poffset,
&bytes_read, &current_offset);
if (rc || (bytes_read == 0)) {
if (total_read) {
break;
} else {
FreeXid(xid);
return rc;
}
} else
*poffset += bytes_read;
}
if (rc || (bytes_read == 0)) {
if (total_read) {
break;
} else {
FreeXid(xid);
return rc;
}
} else {
*poffset += bytes_read;
}
}
......
......@@ -655,7 +655,7 @@ cifs_truncate_file(struct inode *inode)
list_for_each(tmp, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* We check if file is open for writing first */
if((open_file->pfile) &&
if((open_file->pfile) && (!open_file->invalidHandle) &&
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
read_unlock(&GlobalSMBSeslock);
......@@ -769,7 +769,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
list_for_each(tmp, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist);
/* 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_WRONLY))) {
if(open_file->invalidHandle == FALSE) {
......
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