Commit 6ab007bf authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://cifs.bkbits.net/linux-2.5cifs

into home.transmeta.com:/home/torvalds/v2.5/linux
parents af61a2bd 6c1f0746
......@@ -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 */
......
......@@ -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,
......
......@@ -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;
......@@ -248,7 +260,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
}
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 */ ,
rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */,
(void **) &pSMB, (void **) &smb_buffer_response);
if (rc) {
up(&ses->sesSem);
......@@ -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)
......@@ -447,13 +459,14 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
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 */
/* 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,
......@@ -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),
(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));
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 */
......
......@@ -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,
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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,11 +116,11 @@ 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);
......@@ -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 >=
......
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