# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/07 21:15:17-06:00 stevef@smfhome.smfdom 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into smfhome.smfdom:/home/stevef/bk_cifs_org/linux-2.5cifs
# 
# fs/cifs/connect.c
#   2005/03/07 21:15:04-06:00 stevef@smfhome.smfdom +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/07 18:18:45-06:00 stevef@smf-t23.(none) 
#   [CIFS] recognize nouser_xattr and user_xattr mount options (default is still xattr 
#   enabled if built with xattr support)
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/xattr.c
#   2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +20 -2
#   recognize nouser_xattr and user_xattr mount options (default is still xattr 
#   enabled if built with xattr support)
# 
# fs/cifs/connect.c
#   2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +9 -1
#   recognize nouser_xattr and user_xattr mount options (default is still xattr 
#   enabled if built with xattr support)
# 
# fs/cifs/cifsfs.h
#   2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +1 -1
#   update cifs version to 1.30
# 
# fs/cifs/cifs_fs_sb.h
#   2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +2 -1
#   recognize nouser_xattr and user_xattr mount options (default is still xattr 
#   enabled if built with xattr support)
# 
# fs/cifs/CHANGES
#   2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +4 -0
#   allow disabling of user. xattr support on a mount, update change log for 1.30
# 
# ChangeSet
#   2005/03/07 17:12:19-06:00 stevef@smf-t23.(none) 
#   [CIFS] ioctl support part 1
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/ioctl.c
#   2005/03/07 17:11:57-06:00 stevef@smf-t23.(none) +49 -0
# 
# fs/cifs/ioctl.c
#   2005/03/07 17:11:57-06:00 stevef@smf-t23.(none) +0 -0
#   BitKeeper file /home/stevef/linux-2.5cifs/fs/cifs/ioctl.c
# 
# ChangeSet
#   2005/03/07 00:17:42-06:00 stevef@smf-t23.(none) 
#   [CIFS] cifs ioctl support part 1
#   
#   This is needed for getflags and setflags (chattr) support and the new CIFS 
#   POSIX extensions
#   
#   Signed-off-by:  Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/smbencrypt.c
#   2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +2 -0
#   remove sparse warning on function that is not used yet
# 
# fs/cifs/cifsproto.h
#   2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +2 -0
#   cifs ioctl part 1
# 
# fs/cifs/cifspdu.h
#   2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +2 -0
#   cifs ioctl part 1
# 
# fs/cifs/Makefile
#   2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +1 -1
#   cifs ioctl part 1
# 
# ChangeSet
#   2005/03/06 17:55:20-06:00 stevef@smf-t23.(none) 
#   [CIFS] replace schedule_timeout with msleep (uninterrutable) in send retry path 
#   when clogged socket
#   
#   Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Steve French <sfrench@us.ibm.com>
# 
# fs/cifs/transport.c
#   2005/03/06 17:55:05-06:00 stevef@smf-t23.(none) +3 -4
#   replace schedule_timeout with msleep (uninterrutable) in send retry path on clogged socket
# 
# ChangeSet
#   2005/03/06 17:08:39-06:00 stevef@smf-t23.(none) 
#   [CIFS] remove sparse warnings - moving externs & making more functions static
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/transport.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +2 -2
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/smbencrypt.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -1
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/readdir.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +55 -10
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/netmisc.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +3 -3
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/misc.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -1
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/inode.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +0 -2
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/file.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -51
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/fcntl.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +2 -1
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/connect.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +10 -5
#   remove sparse warnings - changing externs and make more functions static. fix ntlmv2 error path
# 
# fs/cifs/cifssmb.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +4 -220
#   remove sparse warnings - changing externs and make more functions static. Remove dead code
# 
# fs/cifs/cifsproto.h
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +13 -15
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/cifsencrypt.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -0
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/cifs_debug.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +3 -3
#   remove sparse warnings - changing externs and make more functions static
# 
# fs/cifs/asn1.c
#   2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +3 -2
#   remove sparse warnings - changing externs and make more functions static
# 
# ChangeSet
#   2005/02/17 22:52:34-06:00 stevef@smfhome.smfdom 
#   [CIFS] Handle RFC1001 NACK with length of 4
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/connect.c
#   2005/02/17 22:52:25-06:00 stevef@smfhome.smfdom +1 -2
#   Handle RFC1001 NACK with length of 4
# 
# 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-08 01:32:25 -08:00
+++ b/fs/cifs/AUTHORS	2005-03-08 01:32:25 -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-08 01:32:25 -08:00
+++ b/fs/cifs/CHANGES	2005-03-08 01:32:25 -08:00
@@ -1,3 +1,12 @@
+Version 1.30
+------------
+Allow new nouser_xattr mount parm to disable xattr support for user namespace.
+
+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 +16,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/Makefile b/fs/cifs/Makefile
--- a/fs/cifs/Makefile	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/Makefile	2005-03-08 01:32:25 -08:00
@@ -3,4 +3,4 @@
 #
 obj-$(CONFIG_CIFS) += cifs.o
 
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o
+cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o
diff -Nru a/fs/cifs/asn1.c b/fs/cifs/asn1.c
--- a/fs/cifs/asn1.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/asn1.c	2005-03-08 01:32:25 -08:00
@@ -26,6 +26,7 @@
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifs_debug.h"
+#include "cifsproto.h"
 
 /*****************************************************************************
  *
@@ -77,8 +78,8 @@
 
 #define SPNEGO_OID_LEN 7
 #define NTLMSSP_OID_LEN  10
-unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
-unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
+static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
+static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
 
 /* 
  * ASN.1 context.
@@ -210,7 +211,7 @@
 {
 	unsigned char ch;
 
-	if (eoc == 0) {
+	if (eoc == NULL) {
 		if (!asn1_octet_decode(ctx, &ch))
 			return 0;
 
diff -Nru a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
--- a/fs/cifs/cifs_debug.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifs_debug.c	2005-03-08 01:32:25 -08:00
@@ -57,7 +57,7 @@
 }
 
 #ifdef CONFIG_PROC_FS
-int
+static int
 cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 		     int count, int *eof, void *data)
 {
@@ -178,7 +178,7 @@
 }
 
 #ifdef CONFIG_CIFS_STATS
-int
+static int
 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 		  int count, int *eof, void *data)
 {
@@ -286,7 +286,7 @@
 }
 #endif
 
-struct proc_dir_entry *proc_fs_cifs;
+static struct proc_dir_entry *proc_fs_cifs;
 read_proc_t cifs_txanchor_read;
 static read_proc_t cifsFYI_read;
 static write_proc_t cifsFYI_write;
diff -Nru a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
--- a/fs/cifs/cifs_fs_sb.h	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifs_fs_sb.h	2005-03-08 01:32:25 -08:00
@@ -21,7 +21,8 @@
 #define CIFS_MOUNT_NO_PERM      1 /* do not do client vfs_perm check */
 #define CIFS_MOUNT_SET_UID      2 /* set current->euid in create etc. */
 #define CIFS_MOUNT_SERVER_INUM  4 /* inode numbers from uniqueid from server */
-#define CIFS_MOUNT_DIRECT_IO          8 /* do not write nor read through page cache */
+#define CIFS_MOUNT_DIRECT_IO    8 /* do not write nor read through page cache */
+#define CIFS_MOUNT_NO_XATTR  0x10 /* if set - disable xattr support */
 
 struct cifs_sb_info {
 	struct cifsTconInfo *tcon;	/* primary mount */
diff -Nru a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
--- a/fs/cifs/cifsencrypt.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifsencrypt.c	2005-03-08 01:32:25 -08:00
@@ -25,6 +25,7 @@
 #include "cifs_debug.h"
 #include "md5.h"
 #include "cifs_unicode.h"
+#include "cifsproto.h"
 
 /* Calculate and return the CIFS signature based on the mac key and the smb pdu */
 /* the 16 byte signature must be allocated by the caller  */
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifsfs.c	2005-03-08 01:32:25 -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-08 01:32:25 -08:00
+++ b/fs/cifs/cifsfs.h	2005-03-08 01:32:25 -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.30"
 #endif				/* _CIFSFS_H */
diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
--- a/fs/cifs/cifspdu.h	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifspdu.h	2005-03-08 01:32:25 -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;
 
@@ -1078,6 +1078,7 @@
 #define SMB_QUERY_FILE_UNIX_LINK        0x201
 #define SMB_QUERY_POSIX_ACL             0x204
 #define SMB_QUERY_XATTR                 0x205
+#define SMB_QUERY_ATTR_FLAGS            0x206  /* append,immutable etc. */
 #define SMB_QUERY_FILE_INTERNAL_INFO    0x3ee
 #define SMB_QUERY_FILE_ACCESS_INFO      0x3f0
 #define SMB_QUERY_FILE_NAME_INFO2       0x3f1 /* 0x30 bytes */
@@ -1095,6 +1096,7 @@
 #define SMB_SET_FILE_UNIX_HLINK         0x203
 #define SMB_SET_POSIX_ACL               0x204
 #define SMB_SET_XATTR                   0x205
+#define SMB_SET_ATTR_FLAGS              0x206  /* append, immutable etc. */
 #define SMB_SET_FILE_BASIC_INFO2        0x3ec
 #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */
 #define SMB_FILE_ALL_INFO2              0x3fa
@@ -1592,17 +1594,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/cifsproto.h b/fs/cifs/cifsproto.h
--- a/fs/cifs/cifsproto.h	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifsproto.h	2005-03-08 01:32:25 -08:00
@@ -50,16 +50,18 @@
 extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
 extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb);
+extern int is_size_safe_to_change(struct cifsInodeInfo *);
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
 			enum securityEnum *secType);
+extern int cifs_inet_pton(int, char * source, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
 			const struct cifsTconInfo *, int
 			/* length of fixed section (word count) in two byte units  */
 			);
-struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *);
-void DeleteOplockQEntry(struct oplock_q_entry *);
+extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *);
+extern void DeleteOplockQEntry(struct oplock_q_entry *);
 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
 extern u64 cifs_UnixTimeToNT(struct timespec);
 extern int cifs_get_inode_info(struct inode **pinode,
@@ -79,18 +81,11 @@
 			const struct nls_table *);
 
 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 */ );
+            const char *searchName, const struct nls_table *nls_codepage,
+            __u16 *searchHandle, struct cifs_search_info * psrch_inf);
+
 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
-			FILE_DIRECTORY_INFO * findData,
-			T2_FNEXT_RSP_PARMS * findParms,
-			const __u16 searchHandle, char * resume_name,
-			int name_length, __u32 resume_key,
-			int *UnicodeFlag, int *pUnixFlag);
+            __u16 searchHandle, struct cifs_search_info * psrch_inf);
 
 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
 			const __u16 search_handle);
@@ -132,6 +127,9 @@
 extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
 			const char *fileName, const FILE_BASIC_INFO * data,
 			const struct nls_table *nls_codepage);
+extern int CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
+                FILE_BASIC_INFO * data, const struct nls_table *nls_codepage);
+
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
 			const char *fileName, __u64 size,int setAllocationSizeFlag,
 			const struct nls_table *nls_codepage);
@@ -211,10 +209,10 @@
 extern int cifs_reconnect(struct TCP_Server_Info *server);
 
 extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *);
-extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key,
+extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key,
 	__u32 expected_sequence_number);
 extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
-extern void CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *);
+extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *);
 extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * );
 extern int CIFSSMBCopy(int xid,
 			struct cifsTconInfo *source_tcon,
@@ -244,4 +242,6 @@
 		const unsigned char *fileName,
 		const char *local_acl, const int buflen, const int acl_type,
 		const struct nls_table *nls_codepage);
+int cifs_ioctl (struct inode * inode, struct file * filep,
+                unsigned int command, unsigned long arg);
 #endif			/* _CIFSPROTO_H */
diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
--- a/fs/cifs/cifssmb.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/cifssmb.c	2005-03-08 01:32:25 -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);
@@ -1826,7 +1845,7 @@
 	return size;
 }
 
-__u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
+static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
 			const posix_acl_xattr_entry * local_ace)
 {
 	__u16 rc = 0; /* 0 = ACL converted ok */
@@ -1844,7 +1863,7 @@
 }
 
 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
-__u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen,
+static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen,
 		const int acl_type)
 {
 	__u16 rc = 0;
@@ -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);
@@ -2306,118 +2323,9 @@
 }
 #endif /* CIFS_EXPERIMENTAL */
 
-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)
-{
-/* level 257 SMB_ */
-	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
-	TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
-	char *response_data;
-	int rc = 0;
-	int bytes_returned;
-	int name_len;
-	__u16 params, byte_count;
-
-	cFYI(1, ("In FindFirst"));
-findFirstRetry:
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
-	if (rc)
-		return rc;
-
-	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-		name_len =
-		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
-				  /* find define for this maxpathcomponent */
-				  , nls_codepage);
-		name_len++;	/* trailing null */
-		name_len *= 2;
-	} else {		/* BB improve the check for buffer overruns BB */
-		name_len = strnlen(searchName, PATH_MAX);
-		name_len++;	/* trailing null */
-		strncpy(pSMB->FileName, searchName, name_len);
-	}
-
-	params = 12 + name_len /* includes null */ ;
-	pSMB->TotalDataCount = 0;	/* no EAs */
-	pSMB->MaxParameterCount = cpu_to_le16(10);
-	pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf -
-					  MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-	pSMB->MaxSetupCount = 0;
-	pSMB->Reserved = 0;
-	pSMB->Flags = 0;
-	pSMB->Timeout = 0;
-	pSMB->Reserved2 = 0;
-	byte_count = params + 1 /* pad */ ;
-	pSMB->TotalParameterCount = cpu_to_le16(params);
-	pSMB->ParameterCount = pSMB->TotalParameterCount;
-	pSMB->ParameterOffset = cpu_to_le16(
-		offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4);
-	pSMB->DataCount = 0;
-	pSMB->DataOffset = 0;
-	pSMB->SetupCount = 1;	/* one byte no need to make endian neutral */
-	pSMB->Reserved3 = 0;
-	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
-	pSMB->SearchAttributes =
-	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
-			ATTR_DIRECTORY);
-	pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_DIRECTORY_INFO));	/* should this be shrunk even more ? */
-	pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
-
-	/* test for Unix extensions */
-	if (tcon->ses->capabilities & CAP_UNIX) {
-		pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
-		*pUnixFlag = TRUE;
-	} else {
-		pSMB->InformationLevel =
-		    cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
-		*pUnixFlag = FALSE;
-	}
-	pSMB->SearchStorageType = 0;	/* BB what should we set this to? It is not clear if it matters BB */
-	pSMB->hdr.smb_buf_length += byte_count;
-	pSMB->ByteCount = cpu_to_le16(byte_count);
-
-	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
-	if (rc) {		/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
-		cFYI(1, ("Error in FindFirst = %d", rc));
-	} else {
-		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-		if(!rc) {
-		/* decode response */
-		/* BB add safety checks for these memcpys */
-			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-				*pUnicodeFlag = TRUE;
-			else
-				*pUnicodeFlag = FALSE;
-			memcpy(findParms,
-			       (char *) &pSMBr->hdr.Protocol +
-			       le16_to_cpu(pSMBr->t2.ParameterOffset),
-			       sizeof (T2_FFIRST_RSP_PARMS));
-			response_data =
-			    (char *) &pSMBr->hdr.Protocol +
-			    le16_to_cpu(pSMBr->t2.DataOffset);
-			memcpy(findData, response_data, 
-				le16_to_cpu(pSMBr->t2.DataCount));
-		}
-	}
-	if (pSMB)
-		cifs_buf_release(pSMB);
-
-	if (rc == -EAGAIN)
-		goto findFirstRetry;
-
-	return rc;
-}
-
 /* xid, tcon, searchName and codepage are input parms, rest are returned */
 int
-CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
+CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
 	      const char *searchName, 
 	      const struct nls_table *nls_codepage,
 	      __u16 *	pnetfid,
@@ -2541,7 +2449,7 @@
 	return rc;
 }
 
-int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
+int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
             __u16 searchHandle, struct cifs_search_info * psrch_inf)
 {
 	TRANSACTION2_FNEXT_REQ *pSMB = NULL;
@@ -2666,113 +2574,6 @@
 }
 
 int
-CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
-		FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms,
-		const __u16 searchHandle, char * resume_file_name, int name_len,
-		__u32 resume_key, int *pUnicodeFlag, int *pUnixFlag)
-{
-/* level 257 SMB_ */
-	TRANSACTION2_FNEXT_REQ *pSMB = NULL;
-	TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
-	char *response_data;
-	int rc = 0;
-	int bytes_returned;
-	__u16 params, byte_count;
-
-	cFYI(1, ("In FindNext"));
-
-	if(resume_file_name == NULL) {
-		return -EIO;
-	}
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
-	if (rc)
-		return rc;
-
-	params = 14;	/* includes 2 bytes of null string, converted to LE below */
-	byte_count = 0;
-	pSMB->TotalDataCount = 0;	/* no EAs */
-	pSMB->MaxParameterCount = cpu_to_le16(8);
-	pSMB->MaxDataCount =
-	    cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-	pSMB->MaxSetupCount = 0;
-	pSMB->Reserved = 0;
-	pSMB->Flags = 0;
-	pSMB->Timeout = 0;
-	pSMB->Reserved2 = 0;
-	pSMB->ParameterOffset =  cpu_to_le16(
-           offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
-	pSMB->DataCount = 0;
-	pSMB->DataOffset = 0;
-	pSMB->SetupCount = 1;
-	pSMB->Reserved3 = 0;
-	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
-	pSMB->SearchHandle = searchHandle;	/* always kept as le */
-	findParms->SearchCount = 0;	/* set to zero in case of error */
-	pSMB->SearchCount =
-	    cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
-	/* test for Unix extensions */
-	if (tcon->ses->capabilities & CAP_UNIX) {
-		pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
-		*pUnixFlag = TRUE;
-	} else {
-		pSMB->InformationLevel =
-		    cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
-		*pUnixFlag = FALSE;
-	}
-	pSMB->ResumeKey = resume_key;
-	pSMB->SearchFlags =
-	    cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
-	/* BB add check to make sure we do not cross end of smb */
-	if(name_len < PATH_MAX) {
-		memcpy(pSMB->ResumeFileName, resume_file_name, name_len);
-		byte_count += name_len;
-	}
-	params += name_len;
-	byte_count = params + 1 /* pad */ ;
-	pSMB->TotalParameterCount = cpu_to_le16(params);
-	pSMB->ParameterCount = pSMB->TotalParameterCount;
-	/* BB improve error handling here */
-	pSMB->hdr.smb_buf_length += byte_count;
-	pSMB->ByteCount = cpu_to_le16(byte_count);
-
-	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
-	if (rc) {
-		if (rc == -EBADF)
-			rc = 0;	/* search probably was closed at end of search above */
-		else
-			cFYI(1, ("FindNext returned = %d", rc));
-	} else {		/* decode response */
-		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
-		/* BB add safety checks for these memcpys */
-		if(rc == 0) {
-			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-				*pUnicodeFlag = TRUE;
-			else
-				*pUnicodeFlag = FALSE;
-			memcpy(findParms,
-			       (char *) &pSMBr->hdr.Protocol +
-			       le16_to_cpu(pSMBr->t2.ParameterOffset),
-			       sizeof (T2_FNEXT_RSP_PARMS));
-			response_data =
-			    (char *) &pSMBr->hdr.Protocol +
-			    le16_to_cpu(pSMBr->t2.DataOffset);
-			memcpy(findData,response_data,le16_to_cpu(pSMBr->t2.DataCount));
-		}
-	}
-	if (pSMB)
-		cifs_buf_release(pSMB);
-
-	/* Note: On -EAGAIN error only caller can retry on handle based calls
-		since file handle passed in no longer valid */
-
-	return rc;
-}
-
-int
 CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle)
 {
 	int rc = 0;
@@ -3574,10 +3375,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 +3409,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 +3420,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 +3438,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-08 01:32:25 -08:00
+++ b/fs/cifs/connect.c	2005-03-08 01:32:25 -08:00
@@ -47,7 +47,6 @@
 		       unsigned char *p24);
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
 			 unsigned char *p24);
-extern int cifs_inet_pton(int, const char *, void *dst);
 
 extern mempool_t *cifs_req_poolp;
 
@@ -70,6 +69,7 @@
 	unsigned setuids:1;
 	unsigned noperm:1;
 	unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
+	unsigned no_xattr:1;   /* set if xattr (EA) support should be disabled*/
 	unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
 	unsigned direct_io:1;
 	unsigned int rsize;
@@ -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,29 +271,18 @@
 			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)) {
+			} else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
 				/* we get this from Windows 98 instead of error on SMB negprot response */
 				cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4]));
 				if(server->tcpStatus == CifsNew) {
@@ -330,38 +313,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 +338,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 +379,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);
@@ -560,7 +525,12 @@
 			continue;
 		if ((value = strchr(data, '=')) != NULL)
 			*value++ = '\0';
-		if (strnicmp(data, "user", 4) == 0) {
+
+		if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/
+			vol->no_xattr = 0;
+		} else if (strnicmp(data, "nouser_xattr",12) == 0) {
+			vol->no_xattr = 1;
+		} else if (strnicmp(data, "user", 4) == 0) {
 			if (!value || !*value) {
 				printk(KERN_WARNING
 				       "CIFS: invalid or missing username\n");
@@ -845,7 +815,7 @@
 			return 1;
 		}
 	}
-	if(vol->UNCip == 0)
+	if(vol->UNCip == NULL)
 		vol->UNCip = &vol->UNC[2];
 
 	return 0;
@@ -1409,14 +1379,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)"));
@@ -1433,6 +1403,8 @@
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
 		if(volume_info.server_ino)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
+		if(volume_info.no_xattr)
+			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
 		if(volume_info.direct_io) {
 			cERROR(1,("mounting share using direct i/o"));
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
@@ -1504,7 +1476,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 +1547,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 +1564,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 +1800,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 +2065,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 +2407,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 +2781,7 @@
 		return -EIO;
 
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == 0) {
+	if (smb_buffer == NULL) {
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
@@ -3011,16 +2983,21 @@
 				if(ntlmv2_flag) {
 					char * v2_response;
 					cFYI(1,("Can use more secure NTLM version 2 password hash"));
-					CalcNTLMv2_partial_mac_key(pSesInfo, 
-						nls_info);
-					v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
+					if(CalcNTLMv2_partial_mac_key(pSesInfo, 
+						nls_info)) {
+						rc = -ENOMEM;
+						goto ss_err_exit;
+					} else
+						v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
 					if(v2_response) {
 						CalcNTLMv2_response(pSesInfo,v2_response);
 /*						cifs_calculate_ntlmv2_mac_key(pSesInfo->mac_signing_key, response, ntlm_session_key, */
 						kfree(v2_response);
 					/* BB Put dummy sig in SessSetup PDU? */
-					} else
+					} else {
 						rc = -ENOMEM;
+						goto ss_err_exit;
+					}
 
 				} else {
 					SMBNTencrypt(pSesInfo->password,
@@ -3057,6 +3034,7 @@
 			pSesInfo->status = CifsGood;
 		}
 	}
+ss_err_exit:
 	return rc;
 }
 
diff -Nru a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
--- a/fs/cifs/fcntl.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/fcntl.c	2005-03-08 01:32:25 -08:00
@@ -27,8 +27,9 @@
 #include "cifsproto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
+#include "cifsfs.h"
 
-__u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
+static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
 {
 	__u32 cifs_ntfy_flags = 0;
 
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/file.c	2005-03-08 01:32:25 -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;
@@ -1750,651 +1755,7 @@
 	}
 }
 
-/* Returns one if new inode created (which therefore needs to be hashed) */
-/* Might check in the future if inode number changed so we can rehash inode */
-int
-construct_dentry(struct qstr *qstring, struct file *file,
-		 struct inode **ptmp_inode, struct dentry **pnew_dentry)
-{
-	struct dentry *tmp_dentry;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *pTcon;
-	int rc = 0;
-
-	cFYI(1, ("For %s ", qstring->name));
-	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-	pTcon = cifs_sb->tcon;
-
-	qstring->hash = full_name_hash(qstring->name, qstring->len);
-	tmp_dentry = d_lookup(file->f_dentry, qstring);
-	if (tmp_dentry) {
-		cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
-		*ptmp_inode = tmp_dentry->d_inode;
-		/* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
-		if(*ptmp_inode == NULL) {
-	                *ptmp_inode = new_inode(file->f_dentry->d_sb);
-			if(*ptmp_inode == NULL)
-				return rc;
-			rc = 1;
-			d_instantiate(tmp_dentry, *ptmp_inode);
-		}
-	} else {
-		tmp_dentry = d_alloc(file->f_dentry, qstring);
-		if(tmp_dentry == NULL) {
-			cERROR(1,("Failed allocating dentry"));
-			*ptmp_inode = NULL;
-			return rc;
-		}
-			
-		*ptmp_inode = new_inode(file->f_dentry->d_sb);
-		tmp_dentry->d_op = &cifs_dentry_ops;
-		if(*ptmp_inode == NULL)
-			return rc;
-		rc = 1;
-		d_instantiate(tmp_dentry, *ptmp_inode);
-		d_rehash(tmp_dentry);
-	}
-
-	tmp_dentry->d_time = jiffies;
-	*pnew_dentry = tmp_dentry;
-	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,
+static int cifs_prepare_write(struct file *file, struct page *page,
 			unsigned from, unsigned to)
 {
 	int rc = 0;
diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c
--- a/fs/cifs/inode.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/inode.c	2005-03-08 01:32:25 -08:00
@@ -30,8 +30,6 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 
-extern int is_size_safe_to_change(struct cifsInodeInfo *);
-
 int
 cifs_get_inode_info_unix(struct inode **pinode,
 			 const unsigned char *search_path,
@@ -982,13 +980,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/ioctl.c b/fs/cifs/ioctl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/cifs/ioctl.c	2005-03-08 01:32:25 -08:00
@@ -0,0 +1,49 @@
+/*
+ *   fs/cifs/ioctl.c
+ *
+ *   vfs operations that deal with io control
+ *
+ *   Copyright (C) International Business Machines  Corp., 2005
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/fs.h>
+#include <linux/ext2_fs.h>
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
+
+int cifs_ioctl (struct inode * inode, struct file * filep, 
+		unsigned int command, unsigned long arg)
+{
+	int rc = -ENOTTY; /* strange error - but the precedent */
+#ifdef CONFIG_CIFS_POSIX
+	cFYI(1,("ioctl file %p  cmd %u  arg %lu",filep,command,arg));
+	switch(command) {
+		case EXT2_IOC_GETFLAGS:
+			cFYI(1,("get flags not implemented yet"));
+			return -EOPNOTSUPP;
+		case EXT2_IOC_SETFLAGS:
+			cFYI(1,("set flags not implemented yet"));
+			return -EOPNOTSUPP;
+		default:
+			cFYI(1,("unsupported ioctl"));
+			return rc;
+	}
+#endif /* CONFIG_CIFS_POSIX */
+	return rc;
+} 
diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c
--- a/fs/cifs/misc.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/misc.c	2005-03-08 01:32:25 -08:00
@@ -33,7 +33,7 @@
 extern mempool_t *cifs_req_poolp;
 extern struct task_struct * oplockThread;
 
-__u16 GlobalMid;		/* multiplex id - rotating counter */
+static __u16 GlobalMid;		/* multiplex id - rotating counter */
 
 /* The xid serves as a useful identifier for each incoming vfs request, 
    in a similar way to the mid which is useful to track each sent smb, 
diff -Nru a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
--- a/fs/cifs/netmisc.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/netmisc.c	2005-03-08 01:32:25 -08:00
@@ -43,7 +43,7 @@
 	int posix_code;
 };
 
-const struct smb_to_posix_error mapping_table_ERRDOS[] = {
+static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
 	{ERRbadfunc, -EINVAL},
 	{ERRbadfile, -ENOENT},
 	{ERRbadpath, -ENOTDIR},
@@ -81,7 +81,7 @@
 	{0, 0}
 };
 
-const struct smb_to_posix_error mapping_table_ERRSRV[] = {
+static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
 	{ERRerror, -EIO},
 	{ERRbadpw, -EPERM},
 	{ERRbadtype, -EREMOTE},
@@ -120,7 +120,7 @@
 	{0, 0}
 };
 
-const struct smb_to_posix_error mapping_table_ERRHRD[] = {
+static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
 	{0, 0}
 };
 
diff -Nru a/fs/cifs/readdir.c b/fs/cifs/readdir.c
--- a/fs/cifs/readdir.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/readdir.c	2005-03-08 01:32:25 -08:00
@@ -29,13 +29,7 @@
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
-
-extern int CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
-            const char *searchName, const struct nls_table *nls_codepage,
-            __u16 *searchHandle, struct cifs_search_info * psrch_inf);
-
-extern int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
-            __u16 searchHandle, struct cifs_search_info * psrch_inf);
+#include "cifsfs.h"
 
 extern int construct_dentry(struct qstr *qstring, struct file *file,
 		 struct inode **ptmp_inode, struct dentry **pnew_dentry);
@@ -71,6 +65,57 @@
 	}
 } */
 
+/* Returns one if new inode created (which therefore needs to be hashed) */
+/* Might check in the future if inode number changed so we can rehash inode */
+int
+construct_dentry(struct qstr *qstring, struct file *file,
+                 struct inode **ptmp_inode, struct dentry **pnew_dentry)
+{
+        struct dentry *tmp_dentry;
+        struct cifs_sb_info *cifs_sb;
+        struct cifsTconInfo *pTcon;
+        int rc = 0;
+
+        cFYI(1, ("For %s ", qstring->name));
+        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+        pTcon = cifs_sb->tcon;
+
+        qstring->hash = full_name_hash(qstring->name, qstring->len);
+        tmp_dentry = d_lookup(file->f_dentry, qstring);
+        if (tmp_dentry) {
+                cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
+                *ptmp_inode = tmp_dentry->d_inode;
+                /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
+                if(*ptmp_inode == NULL) {
+                        *ptmp_inode = new_inode(file->f_dentry->d_sb);
+                        if(*ptmp_inode == NULL)
+                                return rc;
+                        rc = 1;
+                        d_instantiate(tmp_dentry, *ptmp_inode);
+                }
+        } else {
+                tmp_dentry = d_alloc(file->f_dentry, qstring);
+                if(tmp_dentry == NULL) {
+                        cERROR(1,("Failed allocating dentry"));
+                        *ptmp_inode = NULL;
+                        return rc;
+                }
+
+                *ptmp_inode = new_inode(file->f_dentry->d_sb);
+                tmp_dentry->d_op = &cifs_dentry_ops;
+                if(*ptmp_inode == NULL)
+                        return rc;
+                rc = 1;
+                d_instantiate(tmp_dentry, *ptmp_inode);
+                d_rehash(tmp_dentry);
+        }
+
+        tmp_dentry->d_time = jiffies;
+        *pnew_dentry = tmp_dentry;
+        return rc;
+}
+
+
 static int initiate_cifs_search(const int xid, struct file * file)
 {
 	int rc = 0;
@@ -123,7 +168,7 @@
 		cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
 	}
 
-	rc = CIFSFindFirst2(xid, pTcon,full_path,cifs_sb->local_nls, 
+	rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, 
 		&cifsFile->netfid, &cifsFile->srch_inf); 
 	if(rc == 0)
 		cifsFile->invalidHandle = FALSE;
@@ -279,7 +324,7 @@
 	while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 
 	      (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){
 	 	cFYI(1,("calling findnext2"));
-		rc = CIFSFindNext2(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf);
+		rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf);
 		if(rc)
 			return -ENOENT;
 	}
@@ -394,7 +439,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;
@@ -459,7 +504,7 @@
 	return rc;
 }
 
-int cifs_save_resume_key(const char * current_entry,struct cifsFileInfo * cifsFile)
+static int cifs_save_resume_key(const char * current_entry,struct cifsFileInfo * cifsFile)
 {
 	int rc = 0;
 	unsigned int len = 0;
@@ -515,7 +560,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 +670,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/smbencrypt.c b/fs/cifs/smbencrypt.c
--- a/fs/cifs/smbencrypt.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/smbencrypt.c	2005-03-08 01:32:25 -08:00
@@ -186,7 +186,8 @@
 }
 
 /* Does the NTLMv2 owfs of a user's password */
-void
+#if 0  /* function not needed yet - but will be soon */
+static void
 ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
 		const char *domain_n, unsigned char kr_buf[16],
 		const struct nls_table *nls_codepage)
@@ -219,6 +220,7 @@
 
 	kfree(user_u);
 }
+#endif 
 
 /* Does the des encryption from the NT or LM MD4 hash. */
 void
diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c
--- a/fs/cifs/transport.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/transport.c	2005-03-08 01:32:25 -08:00
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/wait.h>
 #include <linux/net.h>
+#include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <linux/mempool.h>
@@ -34,7 +35,7 @@
 extern mempool_t *cifs_mid_poolp;
 extern kmem_cache_t *cifs_oplock_cachep;
 
-struct mid_q_entry *
+static struct mid_q_entry *
 AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
 {
 	struct mid_q_entry *temp;
@@ -70,7 +71,7 @@
 	return temp;
 }
 
-void
+static void
 DeleteMidQEntry(struct mid_q_entry *midEntry)
 {
 	spin_lock(&GlobalMid_Lock);
@@ -156,8 +157,7 @@
 				rc = -EAGAIN;
 				break;
 			}
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ/2);
+			msleep(500);
 			continue;
 		}
 		if (rc < 0) 
@@ -179,6 +179,70 @@
 #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;
+			}
+			msleep(500);
+			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 +349,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);
diff -Nru a/fs/cifs/xattr.c b/fs/cifs/xattr.c
--- a/fs/cifs/xattr.c	2005-03-08 01:32:25 -08:00
+++ b/fs/cifs/xattr.c	2005-03-08 01:32:25 -08:00
@@ -71,16 +71,21 @@
 	}
 	if(ea_name == NULL) {
 		cFYI(1,("Null xattr names not supported"));
-	} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
+	} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)
+		&& (strncmp(ea_name,CIFS_XATTR_OS2_PREFIX,4))) {
 		cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
 		/* BB what if no namespace prefix? */
 		/* Should we just pass them to server, except for
 		system and perhaps security prefixes? */
 	} else {
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+			goto remove_ea_exit;
+
 		ea_name+=5; /* skip past user. prefix */
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL,
 			(__u16)0, cifs_sb->local_nls);
 	}
+remove_ea_exit:
 	if (full_path)
 		kfree(full_path);
 	FreeXid(xid);
@@ -135,6 +140,8 @@
 	if(ea_name == NULL) {
 		cFYI(1,("Null xattr names not supported"));
 	} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) {
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+			goto set_ea_exit;
 		if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) {
 			cFYI(1,("attempt to set cifs inode metadata"));
 		}
@@ -142,6 +149,9 @@
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
 			(__u16)value_size, cifs_sb->local_nls);
 	} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+			goto set_ea_exit;
+
 		ea_name += 4; /* skip past os2. prefix */
 		rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
 			(__u16)value_size, cifs_sb->local_nls);
@@ -174,7 +184,8 @@
 		  system and perhaps security prefixes? */
 		}
 	}
- 
+
+set_ea_exit:
 	if (full_path)
 		kfree(full_path);
 	FreeXid(xid);
@@ -218,6 +229,9 @@
 	if(ea_name == NULL) {
 		cFYI(1,("Null xattr names not supported"));
 	} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) {
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+			goto get_ea_exit;
+
 		if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) {
 			cFYI(1,("attempt to query cifs inode metadata"));
 			/* revalidate/getattr then populate from inode */
@@ -226,6 +240,9 @@
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
 			buf_size, cifs_sb->local_nls);
 	} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+			goto get_ea_exit;
+
 		ea_name += 4; /* skip past os2. prefix */
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
 			buf_size, cifs_sb->local_nls);
@@ -263,6 +280,7 @@
 	if(rc == -EINVAL)
 		rc = -EOPNOTSUPP; 
 
+get_ea_exit:
 	if (full_path)
 		kfree(full_path);
 	FreeXid(xid);