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 { ...@@ -170,7 +170,7 @@ struct cifsTconInfo {
struct list_head openFileList; struct list_head openFileList;
struct semaphore tconSem; struct semaphore tconSem;
struct cifsSesInfo *ses; /* pointer to session associated with */ 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; char *nativeFileSystem;
__u16 tid; /* The 2 byte transaction id */ __u16 tid; /* The 2 byte transaction id */
__u16 Flags; /* optional support bits */ __u16 Flags; /* optional support bits */
......
...@@ -93,26 +93,26 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -93,26 +93,26 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
const char *tree, struct cifsTconInfo *tcon, const char *tree, struct cifsTconInfo *tcon,
const struct nls_table *); 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, const char *searchName,
FILE_DIRECTORY_INFO * findData, FILE_DIRECTORY_INFO * findData,
T2_FFIRST_RSP_PARMS * findParms, T2_FFIRST_RSP_PARMS * findParms,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int *pUnicodeFlag, int *pUnicodeFlag,
int *pUnixFlag /* if Unix extensions used */ ); 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, FILE_DIRECTORY_INFO * findData,
T2_FNEXT_RSP_PARMS * findParms, T2_FNEXT_RSP_PARMS * findParms,
const __u16 searchHandle, const __u32 resumeKey, const __u16 searchHandle, const __u32 resumeKey,
int *UnicodeFlag, int *pUnixFlag); 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, const unsigned char *searchName,
FILE_ALL_INFO * findData, FILE_ALL_INFO * findData,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQPathInfo(const int xid, extern int CIFSSMBUnixQPathInfo(const int xid,
const struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_UNIX_BASIC_INFO * pFindData, FILE_UNIX_BASIC_INFO * pFindData,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
...@@ -127,7 +127,7 @@ extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, ...@@ -127,7 +127,7 @@ extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path, const char *old_path,
const struct nls_table *nls_codepage); 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, struct statfs *FSData,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQFSAttributeInfo(const int xid, extern int CIFSSMBQFSAttributeInfo(const int xid,
...@@ -150,57 +150,57 @@ extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, ...@@ -150,57 +150,57 @@ extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
char *full_path, __u64 mode, __u64 uid, char *full_path, __u64 mode, __u64 uid,
__u64 gid, const struct nls_table *nls_codepage); __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 char *newName,
const struct nls_table *nls_codepage); 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); 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 char *name,
const struct nls_table *nls_codepage); 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 char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSCreateHardLink(const int xid, extern int CIFSCreateHardLink(const int xid,
const struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSUnixCreateHardLink(const int xid, extern int CIFSUnixCreateHardLink(const int xid,
const struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSUnixCreateSymLink(const int xid, extern int CIFSUnixCreateSymLink(const int xid,
const struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQuerySymLink(const int xid, extern int CIFSSMBUnixQuerySymLink(const int xid,
const struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *syminfo, const int buflen, char *syminfo, const int buflen,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQueryReparseLinkInfo(const int xid, extern int CIFSSMBQueryReparseLinkInfo(const int xid,
const struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *symlinkinfo, const int buflen, __u16 fid, char *symlinkinfo, const int buflen, __u16 fid,
const struct nls_table *nls_codepage); 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 char *fileName, const int disposition,
const int access_flags, const int omode, const int access_flags, const int omode,
__u16 * netfid, int *pOplock, __u16 * netfid, int *pOplock,
const struct nls_table *nls_codepage); 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); 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 int netfid, unsigned int count,
const __u64 lseek, unsigned int *nbytes, char **buf); 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 int netfid, const unsigned int count,
const __u64 lseek, unsigned int *nbytes, const __u64 lseek, unsigned int *nbytes,
const char *buf, const int long_op); 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 __u16 netfid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
......
This diff is collapsed.
...@@ -76,22 +76,32 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -76,22 +76,32 @@ cifs_reconnect(struct TCP_Server_Info *server)
int rc = 0; int rc = 0;
struct list_head *tmp; struct list_head *tmp;
struct cifsSesInfo *ses; struct cifsSesInfo *ses;
struct cifsTconInfo *tcon;
server->tcpStatus = CifsNeedReconnect; server->tcpStatus = CifsNeedReconnect;
server->maxBuf = 0; server->maxBuf = 0;
cFYI(1, ("Reconnecting tcp session ")); 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); read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalSMBSessionList) { list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
if (ses->server) { if (ses->server) {
if (ses->server == server) { if (ses->server == server) {
ses->status = CifsNeedReconnect; ses->status = CifsNeedReconnect;
ses->ipc_tid = 0;
} }
} }
/* else tcp and smb sessions need reconnection */ /* 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); read_unlock(&GlobalSMBSeslock);
if(server->ssocket) { if(server->ssocket) {
...@@ -112,6 +122,7 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -112,6 +122,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
schedule_timeout(3 * HZ); schedule_timeout(3 * HZ);
} else { } else {
server->tcpStatus = CifsGood; server->tcpStatus = CifsGood;
wake_up(&server->response_q);
} }
} }
...@@ -174,15 +185,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -174,15 +185,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
csocket = server->ssocket; csocket = server->ssocket;
continue; continue;
} else { /* find define for the -512 returned at unmount time */ } else { /* find define for the -512 returned at unmount time */
cFYI(1, cFYI(1,("Error on sock_recvmsg(peek) length = %d",
("Received error on sock_recvmsg( peek) with length = %d",
length)); length));
} }
break; break;
} } else if (length == 0) {
if (length == 0) { cFYI(1,("Zero length peek received - dead session?"));
cFYI(1,
("Zero length peek received - dead session?"));
cifs_reconnect(server); cifs_reconnect(server);
csocket = server->ssocket; csocket = server->ssocket;
continue; continue;
...@@ -507,8 +515,7 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName) ...@@ -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? */ /* BB lock tcon and server and tcp session and increment use count here? */
/* found a match on the TCP session */ /* found a match on the TCP session */
/* BB check if reconnection needed */ /* BB check if reconnection needed */
cFYI(1, cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
("Matched ip, old UNC: %s == new: %s ?",
tcon->treeName, uncName)); tcon->treeName, uncName));
if (strncmp if (strncmp
(tcon->treeName, uncName, (tcon->treeName, uncName,
...@@ -2196,6 +2203,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2196,6 +2203,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
/* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */ /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
/* above now done in SendReceive */ /* above now done in SendReceive */
if ((rc == 0) && (tcon != NULL)) { if ((rc == 0) && (tcon != NULL)) {
tcon->tidStatus = CifsGood;
tcon->tid = smb_buffer_response->Tid; tcon->tid = smb_buffer_response->Tid;
bcc_ptr = pByteArea(smb_buffer_response); bcc_ptr = pByteArea(smb_buffer_response);
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
......
...@@ -423,6 +423,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to) ...@@ -423,6 +423,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
return rc; return rc;
} }
#if 0
static int static int
cifs_writepages(struct address_space *mapping, struct writeback_control *wbc) cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
{ {
...@@ -434,6 +435,7 @@ 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); FreeXid(xid);
return rc; return rc;
} }
#endif
static int static int
cifs_writepage(struct page* page, struct writeback_control *wbc) cifs_writepage(struct page* page, struct writeback_control *wbc)
...@@ -635,7 +637,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping, ...@@ -635,7 +637,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
} }
page_cache_get(page); page_cache_get(page);
target = kmap(page); target = kmap_atomic(page,KM_USER0);
if(PAGE_CACHE_SIZE > bytes_read) { if(PAGE_CACHE_SIZE > bytes_read) {
memcpy(target,data,bytes_read); memcpy(target,data,bytes_read);
...@@ -649,7 +651,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping, ...@@ -649,7 +651,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
__pagevec_lru_add(plru_pvec); __pagevec_lru_add(plru_pvec);
flush_dcache_page(page); flush_dcache_page(page);
SetPageUptodate(page); SetPageUptodate(page);
kunmap(page); kunmap_atomic(page,KM_USER0);
unlock_page(page); unlock_page(page);
page_cache_release(page); page_cache_release(page);
data += PAGE_CACHE_SIZE; data += PAGE_CACHE_SIZE;
......
...@@ -70,6 +70,7 @@ sesInfoAlloc(void) ...@@ -70,6 +70,7 @@ sesInfoAlloc(void)
memset(ret_buf, 0, sizeof (struct cifsSesInfo)); memset(ret_buf, 0, sizeof (struct cifsSesInfo));
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
atomic_inc(&sesInfoAllocCount); atomic_inc(&sesInfoAllocCount);
ret_buf->status = CifsNew;
list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList); list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList);
init_MUTEX(&ret_buf->sesSem); init_MUTEX(&ret_buf->sesSem);
write_unlock(&GlobalSMBSeslock); write_unlock(&GlobalSMBSeslock);
...@@ -111,6 +112,7 @@ tconInfoAlloc(void) ...@@ -111,6 +112,7 @@ tconInfoAlloc(void)
atomic_inc(&tconInfoAllocCount); atomic_inc(&tconInfoAllocCount);
list_add(&ret_buf->cifsConnectionList, list_add(&ret_buf->cifsConnectionList,
&GlobalTreeConnectionList); &GlobalTreeConnectionList);
ret_buf->tidStatus = CifsNew;
INIT_LIST_HEAD(&ret_buf->openFileList); INIT_LIST_HEAD(&ret_buf->openFileList);
init_MUTEX(&ret_buf->tconSem); init_MUTEX(&ret_buf->tconSem);
write_unlock(&GlobalSMBSeslock); write_unlock(&GlobalSMBSeslock);
......
...@@ -37,6 +37,7 @@ struct mid_q_entry * ...@@ -37,6 +37,7 @@ struct mid_q_entry *
AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
{ {
struct mid_q_entry *temp; struct mid_q_entry *temp;
int timeout = 10 * HZ;
/* BB add spinlock to protect midq for each session BB */ /* BB add spinlock to protect midq for each session BB */
if (ses == NULL) { if (ses == NULL) {
...@@ -57,13 +58,22 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -57,13 +58,22 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->ses = ses; temp->ses = ses;
temp->tsk = current; 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) { if (ses->server->tcpStatus == CifsGood) {
write_lock(&GlobalMid_Lock); write_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &ses->server->pending_mid_q); list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
atomic_inc(&midCount); atomic_inc(&midCount);
temp->midState = MID_REQUEST_ALLOCATED; temp->midState = MID_REQUEST_ALLOCATED;
write_unlock(&GlobalMid_Lock); write_unlock(&GlobalMid_Lock);
} else { /* could add more reconnect code here BB */ } else {
cERROR(1,("Need to reconnect after session died to server")); cERROR(1,("Need to reconnect after session died to server"));
if (temp) if (temp)
kmem_cache_free(cifs_mid_cachep, temp); kmem_cache_free(cifs_mid_cachep, temp);
...@@ -106,11 +116,11 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -106,11 +116,11 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
smb_msg.msg_iovlen = 1; smb_msg.msg_iovlen = 1;
smb_msg.msg_control = NULL; smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0; 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, /* smb header is converted in header_assemble. bcc and rest of SMB word
and byte area if necessary, is converted to littleendian in cifssmb.c and RFC1001 area, and byte area if necessary, is converted to littleendian in
len is converted to bigendian in smb_send */ cifssmb.c and RFC1001 len is converted to bigendian in smb_send */
if (smb_buf_length > 12) if (smb_buf_length > 12)
smb_buffer->Flags2 = cpu_to_le16(smb_buffer->Flags2); smb_buffer->Flags2 = cpu_to_le16(smb_buffer->Flags2);
...@@ -148,7 +158,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -148,7 +158,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
midQ = AllocMidQEntry(in_buf, ses); midQ = AllocMidQEntry(in_buf, ses);
if (midQ == NULL) 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) { if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1, cERROR(1,
("Illegal length, greater than maximum frame, %d ", ("Illegal length, greater than maximum frame, %d ",
...@@ -219,7 +229,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -219,7 +229,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
*pbytes_returned = out_buf->smb_buf_length; *pbytes_returned = out_buf->smb_buf_length;
/* BB special case reconnect tid and reconnect uid here? */ /* 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 */ /* convert ByteCount if necessary */
if (receive_len >= 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