summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve French <stevef@smfhome1.austin.rr.com>2003-02-18 09:15:15 -0600
committerSteve French <stevef@smfhome1.austin.rr.com>2003-02-18 09:15:15 -0600
commit6c1f07467c8ac2e10277dde55e8158508209094b (patch)
tree924fd33a8d12591abfaca90c6bdff160802bddb0
parentc0630ba10df3a20ab916557c76f1cf8245ed65aa (diff)
Remove compiler warnings and allow reconnection of tids after temporary tcp session failure
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/cifsproto.h38
-rw-r--r--fs/cifs/cifssmb.c156
-rw-r--r--fs/cifs/connect.c30
-rw-r--r--fs/cifs/file.c6
-rw-r--r--fs/cifs/misc.c2
-rw-r--r--fs/cifs/transport.c28
7 files changed, 148 insertions, 116 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7d851b2af138..d8f7370ccaef 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -105,7 +105,7 @@ struct TCP_Server_Info {
char versionMinor;
int svlocal:1; /* local server or remote */
atomic_t socketUseCount; /* indicates if the server has any open cifs sessions */
- enum statusEnum tcpStatus; /* what we think the status is */
+ enum statusEnum tcpStatus; /* what we think the status is */
struct semaphore tcpSem;
struct task_struct *tsk;
char server_GUID[16];
@@ -170,7 +170,7 @@ struct cifsTconInfo {
struct list_head openFileList;
struct semaphore tconSem;
struct cifsSesInfo *ses; /* pointer to session associated with */
- char treeName[MAX_TREE_SIZE + 1]; /* The ascii or unicode name of this resource depending on the ses->capabilities *//* BB fill in this field */
+ char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource (in ASCII not UTF) */
char *nativeFileSystem;
__u16 tid; /* The 2 byte transaction id */
__u16 Flags; /* optional support bits */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 66b3c3cb9d9f..b6b8965f9e71 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -93,26 +93,26 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
const char *tree, struct cifsTconInfo *tcon,
const struct nls_table *);
-extern int CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
const char *searchName,
FILE_DIRECTORY_INFO * findData,
T2_FFIRST_RSP_PARMS * findParms,
const struct nls_table *nls_codepage,
int *pUnicodeFlag,
int *pUnixFlag /* if Unix extensions used */ );
-extern int CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
FILE_DIRECTORY_INFO * findData,
T2_FNEXT_RSP_PARMS * findParms,
const __u16 searchHandle, const __u32 resumeKey,
int *UnicodeFlag, int *pUnixFlag);
-extern int CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_ALL_INFO * findData,
const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQPathInfo(const int xid,
- const struct cifsTconInfo *tcon,
+ struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_UNIX_BASIC_INFO * pFindData,
const struct nls_table *nls_codepage);
@@ -127,7 +127,7 @@ extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path,
const struct nls_table *nls_codepage);
-extern int CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
struct statfs *FSData,
const struct nls_table *nls_codepage);
extern int CIFSSMBQFSAttributeInfo(const int xid,
@@ -150,57 +150,57 @@ extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
char *full_path, __u64 mode, __u64 uid,
__u64 gid, const struct nls_table *nls_codepage);
-extern int CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
const char *newName,
const struct nls_table *nls_codepage);
-extern int CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
const char *name, const struct nls_table *nls_codepage);
-extern int CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
const char *name,
const struct nls_table *nls_codepage);
-extern int CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage);
extern int CIFSCreateHardLink(const int xid,
- const struct cifsTconInfo *tcon,
+ struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage);
extern int CIFSUnixCreateHardLink(const int xid,
- const struct cifsTconInfo *tcon,
+ struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage);
extern int CIFSUnixCreateSymLink(const int xid,
- const struct cifsTconInfo *tcon,
+ struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQuerySymLink(const int xid,
- const struct cifsTconInfo *tcon,
+ struct cifsTconInfo *tcon,
const unsigned char *searchName,
char *syminfo, const int buflen,
const struct nls_table *nls_codepage);
extern int CIFSSMBQueryReparseLinkInfo(const int xid,
- const struct cifsTconInfo *tcon,
+ struct cifsTconInfo *tcon,
const unsigned char *searchName,
char *symlinkinfo, const int buflen, __u16 fid,
const struct nls_table *nls_codepage);
-extern int CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int disposition,
const int access_flags, const int omode,
__u16 * netfid, int *pOplock,
const struct nls_table *nls_codepage);
-extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id);
-extern int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
const int netfid, unsigned int count,
const __u64 lseek, unsigned int *nbytes, char **buf);
-extern int CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 lseek, unsigned int *nbytes,
const char *buf, const int long_op);
-extern int CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
+extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 netfid, const __u64 len,
const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 98221be0e6ee..e434f781d5aa 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -43,16 +43,27 @@ static struct {
};
int
-smb_init(int smb_command, int wct, const struct cifsTconInfo *tcon,
+smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
void **request_buf /* returned */ ,
void **response_buf /* returned */ )
{
int rc = 0;
- if(tcon)
- if(tcon->ses)
+ if(tcon && (tcon->tidStatus == CifsNeedReconnect)) {
+ rc = -EIO;
+ if(tcon->ses) {
+ struct nls_table *nls_codepage = load_nls_default();
if(tcon->ses->status == CifsNeedReconnect)
- setup_session(0, tcon->ses, load_nls_default());
+ rc = setup_session(0, tcon->ses, nls_codepage);
+ if(!rc) {
+ rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon,
+ nls_codepage);
+ cFYI(1, ("reconnect tcon rc = %d", rc));
+ }
+ }
+ }
+ if(rc)
+ return rc;
*request_buf = buf_get();
if (request_buf == 0) {
@@ -143,7 +154,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
pSMBr->u.extended_response.
GUID, 16) != 0) {
cFYI(1,
- ("UID of server does not match that of previous connection to same ip address"));
+ ("UID of server does not match previous connection to same ip address"));
memcpy(server->
server_GUID,
pSMBr->u.
@@ -166,7 +177,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->capabilities &= ~CAP_EXTENDED_SECURITY;
if(sign_CIFS_PDUs == FALSE) {
if(server->secMode & SECMODE_SIGN_REQUIRED)
- cERROR(1,("Server required CIFS packet signing - enable /proc/fs/cifs/PacketSigningEnabled"));
+ cERROR(1,
+ ("Server requires /proc/fs/cifs/PacketSigningEnabled"));
server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
}
}
@@ -188,8 +200,8 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
* If last user of the connection and
* connection alive - disconnect it
* If this is the last connection on the server session disconnect it
- * (and inside session disconnect we should check if tcp socket needs to
- * be freed and kernel thread woken up).
+ * (and inside session disconnect we should check if tcp socket needs
+ * to be freed and kernel thread woken up).
*/
if (tcon)
down(&tcon->tconSem);
@@ -237,7 +249,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
cFYI(1, ("In SMBLogoff for session disconnect"));
if (ses)
- down(&ses->sesSem); /* need to add more places where this sem is checked */
+ down(&ses->sesSem); /* check this sem more places */
else
return -EIO;
@@ -246,10 +258,10 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
up(&ses->sesSem);
return -EBUSY;
}
- if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */ ,
- (void **) &pSMB, (void **) &smb_buffer_response);
+ if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+ rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */,
+ (void **) &pSMB, (void **) &smb_buffer_response);
if (rc) {
up(&ses->sesSem);
return rc;
@@ -272,7 +284,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
}
int
-CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const struct nls_table *nls_codepage)
{
DELETE_FILE_REQ *pSMB = NULL;
@@ -315,7 +327,7 @@ CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
const char *dirName, const struct nls_table *nls_codepage)
{
DELETE_DIRECTORY_REQ *pSMB = NULL;
@@ -358,7 +370,7 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
const char *name, const struct nls_table *nls_codepage)
{
int rc = 0;
@@ -402,7 +414,7 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 * netfid,
int *pOplock, const struct nls_table *nls_codepage)
@@ -446,14 +458,15 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
pSMB->AllocationSize = 0;
pSMB->FileAttributes = ATTR_NORMAL; /* XP does not handle ATTR_POSIX_SEMANTICS */
/*if ((omode & S_IWUGO) == 0)
- pSMB->FileAttributes |= ATTR_READONLY;*/
- /* Above line causes problems due to problem with vfs splitting create into
- two pieces - need to set mode after file created not while it is being created */
+ pSMB->FileAttributes |= ATTR_READONLY;*/
+ /* Above line causes problems due to vfs splitting create into two
+ pieces - need to set mode after file created not while it is
+ being created */
pSMB->FileAttributes = cpu_to_le32(pSMB->FileAttributes);
pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
pSMB->CreateDisposition = cpu_to_le32(openDisposition);
pSMB->CreateOptions = cpu_to_le32(create_options);
- pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); /* BB ?? BB */
+ pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); /* BB ??*/
pSMB->SecurityFlags =
cpu_to_le32(SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY);
@@ -470,7 +483,7 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
*netfid = pSMBr->Fid; /* cifs fid stays in le */
/* Do we care about the CreateAction in any cases? */
- /* BB add code to update inode with file sizes from create response */
+ /* BB add code to update inode file sizes from create response */
}
if (pSMB)
buf_release(pSMB);
@@ -483,7 +496,7 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
freed by the caller */
int
-CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 lseek, unsigned int *nbytes, char **buf)
{
@@ -504,9 +517,8 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
pSMB->Remaining = 0;
- pSMB->MaxCount = cpu_to_le16(min(count,
- (tcon->ses->server->maxBuf -
- MAX_CIFS_HDR_SIZE) & 0xFFFFFF00));
+ pSMB->MaxCount = cpu_to_le16(min_t(const unsigned int, count,
+ (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00));
pSMB->MaxCountHigh = 0;
pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */
@@ -545,7 +557,7 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, const char *buf,
const int long_op)
@@ -596,7 +608,7 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u64 len,
const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const int waitFlag)
@@ -639,7 +651,7 @@ CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, int smb_file_id)
+CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
{
int rc = 0;
CLOSE_REQ *pSMB = NULL;
@@ -667,7 +679,7 @@ CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, int smb_file_id)
}
int
-CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
{
@@ -697,7 +709,8 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */
name_len *= 2;
pSMB->OldFileName[name_len] = 0; /* pad */
- pSMB->OldFileName[name_len + 1] = 0x04; /* strange that protocol requires an ASCII signature byte on Unicode string */
+ /* protocol requires ASCII signature byte on Unicode string */
+ pSMB->OldFileName[name_len + 1] = 0x04;
name_len2 =
cifs_strtoUCS((wchar_t *) & pSMB->
OldFileName[name_len + 2], toName, 530,
@@ -710,13 +723,13 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
strncpy(pSMB->OldFileName, fromName, name_len);
name_len2 = strnlen(toName, 530);
name_len2++; /* trailing null */
- pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
+ pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
name_len2++; /* trailing null */
name_len2++; /* signature byte */
}
- pSMB->ByteCount = 1 /* 1st signature byte */ + name_len + name_len2;
+ pSMB->ByteCount = 1 /* 1st signature byte */ + name_len + name_len2;
/* we could also set search attributes but not needed */
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
@@ -733,7 +746,7 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon,
+CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
{
@@ -791,7 +804,8 @@ CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon,
pSMB->DataCount = name_len_target;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /*BB find exact max SMB from sess */
+ /* BB find exact max on data count below from sess */
+ pSMB->MaxDataCount = cpu_to_le16(1000);
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
@@ -820,7 +834,7 @@ CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
+CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
{
@@ -877,7 +891,8 @@ CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
pSMB->DataCount = name_len_target;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB from sess*/
+ /* BB find exact max on data count below from sess*/
+ pSMB->MaxDataCount = cpu_to_le16(1000);
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
@@ -904,7 +919,7 @@ CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
+CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
{
@@ -937,7 +952,7 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */
name_len *= 2;
pSMB->OldFileName[name_len] = 0; /* pad */
- pSMB->OldFileName[name_len + 1] = 0x04; /* strange that protocol requires an ASCII signature byte on Unicode string */
+ pSMB->OldFileName[name_len + 1] = 0x04;
name_len2 =
cifs_strtoUCS((wchar_t *) & pSMB->
OldFileName[name_len + 2], toName, 530,
@@ -972,7 +987,7 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
char *symlinkinfo, const int buflen,
const struct nls_table *nls_codepage)
@@ -1007,7 +1022,8 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
pSMB->TotalDataCount = 0;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
+ /* BB find exact max data count below from sess structure BB */
+ pSMB->MaxDataCount = cpu_to_le16(4000);
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
@@ -1041,27 +1057,17 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
else {
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len = UniStrnlen((wchar_t *) ((char *)
- &pSMBr->hdr.
- Protocol +
- pSMBr->
- DataOffset),
- min(buflen,
- (int) pSMBr->
- DataCount) / 2);
+ &pSMBr->hdr.Protocol +pSMBr->DataOffset),
+ min_t(const int, buflen,pSMBr->DataCount) / 2);
cifs_strfromUCS_le(symlinkinfo,
- (wchar_t *) ((char *)
- &pSMBr->
- hdr.
- Protocol +
- pSMBr->
- DataOffset),
- name_len, nls_codepage);
+ (wchar_t *) ((char *)&pSMBr->hdr.Protocol +
+ pSMBr->DataOffset),
+ name_len, nls_codepage);
} else {
strncpy(symlinkinfo,
- (char *) &pSMBr->hdr.Protocol +
- pSMBr->DataOffset, min(buflen, (int)
- pSMBr->
- DataCount));
+ (char *) &pSMBr->hdr.Protocol +
+ pSMBr->DataOffset,
+ min_t(const int, buflen, pSMBr->DataCount));
}
symlinkinfo[buflen] = 0;
/* just in case so calling code does not go off the end of buffer */
@@ -1075,7 +1081,7 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
int
-CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
char *symlinkinfo, const int buflen,__u16 fid,
const struct nls_table *nls_codepage)
@@ -1086,7 +1092,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
struct smb_com_transaction_ioctl_req * pSMB;
struct smb_com_transaction_ioctl_rsp * pSMBr;
- cFYI(1, ("In Windows reparse style QueryLink info for path %s", searchName));
+ cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
@@ -1095,7 +1101,8 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
pSMB->TotalParameterCount = 0 ;
pSMB->TotalDataCount = 0;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
+ /* BB find exact data count max from sess structure BB */
+ pSMB->MaxDataCount = cpu_to_le16(4000);
pSMB->MaxSetupCount = 4;
pSMB->Reserved = 0;
pSMB->ParameterOffset = 0;
@@ -1122,7 +1129,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
rc = -EIO; /* bad smb */
else {
if(pSMBr->DataCount && (pSMBr->DataCount < 2048)) {
- /* could also validata reparse tag && better check name length */
+ /* could also validate reparse tag && better check name length */
struct reparse_data * reparse_buf = (struct reparse_data *)
((char *)&pSMBr->hdr.Protocol + pSMBr->DataOffset);
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
@@ -1137,7 +1144,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
} else { /* ASCII names */
strncpy(symlinkinfo,reparse_buf->LinkNamesBuf +
reparse_buf->TargetNameOffset,
- min(buflen, (int)reparse_buf->TargetNameLen));
+ min_t(const int, buflen, reparse_buf->TargetNameLen));
}
} else {
rc = -EIO;
@@ -1154,7 +1161,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_ALL_INFO * pFindData,
const struct nls_table *nls_codepage)
@@ -1216,7 +1223,8 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
cFYI(1, ("Send error in QPathInfo = %d", rc));
} else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
- if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
+ /* BB also check enough total bytes returned */
+ if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
rc = -EIO; /* bad smb */
else {
memcpy((char *) pFindData,
@@ -1230,7 +1238,7 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_UNIX_BASIC_INFO * pFindData,
const struct nls_table *nls_codepage)
@@ -1265,7 +1273,8 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
name_len /* includes null */ ;
pSMB->TotalDataCount = 0;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
+ /* BB find exact max SMB PDU from sess structure BB */
+ pSMB->MaxDataCount = cpu_to_le16(4000);
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
@@ -1292,7 +1301,8 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
cFYI(1, ("Send error in QPathInfo = %d", rc));
} else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
- if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
+ /* BB also check if enough total bytes returned */
+ if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
rc = -EIO; /* bad smb */
else {
memcpy((char *) pFindData,
@@ -1307,7 +1317,7 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon,
+CIFSFindSingle(const int xid, struct cifsTconInfo *tcon,
const char *searchName, FILE_ALL_INFO * findData,
const struct nls_table *nls_codepage)
{
@@ -1381,7 +1391,7 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
+CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
const char *searchName, FILE_DIRECTORY_INFO * findData,
T2_FFIRST_RSP_PARMS * findParms,
const struct nls_table *nls_codepage, int *pUnicodeFlag,
@@ -1484,7 +1494,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
}
int
-CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
+CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
FILE_DIRECTORY_INFO * findData,
T2_FNEXT_RSP_PARMS * findParms, const __u16 searchHandle,
__u32 resumeKey, int *pUnicodeFlag, int *pUnixFlag)
@@ -1661,7 +1671,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
}
int
-CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
+CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
struct statfs *FSData, const struct nls_table *nls_codepage)
{
/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 40e8ea812433..dd28f46185e1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -76,22 +76,32 @@ cifs_reconnect(struct TCP_Server_Info *server)
int rc = 0;
struct list_head *tmp;
struct cifsSesInfo *ses;
+ struct cifsTconInfo *tcon;
server->tcpStatus = CifsNeedReconnect;
server->maxBuf = 0;
cFYI(1, ("Reconnecting tcp session "));
+ /* before reconnecting the tcp session, mark the smb session (uid)
+ and the tid bad so they are not used until reconnected */
read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
if (ses->server) {
if (ses->server == server) {
ses->status = CifsNeedReconnect;
+ ses->ipc_tid = 0;
}
}
/* else tcp and smb sessions need reconnection */
}
+ list_for_each(tmp, &GlobalTreeConnectionList) {
+ tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+ if(tcon->ses->server == server) {
+ tcon->tidStatus = CifsNeedReconnect;
+ }
+ }
read_unlock(&GlobalSMBSeslock);
if(server->ssocket) {
@@ -112,6 +122,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
schedule_timeout(3 * HZ);
} else {
server->tcpStatus = CifsGood;
+ wake_up(&server->response_q);
}
}
@@ -174,15 +185,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
csocket = server->ssocket;
continue;
} else { /* find define for the -512 returned at unmount time */
- cFYI(1,
- ("Received error on sock_recvmsg( peek) with length = %d",
+ cFYI(1,("Error on sock_recvmsg(peek) length = %d",
length));
}
break;
- }
- if (length == 0) {
- cFYI(1,
- ("Zero length peek received - dead session?"));
+ } else if (length == 0) {
+ cFYI(1,("Zero length peek received - dead session?"));
cifs_reconnect(server);
csocket = server->ssocket;
continue;
@@ -507,8 +515,7 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName)
/* BB lock tcon and server and tcp session and increment use count here? */
/* found a match on the TCP session */
/* BB check if reconnection needed */
- cFYI(1,
- ("Matched ip, old UNC: %s == new: %s ?",
+ cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
tcon->treeName, uncName));
if (strncmp
(tcon->treeName, uncName,
@@ -855,9 +862,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
FreeXid(xid);
return -ENODEV;
} else {
- rc = CIFSTCon(xid, pSesInfo,
- volume_info.UNC,
- tcon, cifs_sb->local_nls);
+ rc = CIFSTCon(xid, pSesInfo,
+ volume_info.UNC,
+ tcon, cifs_sb->local_nls);
cFYI(1, ("CIFS Tcon rc = %d", rc));
}
if (!rc)
@@ -2196,6 +2203,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
/* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
/* above now done in SendReceive */
if ((rc == 0) && (tcon != NULL)) {
+ tcon->tidStatus = CifsGood;
tcon->tid = smb_buffer_response->Tid;
bcc_ptr = pByteArea(smb_buffer_response);
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0510f8184037..03aa43894f23 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -423,6 +423,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
return rc;
}
+#if 0
static int
cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
{
@@ -434,6 +435,7 @@ cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
FreeXid(xid);
return rc;
}
+#endif
static int
cifs_writepage(struct page* page, struct writeback_control *wbc)
@@ -635,7 +637,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
}
page_cache_get(page);
- target = kmap(page);
+ target = kmap_atomic(page,KM_USER0);
if(PAGE_CACHE_SIZE > bytes_read) {
memcpy(target,data,bytes_read);
@@ -649,7 +651,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
__pagevec_lru_add(plru_pvec);
flush_dcache_page(page);
SetPageUptodate(page);
- kunmap(page);
+ kunmap_atomic(page,KM_USER0);
unlock_page(page);
page_cache_release(page);
data += PAGE_CACHE_SIZE;
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 400bca121f4d..02a235ee9442 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -70,6 +70,7 @@ sesInfoAlloc(void)
memset(ret_buf, 0, sizeof (struct cifsSesInfo));
write_lock(&GlobalSMBSeslock);
atomic_inc(&sesInfoAllocCount);
+ ret_buf->status = CifsNew;
list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList);
init_MUTEX(&ret_buf->sesSem);
write_unlock(&GlobalSMBSeslock);
@@ -111,6 +112,7 @@ tconInfoAlloc(void)
atomic_inc(&tconInfoAllocCount);
list_add(&ret_buf->cifsConnectionList,
&GlobalTreeConnectionList);
+ ret_buf->tidStatus = CifsNew;
INIT_LIST_HEAD(&ret_buf->openFileList);
init_MUTEX(&ret_buf->tconSem);
write_unlock(&GlobalSMBSeslock);
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 56936ef0e07e..aad3a7b4aac8 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -37,6 +37,7 @@ struct mid_q_entry *
AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
{
struct mid_q_entry *temp;
+ int timeout = 10 * HZ;
/* BB add spinlock to protect midq for each session BB */
if (ses == NULL) {
@@ -57,13 +58,22 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->ses = ses;
temp->tsk = current;
}
+
+ while ((ses->server->tcpStatus != CifsGood) && (timeout > 0)){
+ /* Give the tcp thread up to 10 seconds to reconnect */
+ /* Should we wake up tcp thread first? BB */
+ timeout = wait_event_interruptible_timeout(ses->server->response_q,
+ (ses->server->tcpStatus == CifsGood), timeout);
+ cFYI(1,("timeout (after reconnection wait) %d",timeout));
+ }
+
if (ses->server->tcpStatus == CifsGood) {
write_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
atomic_inc(&midCount);
temp->midState = MID_REQUEST_ALLOCATED;
write_unlock(&GlobalMid_Lock);
- } else { /* could add more reconnect code here BB */
+ } else {
cERROR(1,("Need to reconnect after session died to server"));
if (temp)
kmem_cache_free(cifs_mid_cachep, temp);
@@ -106,16 +116,16 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
smb_msg.msg_iovlen = 1;
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
- smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags? */
+ smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
- /* smb header is converted in header_assemble. bcc and rest of SMB word area,
- and byte area if necessary, is converted to littleendian in cifssmb.c and RFC1001
- len is converted to bigendian in smb_send */
+ /* smb header is converted in header_assemble. bcc and rest of SMB word
+ area, and byte area if necessary, is converted to littleendian in
+ cifssmb.c and RFC1001 len is converted to bigendian in smb_send */
if (smb_buf_length > 12)
smb_buffer->Flags2 = cpu_to_le16(smb_buffer->Flags2);
- /* if(smb_buffer->Flags2 & SMBFLG2_SECURITY_SIGNATURE)
- sign_smb(smb_buffer); */ /* BB enable when signing tested more */
+ /* if(smb_buffer->Flags2 & SMBFLG2_SECURITY_SIGNATURE)
+ sign_smb(smb_buffer); */ /* BB enable when signing tested more */
smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
cFYI(1, ("Sending smb of length %d ", smb_buf_length));
@@ -148,7 +158,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
midQ = AllocMidQEntry(in_buf, ses);
if (midQ == NULL)
- return -EIO; /* reconnect should be done, if possible, in AllocMidQEntry */
+ return -EIO;
if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1,
("Illegal length, greater than maximum frame, %d ",
@@ -219,7 +229,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
*pbytes_returned = out_buf->smb_buf_length;
/* BB special case reconnect tid and reconnect uid here? */
- rc = map_smb_to_linux_error(out_buf); /* BB watch endianness here BB */
+ rc = map_smb_to_linux_error(out_buf);
/* convert ByteCount if necessary */
if (receive_len >=