Commit 1915ad84 authored by Steve French's avatar Steve French Committed by Steve French

have to reconnect open files safely, one at a time, as needed

parent c0426ae3
...@@ -211,6 +211,7 @@ struct cifsFileInfo { ...@@ -211,6 +211,7 @@ struct cifsFileInfo {
struct inode * pInode; /* needed for oplock break */ struct inode * pInode; /* needed for oplock break */
int endOfSearch:1; /* we have reached end of search */ int endOfSearch:1; /* we have reached end of search */
int closePend:1; /* file is marked to close */ int closePend:1; /* file is marked to close */
int reopenPend:1; /* reopen of file in progress */
int emptyDir:1; int emptyDir:1;
int invalidHandle:1; /* file closed via session abend */ int invalidHandle:1; /* file closed via session abend */
char * search_resume_name; char * search_resume_name;
......
...@@ -21,7 +21,11 @@ ...@@ -21,7 +21,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
/* These are mostly routines that operate on a pathname, or on a tree id */
/* (mounted volume), but there are eight handle based routines which must be */
/* treated slightly different for reconnection purposes since we never want */
/* to reuse a stale file handle and the caller knows the file handle */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -49,21 +53,45 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, ...@@ -49,21 +53,45 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
{ {
int rc = 0; int rc = 0;
if(tcon && (tcon->tidStatus == CifsNeedReconnect)) { /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
if(tcon->ses) { check for tcp and smb session status done differently
for those three - in the calling routine */
if(tcon) {
if((tcon->ses) && (tcon->ses->server)){
if(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
/* Give Demultiplex thread up to 10 seconds to
reconnect, should be greater than cifs socket
timeout which is 7 seconds */
wait_event_interruptible_timeout(tcon->ses->server->response_q,
(tcon->ses->server->tcpStatus == CifsGood), 10 * HZ);
if(tcon->ses->server->tcpStatus == CifsNeedReconnect)
return -EHOSTDOWN;
}
/* need to prevent multiple threads trying to
simultaneously reconnect the same SMB session */
down(&tcon->ses->sesSem);
struct nls_table *nls_codepage = load_nls_default(); struct nls_table *nls_codepage = load_nls_default();
if(tcon->ses->status == CifsNeedReconnect) if(tcon->ses->status == CifsNeedReconnect)
rc = setup_session(0, tcon->ses, nls_codepage); rc = setup_session(0, tcon->ses, nls_codepage);
if(!rc) { if(!rc && (tcon->tidStatus == CifsNeedReconnect)) {
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon,
nls_codepage); nls_codepage);
up(&tcon->ses->sesSem);
cFYI(1, ("reconnect tcon rc = %d", rc)); cFYI(1, ("reconnect tcon rc = %d", rc));
if(!rc) /* Remove call to reopen files here -
reopen_files(tcon,nls_codepage); it is safer (and faster) to reopen
files as needed in read and write */
/* if(!rc)
reopen_files(tcon,nls_codepage);*/
} else {
up(&tcon->ses->sesSem);
} }
unload_nls(nls_codepage); unload_nls(nls_codepage);
} else
rc = -EIO; } else {
return -EIO;
}
} }
if(rc) if(rc)
return rc; return rc;
...@@ -209,7 +237,6 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) ...@@ -209,7 +237,6 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
* (and inside session disconnect we should check if tcp socket needs * (and inside session disconnect we should check if tcp socket needs
* to be freed and kernel thread woken up). * to be freed and kernel thread woken up).
*/ */
tdisRetry:
if (tcon) if (tcon)
down(&tcon->tconSem); down(&tcon->tconSem);
else else
...@@ -221,12 +248,19 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) ...@@ -221,12 +248,19 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
return -EBUSY; return -EBUSY;
} }
/* No need to return error on this operation if tid invalidated and
closed on server already e.g. due to tcp session crashing */
if(tcon->tidStatus == CifsNeedReconnect) {
up(&tcon->tconSem);
return 0;
}
/* BB remove (from server) list of shares - but with smp safety BB */ /* BB remove (from server) list of shares - but with smp safety BB */
/* BB is ses active - do we need to check here - but how? BB */ /* BB is ses active - do we need to check here - but how? BB */
if((tcon->ses == 0) || (tcon->ses->server == 0)) { if((tcon->ses == 0) || (tcon->ses->server == 0)) {
up(&tcon->tconSem); up(&tcon->tconSem);
return -EIO; return -EIO;
} }
rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
(void **) &smb_buffer, (void **) &smb_buffer_response); (void **) &smb_buffer, (void **) &smb_buffer_response);
...@@ -242,8 +276,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) ...@@ -242,8 +276,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
if (smb_buffer) if (smb_buffer)
buf_release(smb_buffer); buf_release(smb_buffer);
up(&tcon->tconSem); up(&tcon->tconSem);
/* No need to return error on this operation if tid invalidated and
closed on server already e.g. due to tcp session crashing */
if (rc == -EAGAIN) if (rc == -EAGAIN)
goto tdisRetry; rc = 0;
return rc; return rc;
} }
...@@ -256,9 +294,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -256,9 +294,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
int length; int length;
cFYI(1, ("In SMBLogoff for session disconnect")); cFYI(1, ("In SMBLogoff for session disconnect"));
LogoffRetry:
if (ses) if (ses)
down(&ses->sesSem); /* check this sem more places */ down(&ses->sesSem);
else else
return -EIO; return -EIO;
...@@ -292,8 +329,12 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -292,8 +329,12 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
up(&ses->sesSem); up(&ses->sesSem);
/* if session dead then we do not need to do ulogoff,
since server closed smb session, no sense reporting
error */
if (rc == -EAGAIN) if (rc == -EAGAIN)
goto LogoffRetry; rc = 0;
return rc; return rc;
} }
...@@ -537,7 +578,6 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, ...@@ -537,7 +578,6 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
char *pReadData = NULL; char *pReadData = NULL;
int bytes_returned; int bytes_returned;
readRetry:
*nbytes = 0; *nbytes = 0;
rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -588,9 +628,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, ...@@ -588,9 +628,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
else else
*buf = (char *)pSMB; *buf = (char *)pSMB;
} }
if (rc == -EAGAIN)
goto readRetry;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return rc; return rc;
} }
...@@ -605,7 +645,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, ...@@ -605,7 +645,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
WRITE_RSP *pSMBr = NULL; WRITE_RSP *pSMBr = NULL;
int bytes_returned; int bytes_returned;
writeRetry:
rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -646,8 +685,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, ...@@ -646,8 +685,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
if (rc == -EAGAIN) /* Note: On -EAGAIN error only caller can retry on handle based calls
goto writeRetry; since file handle passed in no longer valid */
return rc; return rc;
} }
...@@ -666,7 +705,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -666,7 +705,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
__u64 temp; __u64 temp;
cFYI(1, ("In CIFSSMBLock")); cFYI(1, ("In CIFSSMBLock"));
lockRetry:
rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -701,8 +739,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -701,8 +739,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
if (rc == -EAGAIN)
goto lockRetry; /* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return rc; return rc;
} }
...@@ -732,9 +771,9 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ...@@ -732,9 +771,9 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
/* file will be closed on server if session is dead */ /* Since session is dead, file will be closed on server already */
if(rc == -EAGAIN) if(rc == -EAGAIN)
rc = -EHOSTDOWN; /* should we fake success? */ rc = 0;
return rc; return rc;
} }
...@@ -822,7 +861,6 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, ...@@ -822,7 +861,6 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int len_of_str; int len_of_str;
cFYI(1, ("Rename to File by handle")); cFYI(1, ("Rename to File by handle"));
renameOpenFileRetry:
rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -880,8 +918,8 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, ...@@ -880,8 +918,8 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
if (rc == -EAGAIN) /* Note: On -EAGAIN error only caller can retry on handle based calls
goto renameOpenFileRetry; since file handle passed in no longer valid */
return rc; return rc;
} }
...@@ -1249,7 +1287,6 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -1249,7 +1287,6 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
struct smb_com_transaction_ioctl_rsp * pSMBr; struct smb_com_transaction_ioctl_rsp * pSMBr;
cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName)); cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
queryReparseLinkInfoRetry:
rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1314,8 +1351,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -1314,8 +1351,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
if (rc == -EAGAIN)
goto queryReparseLinkInfoRetry; /* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return rc; return rc;
} }
...@@ -1686,7 +1724,6 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon, ...@@ -1686,7 +1724,6 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
cFYI(1, ("In FindNext")); cFYI(1, ("In FindNext"));
findNextRetry:
if(resume_file_name == NULL) { if(resume_file_name == NULL) {
return -EIO; return -EIO;
} }
...@@ -1771,8 +1808,8 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon, ...@@ -1771,8 +1808,8 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
if (rc == -EAGAIN) /* Note: On -EAGAIN error only caller can retry on handle based calls
goto findNextRetry; since file handle passed in no longer valid */
return rc; return rc;
} }
...@@ -1784,8 +1821,8 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle ...@@ -1784,8 +1821,8 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
FINDCLOSE_REQ *pSMB = NULL; FINDCLOSE_REQ *pSMB = NULL;
CLOSE_RSP *pSMBr = NULL; CLOSE_RSP *pSMBr = NULL;
int bytes_returned; int bytes_returned;
cFYI(1, ("In CIFSSMBFindClose")); cFYI(1, ("In CIFSSMBFindClose"));
findCloseRetry:
rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1801,8 +1838,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle ...@@ -1801,8 +1838,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
/* Since session is dead, search handle closed on server already */
if (rc == -EAGAIN) if (rc == -EAGAIN)
goto findCloseRetry; rc = 0;
return rc; return rc;
} }
...@@ -2363,7 +2401,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -2363,7 +2401,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
__u32 tmp; __u32 tmp;
cFYI(1, ("SetFileSize (via SetFileInfo)")); cFYI(1, ("SetFileSize (via SetFileInfo)"));
SetFileSizeRetry:
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -2434,8 +2471,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -2434,8 +2471,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
if (rc == -EAGAIN) /* Note: On -EAGAIN error only caller can retry on handle based calls
goto SetFileSizeRetry; since file handle passed in no longer valid */
return rc; return rc;
} }
......
...@@ -821,7 +821,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ...@@ -821,7 +821,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
/* Eventually check for other socket options to change from /* Eventually check for other socket options to change from
the default. sock_setsockopt not used because it expects the default. sock_setsockopt not used because it expects
user space buffer */ user space buffer */
(*csocket)->sk->sk_rcvtimeo = 8 * HZ; (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
return rc; return rc;
} }
...@@ -1002,8 +1002,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1002,8 +1002,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
strncpy(pSesInfo->domainName, strncpy(pSesInfo->domainName,
volume_info.domainname,MAX_USERNAME_SIZE); volume_info.domainname,MAX_USERNAME_SIZE);
pSesInfo->linux_uid = volume_info.linux_uid; pSesInfo->linux_uid = volume_info.linux_uid;
down(&pSesInfo->sesSem);
rc = setup_session(xid,pSesInfo, cifs_sb->local_nls); rc = setup_session(xid,pSesInfo, cifs_sb->local_nls);
up(&pSesInfo->sesSem);
if(!rc) if(!rc)
atomic_inc(&srvTcp->socketUseCount); atomic_inc(&srvTcp->socketUseCount);
} }
......
...@@ -740,10 +740,22 @@ cifs_commit_write(struct file *file, struct page *page, unsigned offset, ...@@ -740,10 +740,22 @@ cifs_commit_write(struct file *file, struct page *page, unsigned offset,
if (file->private_data == NULL) { if (file->private_data == NULL) {
rc = -EBADF; rc = -EBADF;
} else { } else {
cifs_sb = CIFS_SB(inode->i_sb);
open_file = (struct cifsFileInfo *)file->private_data; open_file = (struct cifsFileInfo *)file->private_data;
rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon, position, cifs_sb = CIFS_SB(inode->i_sb);
open_file->netfid,open_file->pid,FALSE); rc = -EAGAIN;
while(rc == -EAGAIN) {
if((open_file->invalidHandle == TRUE) &&
(open_file->closePend == FALSE)) {
open_file->reopenPend = TRUE;
rc = cifs_reopen_file(file->f_dentry->d_inode,file);
open_file->reopenPend = FALSE;
}
if(rc != 0)
break;
rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
position, open_file->netfid,
open_file->pid,FALSE);
}
cFYI(1,(" SetEOF (commit write) rc = %d",rc)); cFYI(1,(" SetEOF (commit write) rc = %d",rc));
} }
} }
......
...@@ -665,7 +665,12 @@ cifs_truncate_file(struct inode *inode) ...@@ -665,7 +665,12 @@ cifs_truncate_file(struct inode *inode)
if(rc == 0) { if(rc == 0) {
FreeXid(xid); FreeXid(xid);
return; return;
} }
/* Do not need reopen and retry on EAGAIN since we will
retry by pathname below */
if(rc == -EAGAIN)
rc = -EHOSTDOWN;
break; /* now that we found one valid file handle no break; /* now that we found one valid file handle no
sense continuing to loop trying others */ sense continuing to loop trying others */
} }
...@@ -767,19 +772,31 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -767,19 +772,31 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
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); if(open_file->invalidHandle == FALSE) {
found = TRUE; /* we found a valid, writeable network file
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, handle to use to try to set the file size */
open_file->netfid,open_file->pid,FALSE); __u16 nfid = open_file->netfid;
cFYI(1,("SetFileSize by handle (setattrs) rc = %d",rc)); __u32 npid = open_file->pid;
break; /* now that we found one valid file handle no read_unlock(&GlobalSMBSeslock);
found = TRUE;
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
nfid,npid,FALSE);
cFYI(1,("SetFileSize by handle (setattrs) rc = %d",rc));
/* Do not need reopen and retry on EAGAIN since we will
retry by pathname below */
break; /* now that we found one valid file handle no
sense continuing to loop trying others */ sense continuing to loop trying others */
}
} }
} }
if(found == FALSE) if(found == FALSE)
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
if(rc != 0) { if(rc != 0) {
/* Set file size by pathname rather than by handle either
because no valid, writeable file handle for it was found or
because there was an error setting it by handle */
rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,FALSE, rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,FALSE,
cifs_sb->local_nls); cifs_sb->local_nls);
cFYI(1,(" SetEOF by path (setattrs) rc = %d",rc)); cFYI(1,(" SetEOF by path (setattrs) rc = %d",rc));
......
...@@ -184,9 +184,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -184,9 +184,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return -ENOENT; return -ENOENT;
} else if (ses->server->tcpStatus == CifsNeedReconnect) { } else if (ses->server->tcpStatus == CifsNeedReconnect) {
cFYI(1,("tcp session dead - return to caller to retry")); cFYI(1,("tcp session dead - return to caller to retry"));
/* Give Demultiplex thread up to 10 seconds to reconnect */
wait_event_interruptible_timeout(ses->server->response_q,
(ses->server->tcpStatus == CifsGood), 10 * HZ);
return -EAGAIN; return -EAGAIN;
} else if (ses->status != CifsGood) { } else if (ses->status != CifsGood) {
/* check if SMB session is bad because we are setting it up */ /* check if SMB session is bad because we are setting it up */
......
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