bk://cifs.bkbits.net/linux-2.5cifs
cifs.adm@bkbits.net|ChangeSet|20050302235253|07945 cifs.adm

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/01/29 12:21:23-08:00 cifs.adm@bkbits.net 
#   Merge bk://linux.bkbits.net/linux-2.5
#   into bkbits.net:/repos/c/cifs/linux-2.5cifs
# 
# fs/cifs/connect.c
#   2005/01/29 12:21:17-08:00 cifs.adm@bkbits.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/26 17:30:51-06:00 stevef@stevef95.austin.ibm.com 
#   [CIFS] Add support for updating Windows NT times/dates (part 1)
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/inode.c
#   2005/01/26 17:30:40-06:00 stevef@stevef95.austin.ibm.com +5 -6
#   Add support for updating Windows NT times/dates
# 
# fs/cifs/cifssmb.c
#   2005/01/26 17:30:40-06:00 stevef@stevef95.austin.ibm.com +6 -3
#   Add support for updating Windows NT times/dates
# 
# fs/cifs/cifspdu.h
#   2005/01/26 17:30:40-06:00 stevef@stevef95.austin.ibm.com +25 -10
#   Add support for updating Windows NT times/dates
# 
# ChangeSet
#   2005/01/20 21:37:57-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   [CIFS] misc cleanup - compare pointers to NULL not zero
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/connect.c
#   2005/01/20 21:37:49-06:00 sfrench@sambaltcdom.austin.ibm.com +7 -7
#   compare pointers to NULL not zero
# 
# fs/cifs/cifssmb.c
#   2005/01/20 21:37:49-06:00 sfrench@sambaltcdom.austin.ibm.com +3 -3
#   compare pointers to NULL not zero
# 
# fs/cifs/asn1.c
#   2005/01/20 21:37:49-06:00 sfrench@sambaltcdom.austin.ibm.com +1 -1
#   compare pointers to NULL not zero
# 
# ChangeSet
#   2005/01/17 20:08:33-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   [CIFS] Fix length check for short smbs in cifs demultiplexing and remove unneeded debug messages
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/connect.c
#   2005/01/17 20:08:24-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -4
#   Fix length check for short smbs in cifs demultiplexing.  Remove unneeded debug messages
# 
# ChangeSet
#   2005/01/17 08:36:45-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   [CIFS] get rid of tcp peek usage on cifs socket. Makes more sense to read normally
#   first four bytes off the socket (then read the rest of the frame) rather than peek 
#   first few bytes then read because we were having to retry the peek multiple times
#   when peek would return less than four bytes and four bytes is the minimum we 
#   ever get.
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/transport.c
#   2005/01/17 08:36:36-06:00 sfrench@sambaltcdom.austin.ibm.com +66 -1
#   get rid of tcp peek usage on cifs socket
# 
# fs/cifs/connect.c
#   2005/01/17 08:36:36-06:00 sfrench@sambaltcdom.austin.ibm.com +27 -59
#   Add new send function (part 1) to avoid extra memcopy in smb sending
# 
# ChangeSet
#   2005/01/17 08:29:15-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   [CIFS] remove old cifs_readdir routine
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/readdir.c
#   2005/01/17 08:29:06-06:00 sfrench@sambaltcdom.austin.ibm.com +3 -3
#   remove old readdir routines
# 
# fs/cifs/file.c
#   2005/01/17 08:29:06-06:00 sfrench@sambaltcdom.austin.ibm.com +5 -598
#   remove old readdir routines
# 
# fs/cifs/CHANGES
#   2005/01/17 08:29:06-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -1
#   Update cifs changelog
# 
# ChangeSet
#   2005/01/09 08:20:07-08:00 cifs.adm@bkbits.net 
#   Merge bk://linux.bkbits.net/linux-2.5
#   into bkbits.net:/repos/c/cifs/linux-2.5cifs
# 
# fs/cifs/cifsfs.c
#   2005/01/09 08:20:01-08:00 cifs.adm@bkbits.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/05 15:06:36-08:00 cifs.adm@bkbits.net 
#   Merge bk://linux.bkbits.net/linux-2.5
#   into bkbits.net:/repos/c/cifs/linux-2.5cifs
# 
# fs/cifs/file.c
#   2005/01/05 15:06:29-08:00 cifs.adm@bkbits.net +0 -0
#   Auto merged
# 
# fs/cifs/connect.c
#   2005/01/05 15:06:28-08:00 cifs.adm@bkbits.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/04 18:11:57-06:00 stevef@stevef95.austin.ibm.com 
#   [CIFS] Fix default mode on cifs module parms in sysfs
#   
#   Pointed out by Domen Puncer
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/cifsfs.h
#   2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +1 -1
#   update cifs contributors
# 
# fs/cifs/cifsfs.c
#   2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +4 -4
#   Fix default mode on cifs module parms in sysfs
# 
# fs/cifs/CHANGES
#   2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +6 -1
#   update to cifs version 1.29
# 
# fs/cifs/AUTHORS
#   2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +2 -0
#   update cifs contributors
# 
# ChangeSet
#   2004/12/22 12:11:36-06:00 stevef@smfhome.smfdom 
#   [CIFS] Fix whitespace
#   
#   Signed-off-by:  Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/cifssmb.c
#   2004/12/22 12:11:27-06:00 stevef@smfhome.smfdom +3 -3
#   Fix whitespace
# 
# ChangeSet
#   2004/12/21 11:08:59-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   [CIFS] Enable reads over 64K by setting large read and write capability at SMB session negotiation
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/connect.c
#   2004/12/21 11:08:51-06:00 sfrench@sambaltcdom.austin.ibm.com +1 -1
#   Enable reads over 64K by setting large read and write capability at SMB session negotiation
# 
# ChangeSet
#   2004/12/19 10:19:16-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   [CIFS] Fix set of mount option rsize so it can be set above negotiated buffer size.
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/connect.c
#   2004/12/19 10:19:08-06:00 sfrench@sambaltcdom.austin.ibm.com +1 -1
#   Fix set of mount option rsize so it can be set above negotiated buffer size.
# 
# ChangeSet
#   2004/12/18 16:01:31-06:00 sfrench@sambaltcdom.austin.ibm.com 
#   check rc of copy_to_user (pointed out by John Cherry)
#   fix wsize mount parm so it works to control writes
#   allow reads bigger than 64K (although Samba does not handle them yet).
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/file.c
#   2004/12/18 16:01:12-06:00 sfrench@sambaltcdom.austin.ibm.com +14 -10
#   check rc of copy_to_user to fix warning pointed out by John Cherry
# 
# fs/cifs/connect.c
#   2004/12/18 16:01:12-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -2
#   adjust wsize default, and fix wsize mount parm so it is used
# 
# fs/cifs/cifssmb.c
#   2004/12/18 16:01:12-06:00 sfrench@sambaltcdom.austin.ibm.com +39 -22
#   misc large read/write fixes, for sizes > 64K
# 
# fs/cifs/cifspdu.h
#   2004/12/18 16:01:11-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -2
#   Definition of write frame missing high offset of count field.
# 
diff -Nru a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS
--- a/fs/cifs/AUTHORS	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/AUTHORS	2005-03-03 21:52:21 -08:00
@@ -25,6 +25,8 @@
 Richard Hughes
 Yury Umanets
 Mark Hamzy
+Domen Puncer
+Jesper Juhl
 
 Test case and Bug Report contributors
 -------------------------------------
diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES
--- a/fs/cifs/CHANGES	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/CHANGES	2005-03-03 21:52:21 -08:00
@@ -1,3 +1,8 @@
+Version 1.29
+------------
+Fix default mode in sysfs of cifs module parms.  Remove old readdir routine.
+Fix capabilities flags for large readx so as to allow reads larger than 64K.
+
 Version 1.28
 ------------
 Add module init parm for large SMB buffer size (to allow it to be changed
@@ -7,7 +12,8 @@
 SpnegoNegotiated returning invalid error. Fix case to retry better when 
 peek returns from 1 to 3 bytes on socket which should have more data.
 Fixed path based calls (such as cifs lookup) to handle path names
-longer than 530 (now can handle PATH_MAX).
+longer than 530 (now can handle PATH_MAX). Fix pass through authentication
+from Samba server to DC (Samba required dummy LM password).
 
 Version 1.27
 ------------
diff -Nru a/fs/cifs/asn1.c b/fs/cifs/asn1.c
--- a/fs/cifs/asn1.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/asn1.c	2005-03-03 21:52:21 -08:00
@@ -210,7 +210,7 @@
 {
 	unsigned char ch;
 
-	if (eoc == 0) {
+	if (eoc == NULL) {
 		if (!asn1_octet_decode(ctx, &ch))
 			return 0;
 
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/cifsfs.c	2005-03-03 21:52:21 -08:00
@@ -59,16 +59,16 @@
 unsigned int sign_CIFS_PDUs = 1;
 struct task_struct * oplockThread = NULL;
 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
-module_param(CIFSMaxBufSize, int, CIFS_MAX_MSGSIZE);
+module_param(CIFSMaxBufSize, int, 0);
 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
 unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
-module_param(cifs_min_rcv, int, CIFS_MIN_RCV_POOL);
+module_param(cifs_min_rcv, int, 0);
 MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64");
 unsigned int cifs_min_small = 30;
-module_param(cifs_min_small, int, 30);
+module_param(cifs_min_small, int, 0);
 MODULE_PARM_DESC(cifs_small_rcv,"Small network buffers in pool. Default: 30 Range: 2 to 256");
 unsigned int cifs_max_pending = CIFS_MAX_REQ;
-module_param(cifs_max_pending, int, CIFS_MAX_REQ);
+module_param(cifs_max_pending, int, 0);
 MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
 
 
diff -Nru a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
--- a/fs/cifs/cifsfs.h	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/cifsfs.h	2005-03-03 21:52:21 -08:00
@@ -90,5 +90,5 @@
 			 size_t, int);
 extern ssize_t	cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
-#define CIFS_VERSION   "1.28"
+#define CIFS_VERSION   "1.29"
 #endif				/* _CIFSFS_H */
diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
--- a/fs/cifs/cifspdu.h	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/cifspdu.h	2005-03-03 21:52:21 -08:00
@@ -568,7 +568,6 @@
 #define SMB_SHARE_IS_IN_DFS     0x0002
 
 typedef struct smb_com_logoff_andx_req {
-
 	struct smb_hdr hdr;	/* wct = 2 */
 	__u8 AndXCommand;
 	__u8 AndXReserved;
@@ -695,7 +694,8 @@
 	__le16 AndXOffset;
 	__le16 Count;
 	__le16 Remaining;
-	__le32 Reserved;
+	__le16 CountHigh;
+	__u16  Reserved;
 	__u16 ByteCount;
 } WRITE_RSP;
 
@@ -1592,17 +1592,32 @@
 	char LinkDest[1];
 } FILE_UNIX_LINK_INFO;		/* level 0x201 QPathInfo */
 
+/* The following three structures are needed only for
+	setting time to NT4 and some older servers via
+	the primitive DOS time format */
+typedef struct {
+	__u16 Day:5;
+	__u16 Month:4;
+	__u16 Year:7;
+} SMB_DATE;
+
 typedef struct {
-	__u16 CreationDate;
-	__u16 CreationTime;
-	__u16 LastAccessDate;
-	__u16 LastAccessTime;
-	__u16 LastWriteDate;
-	__u16 LastWriteTime;
-	__u32 DataSize; /* File Size (EOF) */
-	__u32 AllocationSize;
-	__u16 Attributes; /* verify not u32 */
-	__u32 EASize;
+	__u16 TwoSeconds:5;
+	__u16 Minutes:6;
+	__u16 Hours:5;
+} SMB_TIME;
+
+typedef struct {
+	__le16 CreationDate; /* SMB Date see above */
+	__le16 CreationTime; /* SMB Time */
+	__le16 LastAccessDate;
+	__le16 LastAccessTime;
+	__le16 LastWriteDate;
+	__le16 LastWriteTime;
+	__le32 DataSize; /* File Size (EOF) */
+	__le32 AllocationSize;
+	__le16 Attributes; /* verify not u32 */
+	__le32 EASize;
 } FILE_INFO_STANDARD;  /* level 1 SetPath/FileInfo */
 
 typedef struct {
diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
--- a/fs/cifs/cifssmb.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/cifssmb.c	2005-03-03 21:52:21 -08:00
@@ -154,7 +154,7 @@
 		return rc;
 
 	*request_buf = cifs_small_buf_get();
-	if (*request_buf == 0) {
+	if (*request_buf == NULL) {
 		/* BB should we add a retry in here if not a writepage? */
 		return -ENOMEM;
 	}
@@ -246,7 +246,7 @@
 		return rc;
 
 	*request_buf = cifs_buf_get();
-	if (*request_buf == 0) {
+	if (*request_buf == NULL) {
 		/* BB should we add a retry in here if not a writepage? */
 		return -ENOMEM;
 	}
@@ -448,7 +448,7 @@
 		return 0;  
 	}
 
-	if((tcon->ses == 0) || (tcon->ses->server == 0)) {    
+	if((tcon->ses == NULL) || (tcon->ses->server == NULL)) {    
 		up(&tcon->tconSem);
 		return -EIO;
 	}
@@ -802,6 +802,8 @@
 	char *pReadData = NULL;
 	int bytes_returned;
 
+	cFYI(1,("Reading %d bytes on fid %d",count,netfid));
+
 	*nbytes = 0;
 	rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
 		      (void **) &pSMBr);
@@ -817,8 +819,8 @@
 	pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
 	pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
 	pSMB->Remaining = 0;
-	pSMB->MaxCount = cpu_to_le16(count);
-	pSMB->MaxCountHigh = 0;
+	pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
+	pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
 	pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */
 
 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -826,8 +828,11 @@
 	if (rc) {
 		cERROR(1, ("Send error in read = %d", rc));
 	} else {
-		__u16 data_length = le16_to_cpu(pSMBr->DataLength);
+		int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
+		data_length = data_length << 16;
+		data_length += le16_to_cpu(pSMBr->DataLength);
 		*nbytes = data_length;
+
 		/*check that DataLength would not go beyond end of SMB */
 		if ((data_length > CIFSMaxBufSize) 
 				|| (data_length > count)) {
@@ -868,9 +873,10 @@
 	WRITE_REQ *pSMB = NULL;
 	WRITE_RSP *pSMBr = NULL;
 	int bytes_returned;
-	unsigned bytes_sent;
+	__u32 bytes_sent;
 	__u16 byte_count;
 
+	/* cFYI(1,("write at %lld %d bytes",offset,count));*/
 	rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
 		      (void **) &pSMBr);
 	if (rc)
@@ -886,31 +892,41 @@
 	pSMB->Reserved = 0xFFFFFFFF;
 	pSMB->WriteMode = 0;
 	pSMB->Remaining = 0;
-	/* BB can relax this if buffer is big enough in some cases - ie we can 
-	send more  if LARGE_WRITE_X capability returned by the server and if
+
+	/* Can increase buffer size if buffer is big enough in some cases - ie we 
+	can send more if LARGE_WRITE_X capability returned by the server and if
 	our buffer is big enough or if we convert to iovecs on socket writes
 	and eliminate the copy to the CIFS buffer */
-	bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
+	if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
+		bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
+	} else {
+		bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
+			 & ~0xFF;
+	}
+
 	if (bytes_sent > count)
 		bytes_sent = count;
-	pSMB->DataLengthHigh = 0;
 	pSMB->DataOffset =
 	    cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
-    if(buf)
+	if(buf)
 	    memcpy(pSMB->Data,buf,bytes_sent);
-	else if(ubuf)
-		copy_from_user(pSMB->Data,ubuf,bytes_sent);
-    else {
+	else if(ubuf) {
+		if(copy_from_user(pSMB->Data,ubuf,bytes_sent)) {
+			if(pSMB)
+				cifs_buf_release(pSMB);
+			return -EFAULT;
+		}
+	} else {
 		/* No buffer */
 		if(pSMB)
 			cifs_buf_release(pSMB);
 		return -EINVAL;
 	}
 
-	byte_count = bytes_sent + 1 /* pad */ ;
-	pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
-	pSMB->DataLengthHigh = 0;
-	pSMB->hdr.smb_buf_length += byte_count;
+	byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
+	pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
+	pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
+	pSMB->hdr.smb_buf_length += bytes_sent+1;
 	pSMB->ByteCount = cpu_to_le16(byte_count);
 
 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -918,8 +934,11 @@
 	if (rc) {
 		cFYI(1, ("Send error in write = %d", rc));
 		*nbytes = 0;
-	} else
-		*nbytes = le16_to_cpu(pSMBr->Count);
+	} else {
+		*nbytes = le16_to_cpu(pSMBr->CountHigh);
+		*nbytes = (*nbytes) << 16;
+		*nbytes += le16_to_cpu(pSMBr->Count);
+	}
 
 	if (pSMB)
 		cifs_buf_release(pSMB);
@@ -1913,14 +1932,13 @@
 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 			cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				/* BB fixme find define for this maxpathcomponent */
 				, nls_codepage);
 		name_len++;     /* trailing null */
 		name_len *= 2;
 		pSMB->FileName[name_len] = 0;
 		pSMB->FileName[name_len+1] = 0;
 	} else {                /* BB improve the check for buffer overruns BB */
-		name_len = strnlen(searchName, PATH_MAX /* BB fixme */);
+		name_len = strnlen(searchName, PATH_MAX);
 		name_len++;     /* trailing null */
 		strncpy(pSMB->FileName, searchName, name_len);
 	}
@@ -1996,10 +2014,9 @@
                       (void **) &pSMBr);
 	if (rc)
 		return rc;
-                                                                                                               	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
+	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 		name_len =
 			cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-				/* BB fixme find define for this maxpathcomponent */
 				, nls_codepage);
 		name_len++;     /* trailing null */
 		name_len *= 2;
@@ -2051,9 +2068,9 @@
 setACLerrorExit:
 	if (pSMB)
 		cifs_buf_release(pSMB);
-                                                                                                            	if (rc == -EAGAIN)
+	if (rc == -EAGAIN)
 		goto setAclRetry;
-                                                                                                           	return rc;
+	return rc;
 }
 
 #endif
@@ -2072,7 +2089,7 @@
 	int name_len;
 	__u16 params, byte_count;
 
-/* cFYI(1, ("In QPathInfo path %s", searchName)); */ /* BB fixme BB */
+/* cFYI(1, ("In QPathInfo path %s", searchName)); */
 QPathInfoRetry:
 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
 		      (void **) &pSMBr);
@@ -3574,10 +3591,11 @@
 
 int
 CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
-		FILE_INFO_STANDARD * data, const struct nls_table *nls_codepage)
+		FILE_BASIC_INFO * data, const struct nls_table *nls_codepage)
 {
 	TRANSACTION2_SPI_REQ *pSMB = NULL;
 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
+	FILE_INFO_STANDARD   *pfinfo;
 	int name_len;
 	int rc = 0;
 	int bytes_returned = 0;
@@ -3607,7 +3625,6 @@
 /* BB fixme - we have to map to FILE_STANDARD_INFO (level 1 info
 	in parent function, from the better and ususal FILE_BASIC_INFO */
 	params = 6 + name_len;
-	count = sizeof (FILE_INFO_STANDARD);
 	pSMB->MaxParameterCount = cpu_to_le16(2);
 	pSMB->MaxDataCount = cpu_to_le16(1000);	/* BB find exact max SMB PDU from sess structure BB */
 	pSMB->MaxSetupCount = 0;
@@ -3619,11 +3636,15 @@
                                      InformationLevel) - 4;
 	offset = param_offset + params;
 	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
+	pfinfo = (FILE_INFO_STANDARD *)data_offset;
+	/* BB add conversion for FILE_BASIC_INFO data struct to
+		 FILE_INFO_STANDARD finfo struct */
 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
 	pSMB->DataOffset = cpu_to_le16(offset);
 	pSMB->SetupCount = 1;
 	pSMB->Reserved3 = 0;
 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
+	count = sizeof(FILE_INFO_STANDARD);
 	byte_count = 3 /* pad */  + params + count;
 
 	pSMB->DataCount = cpu_to_le16(count);
@@ -3633,7 +3654,6 @@
 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
 	pSMB->Reserved4 = 0;
 	pSMB->hdr.smb_buf_length += byte_count;
-	memcpy(data_offset, data, sizeof (FILE_INFO_STANDARD));
 	pSMB->ByteCount = cpu_to_le16(byte_count);
 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c
--- a/fs/cifs/connect.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/connect.c	2005-03-03 21:52:21 -08:00
@@ -210,7 +210,7 @@
 	current->flags |= PF_MEMALLOC;
 	server->tsk = current;	/* save process info to wake at shutdown */
 	cFYI(1, ("Demultiplex PID: %d", current->pid));
-	write_lock(&GlobalSMBSeslock);
+	write_lock(&GlobalSMBSeslock); 
 	atomic_inc(&tcpSesAllocCount);
 	length = tcpSesAllocCount.counter;
 	write_unlock(&GlobalSMBSeslock);
@@ -233,17 +233,12 @@
 			continue;
 		}
 		iov.iov_base = smb_buffer;
-		iov.iov_len = sizeof (struct smb_hdr) - 1;	
-        /* 1 byte less above since wct is not always returned in error cases */
+		iov.iov_len = 4;
 		smb_msg.msg_control = NULL;
 		smb_msg.msg_controllen = 0;
-
 		length =
 		    kernel_recvmsg(csocket, &smb_msg,
-				   &iov, 1,
-				   sizeof (struct smb_hdr) -
-				   1 /* RFC1001 header and SMB header */ ,
-				   MSG_PEEK /* flags see socket.h */ );
+				 &iov, 1, 4, 0 /* BB see socket.h flags */);
 
 		if(server->tcpStatus == CifsExiting) {
 			break;
@@ -253,8 +248,7 @@
 			cFYI(1,("call to reconnect done"));
 			csocket = server->ssocket;
 			continue;
-		} else if ((length == -ERESTARTSYS) || (length == -EAGAIN)
-				|| ((length > 0) && (length <= 3)) ) {
+		} else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(1); /* minimum sleep to prevent looping
 				allowing socket to clear and app threads to set
@@ -277,26 +271,16 @@
 			csocket = server->ssocket;
 			wake_up(&server->response_q);
 			continue;
-		}
-
-		pdu_length = 4 + ntohl(smb_buffer->smb_buf_length);
+		} else if (length > 3) {
+			pdu_length = ntohl(smb_buffer->smb_buf_length);
 		/* Only read pdu_length after below checks for too short (due
 		   to e.g. int overflow) and too long ie beyond end of buf */
-		cFYI(1, ("Peek length rcvd: 0x%x beginning 0x%x)", length, pdu_length));
+			cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4));
 
-		temp = (char *) smb_buffer;
-		if (length > 3) {
+			temp = (char *) smb_buffer;
 			if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
-				iov.iov_base = smb_buffer;
-				iov.iov_len = 4;
-				length = kernel_recvmsg(csocket, &smb_msg,
-							&iov, 1, 4, 0);
 				cFYI(0,("Received 4 byte keep alive packet"));
 			} else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
-				iov.iov_base = smb_buffer;
-				iov.iov_len = 4;
-				length = kernel_recvmsg(csocket, &smb_msg,
-							&iov, 1, 4, 0);
 					cFYI(1,("Good RFC 1002 session rsp"));
 			} else if ((temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE)
 				   && (length == 5)) {
@@ -330,38 +314,22 @@
 				csocket = server->ssocket;
 				continue;
 			} else {
-				if (length < 16) {
-					/* We can not validate the SMB unless 
-					at least this much of SMB available
-					so give the socket time to copy
-					a few more bytes and retry */ 
-					set_current_state(TASK_INTERRUPTIBLE);
-					schedule_timeout(10);
-					continue;
-				} else if( (pdu_length >
-					CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
-				    || (pdu_length <
-					sizeof (struct smb_hdr) - 1)
-				    || (checkSMBhdr
-				     (smb_buffer, smb_buffer->Mid))) {
+				if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
+				    || (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
 					cERROR(1,
-					    ("Invalid size or format for SMB found with length %d and pdu_length %d",
-						length, pdu_length));
-					cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)+3);
-					/* could we fix this network corruption by finding next 
-						smb header (instead of killing the session) and
-						restart reading from next valid SMB found? */
+					    ("Invalid size SMB length %d and pdu_length %d",
+						length, pdu_length+4));
 					cifs_reconnect(server);
 					csocket = server->ssocket;
+					wake_up(&server->response_q);
 					continue;
-				} else {	/* length ok */
-
+				} else { /* length ok */
 					length = 0;
-					iov.iov_base = smb_buffer;
+					iov.iov_base = 4 + (char *)smb_buffer;
 					iov.iov_len = pdu_length;
 					for (total_read = 0; 
 					     total_read < pdu_length;
-					     total_read += length) {	
+					     total_read += length) {
 						length = kernel_recvmsg(csocket, &smb_msg, 
 							&iov, 1,
 							pdu_length - total_read, 0);
@@ -371,14 +339,16 @@
 								pdu_length - total_read));
 							cifs_reconnect(server);
 							csocket = server->ssocket;
+							wake_up(&server->response_q);
 							continue;
 						}
 					}
+					length += 4; /* account for rfc1002 hdr */
 				}
 
 				dump_smb(smb_buffer, length);
 				if (checkSMB
-				    (smb_buffer, smb_buffer->Mid, total_read)) {
+				    (smb_buffer, smb_buffer->Mid, total_read+4)) {
 					cERROR(1, ("Bad SMB Received "));
 					continue;
 				}
@@ -410,17 +380,13 @@
 				}
 			}
 		} else {
-			cFYI(0,
-			     ("Frame less than four bytes received  %d bytes long.",
+			cFYI(1,
+			    ("Frame less than four bytes received  %d bytes long.",
 			      length));
-			if (length > 0) {
-				length = kernel_recvmsg(csocket, &smb_msg,
-					&iov, 1,
-					length, 0);	/* throw away junk frame */
-				cFYI(1,
-				     (" with junk  0x%x in it ",
-				      *(__u32 *) smb_buffer));
-			}
+			cifs_reconnect(server);
+			csocket = server->ssocket;
+			wake_up(&server->response_q);
+			continue;
 		}
 	}
 	spin_lock(&GlobalMid_Lock);
@@ -845,7 +811,7 @@
 			return 1;
 		}
 	}
-	if(vol->UNCip == 0)
+	if(vol->UNCip == NULL)
 		vol->UNCip = &vol->UNC[2];
 
 	return 0;
@@ -1409,14 +1375,14 @@
     
 	/* search for existing tcon to this server share */
 	if (!rc) {
-		if((volume_info.rsize) && (volume_info.rsize + MAX_CIFS_HDR_SIZE < srvTcp->maxBuf))
+		if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
 			cifs_sb->rsize = volume_info.rsize;
 		else
 			cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
-		if((volume_info.wsize) && (volume_info.wsize + MAX_CIFS_HDR_SIZE < srvTcp->maxBuf))
+		if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize))
 			cifs_sb->wsize = volume_info.wsize;
 		else
-			cifs_sb->wsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
+			cifs_sb->wsize = CIFSMaxBufSize; /* default */
 		if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
 			cifs_sb->rsize = PAGE_CACHE_SIZE;
 			cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
@@ -1504,7 +1470,7 @@
 		 /* If find_unc succeeded then rc == 0 so we can not end */
 		if (tcon)  /* up accidently freeing someone elses tcon struct */
 			tconInfoFree(tcon);
-		if (existingCifsSes == 0) {
+		if (existingCifsSes == NULL) {
 			if (pSesInfo) {
 				if ((pSesInfo->server) && 
 				    (pSesInfo->status == CifsGood)) {
@@ -1575,7 +1541,7 @@
 	user = ses->userName;
 	domain = ses->domainName;
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == 0) {
+	if (smb_buffer == NULL) {
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
@@ -1592,7 +1558,7 @@
 	if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
 		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
-	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS;
+	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
 	if (ses->capabilities & CAP_UNICODE) {
 		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
 		capabilities |= CAP_UNICODE;
@@ -1828,7 +1794,7 @@
 	domain = ses->domainName;
 
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == 0) {
+	if (smb_buffer == NULL) {
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
@@ -2093,7 +2059,7 @@
 	domain = ses->domainName;
 	*pNTLMv2_flag = FALSE;
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == 0) {
+	if (smb_buffer == NULL) {
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
@@ -2435,7 +2401,7 @@
 	user = ses->userName;
 	domain = ses->domainName;
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == 0) {
+	if (smb_buffer == NULL) {
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
@@ -2809,7 +2775,7 @@
 		return -EIO;
 
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == 0) {
+	if (smb_buffer == NULL) {
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/file.c	2005-03-03 21:52:21 -08:00
@@ -35,8 +35,6 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 
-extern int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir); /* BB removeme BB */
-
 int
 cifs_open(struct inode *inode, struct file *file)
 {
@@ -680,10 +678,10 @@
 			}
 
 			rc = CIFSSMBWrite(xid, pTcon,
-				  open_file->netfid,
-				  write_size - total_written, *poffset,
-				  &bytes_written,
-				  NULL, write_data + total_written, long_op);
+				open_file->netfid,
+				min_t(const int,cifs_sb->wsize,write_size - total_written),
+				*poffset, &bytes_written,
+				NULL, write_data + total_written, long_op);
 		}
 		if (rc || (bytes_written == 0)) {
 			if (total_written)
@@ -800,10 +798,10 @@
 			}
 
 			rc = CIFSSMBWrite(xid, pTcon,
-				  open_file->netfid,
-				  write_size - total_written, *poffset,
-				  &bytes_written,
-				  write_data + total_written, NULL, long_op);
+				 open_file->netfid,
+				 min_t(const int,cifs_sb->wsize,write_size - total_written),
+				 *poffset,&bytes_written,
+				 write_data + total_written, NULL, long_op);
 		}
 		if (rc || (bytes_written == 0)) {
 			if (total_written)
@@ -945,7 +943,11 @@
 	int xid;
 
 	xid = GetXid();
-/* call 16K write then Setpageuptodate */
+
+    /* Find contiguous pages then iterate through repeating */
+/* call 16K write then Setpageuptodate or if LARGE_WRITE_X
+support then send larger writes via kevec so as to eliminate
+a memcpy */
 	FreeXid(xid);
 	return rc;
 }
@@ -1145,7 +1147,6 @@
 	if((file->f_flags & O_ACCMODE) == O_WRONLY) {
 		cFYI(1,("attempting read on write only file instance"));
 	}
-
 	for (total_read = 0,current_offset=read_data; read_size > total_read;
 				total_read += bytes_read,current_offset+=bytes_read) {
 		current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
@@ -1165,8 +1166,12 @@
 				 &bytes_read, &smb_read_data);
 
 			pSMBr = (struct smb_com_read_rsp *)smb_read_data;
-			copy_to_user(current_offset,smb_read_data + 4/* RFC1001 hdr*/
-				+ le16_to_cpu(pSMBr->DataOffset), bytes_read);
+			if(copy_to_user(current_offset,smb_read_data + 4/* RFC1001 hdr*/
+				+ le16_to_cpu(pSMBr->DataOffset), bytes_read)) {
+				rc = -EFAULT;
+				FreeXid(xid);
+				return rc;
+            }
 			if(smb_read_data) {
 				cifs_buf_release(smb_read_data);
 				smb_read_data = NULL;
@@ -1800,600 +1805,6 @@
 	return rc; 
 }
 
-static void reset_resume_key(struct file * dir_file, 
-				unsigned char * filename, 
-				unsigned int len,int Unicode,struct nls_table * nls_tab) {
-	struct cifsFileInfo *cifsFile;
-
-	cifsFile = (struct cifsFileInfo *)dir_file->private_data;
-	if(cifsFile == NULL)
-		return;
-	if(cifsFile->search_resume_name) {
-		kfree(cifsFile->search_resume_name);
-	}
-
-	if(Unicode) 
-		len *= 2;
-	cifsFile->resume_name_length = len;
-
-	cifsFile->search_resume_name = 
-		kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-
-	if(cifsFile->search_resume_name == NULL) {
-		cERROR(1,("failed new resume key allocate, length %d",
-				  cifsFile->resume_name_length));
-		return;
-	}
-	if(Unicode)
-		cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
-			filename, len, nls_tab);
-	else
-		memcpy(cifsFile->search_resume_name, filename, 
-		   cifsFile->resume_name_length);
-	cFYI(1,("Reset resume key to: %s with len %d",filename,len));
-	return;
-}
-
-
-
-static int
-cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
-	     struct file *file, filldir_t filldir, void *direntry)
-{
-	struct inode *tmp_inode;
-	struct dentry *tmp_dentry;
-	int object_type,rc;
-
-	pqstring->name = pfindData->FileName;
-	/* pqstring->len is already set by caller */
-
-	rc = construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
-	if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
-		return -ENOMEM;
-	}
-	fill_in_inode(tmp_inode, pfindData, &object_type);
-	if(rc) {
-		/* We have no reliable way to get inode numbers
-		from servers w/o Unix extensions yet so we can not set
-		i_ino from pfindData yet */
-
-		/* new inode created, let us hash it */
-		insert_inode_hash(tmp_inode);
-	} /* else if inode number changed do we rehash it? */
-	rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
-		tmp_inode->i_ino, object_type);
-	if(rc) {
-		/* due to readdir error we need to recalculate resume 
-		key so next readdir will restart on right entry */
-		cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName));
-	}
-	dput(tmp_dentry);
-	return rc;
-}
-
-static int
-cifs_filldir_unix(struct qstr *pqstring,
-		  FILE_UNIX_INFO * pUnixFindData, struct file *file,
-		  filldir_t filldir, void *direntry)
-{
-	struct inode *tmp_inode;
-	struct dentry *tmp_dentry;
-	int object_type, rc;
-
-	pqstring->name = pUnixFindData->FileName;
-	pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
-
-	rc = construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
-	if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
-		return -ENOMEM;
-	} 
-	if(rc) {
-		struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
-
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
-			tmp_inode->i_ino = 
-				(unsigned long)pUnixFindData->UniqueId;
-		}
-		insert_inode_hash(tmp_inode);
-	} /* else if i_ino has changed should we rehash it? */
-	unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
-	rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
-		file->f_pos, tmp_inode->i_ino, object_type);
-	if(rc) {
-		/* due to readdir error we need to recalculate resume 
-			key so next readdir will restart on right entry */
-		cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName));
-	}
-	dput(tmp_dentry);
-	return rc;
-}
-
-int
-cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
-{
-	int rc = 0;
-	int xid;
-	int Unicode = FALSE;
-	int UnixSearch = FALSE;
-	unsigned int bufsize, i;
-	__u16 searchHandle;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *pTcon;
-	struct cifsFileInfo *cifsFile = NULL;
-	char *full_path = NULL;
-	char *data;
-	struct qstr qstring;
-	T2_FFIRST_RSP_PARMS findParms;
-	T2_FNEXT_RSP_PARMS findNextParms;
-	FILE_DIRECTORY_INFO *pfindData;
-	FILE_DIRECTORY_INFO *lastFindData;
-	FILE_UNIX_INFO *pfindDataUnix;
-
-
-    /* BB removeme begin */
-	if(!experimEnabled)
-		return cifs_readdir2(file,direntry,filldir);
-    /* BB removeme end */
-
-
-	xid = GetXid();
-
-	if(file->f_dentry == NULL) {
-		rc = -EIO;
-		FreeXid(xid);
-		return rc;
-	}
-	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-	pTcon = cifs_sb->tcon;
-	bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE;
-	if(bufsize > CIFSMaxBufSize) {
-		rc = -EIO;
-		FreeXid(xid);
-		return rc;
-	}
-	data = kmalloc(bufsize, GFP_KERNEL);
-	pfindData = (FILE_DIRECTORY_INFO *) data;
-	if(data == NULL) {
-		rc = -ENOMEM;
-		FreeXid(xid);
-		return rc;
-	}
-	down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-	full_path = build_wildcard_path_from_dentry(file->f_dentry);
-	up(&file->f_dentry->d_sb->s_vfs_rename_sem);
-
-	if(full_path == NULL) {
-		kfree(data);
-		FreeXid(xid);
-		return -ENOMEM;
-	}
-	cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
-
-	switch ((int) file->f_pos) {
-	case 0:
-		if (filldir(direntry, ".", 1, file->f_pos,
-		     file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
-			cERROR(1, ("Filldir for current dir failed "));
-			break;
-		}
-		file->f_pos++;
-		/* fallthrough */
-	case 1:
-		if (filldir(direntry, "..", 2, file->f_pos,
-		     file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
-			cERROR(1, ("Filldir for parent dir failed "));
-			break;
-		}
-		file->f_pos++;
-		/* fallthrough */
-	case 2:
-		if (file->private_data != NULL) {
-			cifsFile =
-				(struct cifsFileInfo *) file->private_data;
-			if (cifsFile->srch_inf.endOfSearch) {
-				if(cifsFile->srch_inf.emptyDir) {
-					cFYI(1, ("End of search, empty dir"));
-					rc = 0;
-					break;
-				}
-			} else {
-				cifsFile->invalidHandle = TRUE;
-				CIFSFindClose(xid, pTcon, cifsFile->netfid);
-			}
-			if(cifsFile->search_resume_name) {
-				kfree(cifsFile->search_resume_name);
-				cifsFile->search_resume_name = NULL;
-			}
-		}
-		rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
-				&findParms, cifs_sb->local_nls,
-				&Unicode, &UnixSearch);
-		cFYI(1, ("Count: %d  End: %d ",
-			le16_to_cpu(findParms.SearchCount),
-			le16_to_cpu(findParms.EndofSearch)));
- 
-		if (rc == 0) {
-			__u16 count = le16_to_cpu(findParms.SearchCount);
-			searchHandle = findParms.SearchHandle;
-			if(file->private_data == NULL)
-				file->private_data =
-					kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
-			if (file->private_data) {
-				memset(file->private_data, 0,
-				       sizeof (struct cifsFileInfo));
-				cifsFile =
-				    (struct cifsFileInfo *) file->private_data;
-				cifsFile->netfid = searchHandle;
-				cifsFile->invalidHandle = FALSE;
-				init_MUTEX(&cifsFile->fh_sem);
-			} else {
-				rc = -ENOMEM;
-				break;
-			}
-
-			renew_parental_timestamps(file->f_dentry);
-			lastFindData = 
-				(FILE_DIRECTORY_INFO *) ((char *) pfindData + 
-					le16_to_cpu(findParms.LastNameOffset));
-			if((char *)lastFindData > (char *)pfindData + bufsize) {
-				cFYI(1,("last search entry past end of packet"));
-				rc = -EIO;
-				break;
-			}
-			/* Offset of resume key same for levels 257 and 514 */
-			cifsFile->srch_inf.resume_key = lastFindData->FileIndex;
-			if(UnixSearch == FALSE) {
-				cifsFile->resume_name_length = 
-					le32_to_cpu(lastFindData->FileNameLength);
-				if(cifsFile->resume_name_length > bufsize - 64) {
-					cFYI(1,("Illegal resume file name length %d",
-						cifsFile->resume_name_length));
-					rc = -ENOMEM;
-					break;
-				}
-				cifsFile->search_resume_name = 
-					kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-				cFYI(1,("Last file: %s with name %d bytes long",
-					lastFindData->FileName,
-					cifsFile->resume_name_length));
-				if(cifsFile->search_resume_name == NULL) {
-					rc = -ENOMEM;
-					break;
-				}
-				memcpy(cifsFile->search_resume_name,
-					lastFindData->FileName, 
-					cifsFile->resume_name_length);
-			} else {
-				pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
-				if (Unicode == TRUE) {
-					for(i=0;(pfindDataUnix->FileName[i] 
-						    | pfindDataUnix->FileName[i+1]);
-						i+=2) {
-						if(i > bufsize-64)
-							break;
-					}
-					cifsFile->resume_name_length = i + 2;
-				} else {
-					cifsFile->resume_name_length = 
-						strnlen(pfindDataUnix->FileName,
-							bufsize-63);
-				}
-				if(cifsFile->resume_name_length > bufsize - 64) {
-					cFYI(1,("Illegal resume file name length %d",
-						cifsFile->resume_name_length));
-					rc = -ENOMEM;
-					break;
-				}
-				cifsFile->search_resume_name = 
-					kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-				cFYI(1,("Last file: %s with name %d bytes long",
-					pfindDataUnix->FileName,
-					cifsFile->resume_name_length));
-				if(cifsFile->search_resume_name == NULL) {
-					rc = -ENOMEM;
-					break;
-				}
-				memcpy(cifsFile->search_resume_name,
-					pfindDataUnix->FileName, 
-					cifsFile->resume_name_length);
-			}
-			for (i = 2; i < count + 2; i++) {
-				if (UnixSearch == FALSE) {
-					__u32 len = le32_to_cpu(pfindData->FileNameLength);
-					if (Unicode == TRUE)
-						len =
-						    cifs_strfromUCS_le
-						    (pfindData->FileName,
-						     (wchar_t *)
-						     pfindData->FileName,
-						     len / 2,
-						     cifs_sb->local_nls);
-					qstring.len = len;
-					if (((len != 1)
-					     || (pfindData->FileName[0] != '.'))
-					    && ((len != 2)
-						|| (pfindData->
-						    FileName[0] != '.')
-						|| (pfindData->
-						    FileName[1] != '.'))) {
-						if(cifs_filldir(&qstring,
-							     pfindData,
-							     file, filldir,
-							     direntry)) {
-							/* do not end search if
-								kernel not ready to take
-								remaining entries yet */
-							reset_resume_key(file, pfindData->FileName,qstring.len,
-								Unicode, cifs_sb->local_nls);
-							findParms.EndofSearch = 0;
-							break;
-						}
-						file->f_pos++;
-					}
-				} else {	/* UnixSearch */
-					pfindDataUnix =
-					    (FILE_UNIX_INFO *) pfindData;
-					if (Unicode == TRUE)
-						qstring.len =
-							cifs_strfromUCS_le
-							(pfindDataUnix->FileName,
-							(wchar_t *)
-							pfindDataUnix->FileName,
-							MAX_PATHCONF,
-							cifs_sb->local_nls);
-					else
-						qstring.len =
-							strnlen(pfindDataUnix->
-							  FileName,
-							  MAX_PATHCONF);
-					if (((qstring.len != 1)
-					     || (pfindDataUnix->
-						 FileName[0] != '.'))
-					    && ((qstring.len != 2)
-						|| (pfindDataUnix->
-						    FileName[0] != '.')
-						|| (pfindDataUnix->
-						    FileName[1] != '.'))) {
-						if(cifs_filldir_unix(&qstring,
-								  pfindDataUnix,
-								  file,
-								  filldir,
-								  direntry)) {
-							/* do not end search if
-								kernel not ready to take
-								remaining entries yet */
-							findParms.EndofSearch = 0;
-							reset_resume_key(file, pfindDataUnix->FileName,
-								qstring.len,Unicode,cifs_sb->local_nls);
-							break;
-						}
-						file->f_pos++;
-					}
-				}
-				/* works also for Unix ff struct since first field of both */
-				pfindData = 
-					(FILE_DIRECTORY_INFO *) ((char *) pfindData
-						 + le32_to_cpu(pfindData->NextEntryOffset));
-				/* BB also should check to make sure that pointer is not beyond the end of the SMB */
-				/* if(pfindData > lastFindData) rc = -EIO; break; */
-			}	/* end for loop */
-			if ((findParms.EndofSearch != 0) && cifsFile) {
-				cifsFile->srch_inf.endOfSearch = TRUE;
-				if(findParms.SearchCount == cpu_to_le16(2))
-					cifsFile->srch_inf.emptyDir = TRUE;
-			}
-		} else {
-			if (cifsFile)
-				cifsFile->srch_inf.endOfSearch = TRUE;
-			/* unless parent directory gone do not return error */
-			rc = 0;
-		}
-		break;
-	default:
-		if (file->private_data == NULL) {
-			rc = -EBADF;
-			cFYI(1,
-			     ("Readdir on closed srch, pos = %lld",
-			      file->f_pos));
-		} else {
-			cifsFile = (struct cifsFileInfo *) file->private_data;
-			if (cifsFile->srch_inf.endOfSearch) {
-				rc = 0;
-				cFYI(1, ("End of search "));
-				break;
-			}
-			searchHandle = cifsFile->netfid;
-			rc = CIFSFindNext(xid, pTcon, pfindData,
-				&findNextParms, searchHandle, 
-				cifsFile->search_resume_name,
-				cifsFile->resume_name_length,
-				cifsFile->srch_inf.resume_key,
-				&Unicode, &UnixSearch);
-			cFYI(1,("Count: %d  End: %d ",
-			      le16_to_cpu(findNextParms.SearchCount),
-			      le16_to_cpu(findNextParms.EndofSearch)));
-			if ((rc == 0) && (findNextParms.SearchCount != 0)) {
-			/* BB save off resume key, key name and name length  */
-				__u16 count = le16_to_cpu(findNextParms.SearchCount);
-				lastFindData = 
-					(FILE_DIRECTORY_INFO *) ((char *) pfindData 
-					+ le16_to_cpu(findNextParms.LastNameOffset));
-				if((char *)lastFindData > (char *)pfindData + bufsize) {
-					cFYI(1,("last search entry past end of packet"));
-					rc = -EIO;
-					break;
-				}
-				/* Offset of resume key same for levels 257 and 514 */
-				cifsFile->srch_inf.resume_key = lastFindData->FileIndex;
-
-				if(UnixSearch == FALSE) {
-					cifsFile->resume_name_length = 
-						le32_to_cpu(lastFindData->FileNameLength);
-					if(cifsFile->resume_name_length > bufsize - 64) {
-						cFYI(1,("Illegal resume file name length %d",
-							cifsFile->resume_name_length));
-						rc = -ENOMEM;
-						break;
-					}
-					/* Free the memory allocated by previous findfirst 
-					or findnext call - we can not reuse the memory since
-					the resume name may not be same string length */
-					if(cifsFile->search_resume_name)
-						kfree(cifsFile->search_resume_name);
-					cifsFile->search_resume_name = 
-						kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-					cFYI(1,("Last file: %s with name %d bytes long",
-						lastFindData->FileName,
-						cifsFile->resume_name_length));
-					if(cifsFile->search_resume_name == NULL) {
-						rc = -ENOMEM;
-						break;
-					}
-					
-					memcpy(cifsFile->search_resume_name,
-						lastFindData->FileName, 
-						cifsFile->resume_name_length);
-				} else {
-					pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
-					if (Unicode == TRUE) {
-						for(i=0;(pfindDataUnix->FileName[i] 
-								| pfindDataUnix->FileName[i+1]);
-							i+=2) {
-							if(i > bufsize-64)
-								break;
-						}
-						cifsFile->resume_name_length = i + 2;
-					} else {
-						cifsFile->resume_name_length = 
-							strnlen(pfindDataUnix->
-							 FileName,
-							 MAX_PATHCONF);
-					}
-					if(cifsFile->resume_name_length > bufsize - 64) {
-						cFYI(1,("Illegal resume file name length %d",
-								cifsFile->resume_name_length));
-						rc = -ENOMEM;
-						break;
-					}
-					/* Free the memory allocated by previous findfirst 
-					or findnext call - we can not reuse the memory since
-					the resume name may not be same string length */
-					if(cifsFile->search_resume_name)
-						kfree(cifsFile->search_resume_name);
-					cifsFile->search_resume_name = 
-						kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-					cFYI(1,("fnext last file: %s with name %d bytes long",
-						pfindDataUnix->FileName,
-						cifsFile->resume_name_length));
-					if(cifsFile->search_resume_name == NULL) {
-						rc = -ENOMEM;
-						break;
-					}
-					memcpy(cifsFile->search_resume_name,
-						pfindDataUnix->FileName, 
-						cifsFile->resume_name_length);
-				}
-
-				for (i = 0; i < count; i++) {
-					__u32 len = le32_to_cpu(pfindData->
-							FileNameLength);
-					if (UnixSearch == FALSE) {
-						if (Unicode == TRUE)
-							len =
-							  cifs_strfromUCS_le
-							  (pfindData->FileName,
-							  (wchar_t *)
-							  pfindData->FileName,
-							  len / 2,
-							  cifs_sb->local_nls);
-						qstring.len = len;
-						if (((len != 1)
-						    || (pfindData->FileName[0] != '.'))
-						    && ((len != 2)
-							|| (pfindData->FileName[0] != '.')
-							|| (pfindData->FileName[1] !=
-							    '.'))) {
-							if(cifs_filldir
-							    (&qstring,
-							     pfindData,
-							     file, filldir,
-							     direntry)) {
-							/* do not end search if
-								kernel not ready to take
-								remaining entries yet */
-								findNextParms.EndofSearch = 0;
-								reset_resume_key(file, pfindData->FileName,qstring.len,
-									Unicode,cifs_sb->local_nls);
-								break;
-							}
-							file->f_pos++;
-						}
-					} else {	/* UnixSearch */
-						pfindDataUnix =
-						    (FILE_UNIX_INFO *)
-						    pfindData;
-						if (Unicode == TRUE)
-							qstring.len =
-							  cifs_strfromUCS_le
-							  (pfindDataUnix->FileName,
-							  (wchar_t *)
-							  pfindDataUnix->FileName,
-							  MAX_PATHCONF,
-							  cifs_sb->local_nls);
-						else
-							qstring.len =
-							  strnlen
-							  (pfindDataUnix->
-							  FileName,
-							  MAX_PATHCONF);
-						if (((qstring.len != 1)
-						     || (pfindDataUnix->
-							 FileName[0] != '.'))
-						    && ((qstring.len != 2)
-							|| (pfindDataUnix->
-							    FileName[0] != '.')
-							|| (pfindDataUnix->
-							    FileName[1] !=
-							    '.'))) {
-							if(cifs_filldir_unix
-							    (&qstring,
-							     pfindDataUnix,
-							     file, filldir,
-							     direntry)) {
-								/* do not end search if
-								kernel not ready to take
-								remaining entries yet */
-								findNextParms.EndofSearch = 0;
-								reset_resume_key(file, pfindDataUnix->FileName,qstring.len,
-									Unicode,cifs_sb->local_nls);
-								break;
-							}
-							file->f_pos++;
-						}
-					}
-					pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData + 
-						le32_to_cpu(pfindData->NextEntryOffset));
-	/* works also for Unix find struct since first field of both */
-	/* BB also should check to ensure pointer not beyond end of SMB */
-				} /* end for loop */
-				if (findNextParms.EndofSearch != 0) {
-					cifsFile->srch_inf.endOfSearch = TRUE;
-				}
-			} else {
-				cifsFile->srch_inf.endOfSearch = TRUE;
-				rc = 0;	/* unless parent directory disappeared - do not
-				return error here (eg Access Denied or no more files) */
-			}
-		}
-	} /* end switch */
-	if (data)
-		kfree(data);
-	if (full_path)
-		kfree(full_path);
-	FreeXid(xid);
-
-	return rc;
-}
 int cifs_prepare_write(struct file *file, struct page *page,
 			unsigned from, unsigned to)
 {
diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c
--- a/fs/cifs/inode.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/inode.c	2005-03-03 21:52:21 -08:00
@@ -982,13 +982,12 @@
 				cifs_sb->local_nls);
 		if(rc == -EOPNOTSUPP) {
 			cFYI(1,("OS2 level of SetPathInfo not implemented"));
-			/* Need to convert time_buf into old format, 
-			but probably better to do that inside the function
-			below rather than here */
-			/* Better to return EOPNOTSUPP until function
-			below is ready */
+			/* For older servers converts time_buf into old DOS style
+			level which uses two second granularity */
+
+			/* return EOPNOTSUPP until function below is ready */
 			/* CIFSSMBSetTimesLegacy(xid, pTcon, full_path,
-        	        FILE_INFO_STANDARD * data, cifs_sb->local_nls); */
+        	        &time_buf, cifs_sb->local_nls); */
 		}
 	}
 
diff -Nru a/fs/cifs/readdir.c b/fs/cifs/readdir.c
--- a/fs/cifs/readdir.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/readdir.c	2005-03-03 21:52:21 -08:00
@@ -394,7 +394,7 @@
 
 
 static int
-cifs_filldir2(char * pfindEntry, struct file *file, 
+cifs_filldir(char * pfindEntry, struct file *file, 
 			  filldir_t filldir, void *direntry,char * scratch_buf)
 {
 	int rc = 0;
@@ -515,7 +515,7 @@
 	return rc;
 }
 
-int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
+int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 {
 	int rc = 0;
 	int xid,i;
@@ -625,7 +625,7 @@
 				fill in inode new_inode (which makes number locally)
 			}
 			also create local inode for per reasons unless new mount parm says otherwise */
-			rc = cifs_filldir2(current_entry, file, 
+			rc = cifs_filldir(current_entry, file, 
 					filldir, direntry,tmp_buf);
 			file->f_pos++;
 			if(file->f_pos == cifsFile->srch_inf.index_of_last_entry) {
diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c
--- a/fs/cifs/transport.c	2005-03-03 21:52:21 -08:00
+++ b/fs/cifs/transport.c	2005-03-03 21:52:21 -08:00
@@ -179,6 +179,71 @@
 #ifdef CIFS_EXPERIMENTAL
 /* BB finish off this function, adding support for writing set of pages as iovec */
 /* and also adding support for operations that need to parse the response smb    */
+
+int
+smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
+	 unsigned int smb_buf_length, struct kvec * write_vector /* page list */, struct sockaddr *sin)
+{
+	int rc = 0;
+	int i = 0;
+	struct msghdr smb_msg;
+	number_of_pages += 1; /* account for SMB header */
+	struct kvec * piov  = kmalloc(number_of_pages * sizeof(struct kvec));
+	if(i=0;i<num_pages-1;i++
+	unsigned len = smb_buf_length + 4;
+
+	if(ssocket == NULL)
+		return -ENOTSOCK; /* BB eventually add reconnect code here */
+	iov.iov_base = smb_buffer;
+	iov.iov_len = len;
+
+	smb_msg.msg_name = sin;
+	smb_msg.msg_namelen = sizeof (struct sockaddr);
+	smb_msg.msg_control = NULL;
+	smb_msg.msg_controllen = 0;
+	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 
+	   Flags2 is converted in SendReceive */
+
+	smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
+	cFYI(1, ("Sending smb of length %d ", smb_buf_length));
+	dump_smb(smb_buffer, len);
+
+	while (len > 0) {
+		rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, len?);
+		if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
+			i++;
+			if(i > 60) {
+				cERROR(1,
+				   ("sends on sock %p stuck for 30 seconds",
+				    ssocket));
+				rc = -EAGAIN;
+				break;
+			}
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ/2);
+			continue;
+		}
+		if (rc < 0) 
+			break;
+		iov.iov_base += rc;
+		iov.iov_len -= rc;
+		len -= rc;
+	}
+
+	if (rc < 0) {
+		cERROR(1,("Error %d sending data on socket to server.", rc));
+	} else {
+		rc = 0;
+	}
+
+	return rc;
+}
+
+
 int
 CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
 	    struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op)
@@ -285,7 +350,7 @@
 	rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number);
 
 	midQ->midState = MID_REQUEST_SUBMITTED;
-/*	rc = smb_send2(ses->server->ssocket, in_buf, in_buf->smb_buf_length, piovec,
+/*	rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, piovec,
 		      (struct sockaddr *) &(ses->server->addr.sockAddr));*/
 	if(rc < 0) {
 		DeleteMidQEntry(midQ);