bk://cifs.bkbits.net/linux-2.5cifs
stevef@smf-t23.(none)|ChangeSet|20050406013617|12908 stevef

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/04/05 20:36:17-05:00 stevef@smf-t23.(none) 
#   [CIFS] remove a few redundant null pointer checks, and cleanup misc source formatting
#   
#   Mostly suggested by Jesper Juhl
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/smberr.h
#   2005/04/05 20:36:02-05:00 stevef@smf-t23.(none) +146 -85
#   remove redundant null pointer checks, and cleanup misc formatting
# 
# fs/cifs/dir.c
#   2005/04/05 20:36:02-05:00 stevef@smf-t23.(none) +38 -45
#   remove redundant null pointer checks, and cleanup misc formatting 
# 
# ChangeSet
#   2005/04/04 00:57:55-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/connect.c
#   2005/04/04 00:57:50-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/04/03 23:00:11-05:00 stevef@smf-t23.(none) 
#   [CIFS] Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
#   This first parts implements conversions from Unicode. 
#   
#   Signed-off-by: Steve French
# 
# fs/cifs/readdir.c
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +13 -2
#   Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
# 
# fs/cifs/misc.c
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +69 -0
#   Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
# 
# fs/cifs/connect.c
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +7 -0
#   Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
# 
# fs/cifs/cifsproto.h
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +2 -0
#   Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
# 
# fs/cifs/cifs_fs_sb.h
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +1 -0
#   Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
# 
# fs/cifs/TODO
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +10 -9
#   Update CIFS TOOO list
# 
# fs/cifs/README
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +11 -0
#   Add new mount parm mapchars for handling the seven reserved characters that Linux needs for filenames.
# 
# fs/cifs/CHANGES
#   2005/04/03 22:59:56-05:00 stevef@smf-t23.(none) +3 -1
#   Update cifs change log
# 
# ChangeSet
#   2005/04/03 00:01:37-06:00 stevef@smf-t23.(none) 
#   Fix rare oops in cifs_close - protect access to cifs file list in cifs_close path
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/file.c
#   2005/04/03 00:01:21-06:00 stevef@smf-t23.(none) +2 -0
#   protect access to cifs file list in cifs_close path
# 
# fs/cifs/CHANGES
#   2005/04/03 00:01:21-06:00 stevef@smf-t23.(none) +2 -1
#   update CIFS change log
# 
# ChangeSet
#   2005/04/02 01:24:54-06:00 stevef@smf-t23.(none) 
#   [CIFS] Fix multiuser packet signing to use the right sequence number and mac session key
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/transport.c
#   2005/04/02 01:24:39-06:00 stevef@smf-t23.(none) +13 -9
#   Fix multiuser packet signing to use the right sequence number and mac session key
# 
# fs/cifs/connect.c
#   2005/04/02 01:24:39-06:00 stevef@smf-t23.(none) +20 -8
#   Fix multiuser packet signing to use the right sequence number and mac session key
# 
# fs/cifs/cifsproto.h
#   2005/04/02 01:24:39-06:00 stevef@smf-t23.(none) +1 -1
#   Fix multiuser packet signing to use the right sequence number and mac session key
# 
# fs/cifs/cifsglob.h
#   2005/04/02 01:24:39-06:00 stevef@smf-t23.(none) +6 -5
#   Fix multiuser packet signing to use the right sequence number and mac session key
# 
# fs/cifs/cifsencrypt.c
#   2005/04/02 01:24:39-06:00 stevef@smf-t23.(none) +8 -8
#   Fix multiuser packet signing to use the right sequence number and mac session key
# 
# fs/cifs/CHANGES
#   2005/04/02 01:24:39-06:00 stevef@smf-t23.(none) +2 -1
#   update cifs change log
# 
# ChangeSet
#   2005/04/01 22:14:30-08:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2005/04/01 22:14:23-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/04/01 18:32:59-06:00 stevef@smf-t23.(none) 
#   [CIFS] Enable ioctl support in POSIX extensions to handle lsattr
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/ioctl.c
#   2005/04/01 18:32:41-06:00 stevef@smf-t23.(none) +1 -0
#   remove sparse warning
# 
# fs/cifs/cifssmb.c
#   2005/04/01 18:32:41-06:00 stevef@smf-t23.(none) +6 -7
#   remove unnecessary pad in QueryFileInfo
# 
# fs/cifs/cifsproto.h
#   2005/04/01 18:32:41-06:00 stevef@smf-t23.(none) +0 -2
#   remove redundant function define
# 
# fs/cifs/cifspdu.h
#   2005/04/01 18:32:41-06:00 stevef@smf-t23.(none) +0 -2
#   renmove unnecessary bad on SMB QueryFileInfo
# 
# fs/cifs/cifsfs.c
#   2005/04/01 18:32:41-06:00 stevef@smf-t23.(none) +8 -0
#   Enable ioctl support in POSIX extensions to handle lsattr
# 
# ChangeSet
#   2005/04/01 17:21:05-06:00 stevef@smf-t23.(none) 
#   [CIFS] Gracefully turn off serverino (when serverino is enabled on mount) to old servers such as NT4
#   which do not support this level of FindFirst (and retry with a lower infolevel)
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/readdir.c
#   2005/04/01 17:20:43-06:00 stevef@smf-t23.(none) +6 -0
#   Gracefully turn off serverino (when serverino is enabled on mount) to old servers such as NT4
#   which do not support this level of FindFirst (and retry with a lower infolevel)
# 
# fs/cifs/netmisc.c
#   2005/04/01 17:20:43-06:00 stevef@smf-t23.(none) +1 -1
#   Gracefully turn off serverino (when serverino is enabled on mount) to old servers such as NT4
#   which do not support this level of FindFirst (and retry with a lower infolevel)
# 
# ChangeSet
#   2005/04/01 17:18:10-06:00 stevef@smf-t23.(none) 
#   [CIFS] add support for chattr/lsattr in new CIFS POSIX extensions
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/ioctl.c
#   2005/04/01 17:17:54-06:00 stevef@smf-t23.(none) +49 -3
#   add support for chattr/lsattr in new CIFS POSIX extensions
# 
# fs/cifs/cifssmb.c
#   2005/04/01 17:17:54-06:00 stevef@smf-t23.(none) +85 -1
#   add support for chattr/lsattr in new CIFS POSIX extensions
# 
# fs/cifs/cifsproto.h
#   2005/04/01 17:17:54-06:00 stevef@smf-t23.(none) +3 -1
#   add support for chattr/lsattr in new CIFS POSIX extensions
# 
# fs/cifs/cifspdu.h
#   2005/04/01 17:17:54-06:00 stevef@smf-t23.(none) +62 -5
#   add support for chattr/lsattr in new CIFS POSIX extensions
# 
# fs/cifs/cifsfs.h
#   2005/04/01 17:17:54-06:00 stevef@smf-t23.(none) +4 -2
#   add support for lsattr, update version to 1.32
# 
# fs/cifs/CHANGES
#   2005/04/01 17:17:54-06:00 stevef@smf-t23.(none) +8 -1
#   Update CIFS version info
# 
# ChangeSet
#   2005/04/01 12:52:41-06:00 stevef@smf-t23.(none) 
#   [CIFS] Only send POSIX ACL calls to server if server claims to support that capability bit
#   
#   Signed-off-by: Steve French (sfrench@us.ibm.com)
# 
# fs/cifs/xattr.c
#   2005/04/01 12:52:26-06:00 stevef@smf-t23.(none) +12 -8
#   Only send POSIX ACL calls to server if server claims to support that capability bit
# 
# ChangeSet
#   2005/03/29 12:00:37-08:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/connect.c
#   2005/03/29 12:00:32-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/cifs/cifsfs.c
#   2005/03/29 12:00:32-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/28 22:25:42-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/connect.c
#   2005/03/28 22:25:37-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/cifs/cifsfs.c
#   2005/03/28 22:25:37-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES
--- a/fs/cifs/CHANGES	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/CHANGES	2005-04-07 17:54:06 -07:00
@@ -1,7 +1,18 @@
-Version 1.31
+Version 1.32
 ------------
 Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one
 transact response for an SMB request and search entry split across two frames.
+Add support for lsattr (getting ext2/ext3/reiserfs attr flags from the server)
+as new protocol extensions. Do not send Get/Set calls for POSIX ACLs
+unless server explicitly claims to support them in CIFS Unix extensions
+POSIX ACL capability bit. Fix packet signing when multiuser mounting with
+different users from the same client to the same server. Fix oops in
+cifs_close. Add mount option for remapping reserved characters in
+filenames (also allow recognizing files with created by SFU which have any
+of these seven reserved characters to be recognized).
+
+Version 1.31
+------------
 Fix updates of DOS attributes and time fields so that files on NT4 servers
 do not get marked delete on close. Display sizes of cifs buffer pools in
 cifs stats. Fix oops in unmount when cifsd thread being killed by 
diff -Nru a/fs/cifs/README b/fs/cifs/README
--- a/fs/cifs/README	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/README	2005-04-07 17:54:06 -07:00
@@ -376,6 +376,17 @@
 		attributes) to the server (default) e.g. via setfattr 
 		and getfattr utilities. 
   nouser_xattr  Do not allow getfattr/setfattr to get/set xattrs 
+  mapchars      Translate the seven reserved characters 
+			*?<>|:\	
+		to the remap range (above 0xF000), which also
+		allows the CIFS client to recognize files created with
+		such characters by Windows's POSIX emulation. This can
+		also be useful when mounting to most versions of Samba
+		(which also forbids creating and opening files
+		whose names contain any of these seven characters).
+		This has no effect if the server does not support
+		Unicode on the wire.
+ nomapchars     Do not translate any of these seven characters (default).
 		
 The mount.cifs mount helper also accepts a few mount options before -o
 including:
diff -Nru a/fs/cifs/TODO b/fs/cifs/TODO
--- a/fs/cifs/TODO	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/TODO	2005-04-07 17:54:06 -07:00
@@ -1,4 +1,4 @@
-version 1.22 July 30, 2004 
+version 1.32 April 3, 2005
 
 A Partial List of Missing Features
 ==================================
@@ -14,7 +14,7 @@
 better)
 
 c) multi-user mounts - multiplexed sessionsetups over single vc
-(ie tcp session) - prettying up needed, and more testing needed
+(ie tcp session) - more testing needed
 
 d) Kerberos/SPNEGO session setup support - (started)
 
@@ -67,12 +67,15 @@
 
 r) Implement O_DIRECT flag on open (already supported on mount)
 
-KNOWN BUGS (updated December 10, 2004)
+KNOWN BUGS (updated April 3, 2005)
 ====================================
+See http://bugzilla.samba.org - search on product "CifsVFS" for
+current bug list.
+
 1) existing symbolic links (Windows reparse points) are recognized but
 can not be created remotely. They are implemented for Samba and those that
-support the CIFS Unix extensions but Samba has a bug currently handling
-symlink text beginning with slash
+support the CIFS Unix extensions, although earlier versions of Samba
+overly restrict the pathnames.
 2) follow_link and readdir code does not follow dfs junctions
 but recognizes them
 3) create of new files to FAT partitions on Windows servers can
@@ -98,7 +101,5 @@
 and when signing is disabled to request larger read sizes (larger than 
 negotiated size) and send larger write sizes to modern servers.
 
-4) More exhaustively test the recently added NT4 support against various
-NT4 service pack levels, and fix cifs_setattr for setting file times and 
-size to fall back to level 1 when error invalid level returned.
-
+4) More exhaustively test against less common servers.  More testing
+against Windows 9x, Windows ME servers.
diff -Nru a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
--- a/fs/cifs/cifs_fs_sb.h	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifs_fs_sb.h	2005-04-07 17:54:06 -07:00
@@ -23,6 +23,7 @@
 #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_NO_XATTR  0x10 /* if set - disable xattr support */
+#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
 
 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-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifsencrypt.c	2005-04-07 17:54:06 -07:00
@@ -50,7 +50,7 @@
 	return 0;
 }
 
-int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
+int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
 	__u32 * pexpected_response_sequence_number)
 {
 	int rc = 0;
@@ -59,21 +59,21 @@
 	/* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */
 	/* BB remember to add code to save expected sequence number in midQ entry BB */
 
-	if((cifs_pdu == NULL) || (ses == NULL))
+	if((cifs_pdu == NULL) || (server == NULL))
 		return -EINVAL;
 
 	if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 
 		return rc;
 
 	spin_lock(&GlobalMid_Lock);
-	cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(ses->sequence_number);
+	cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(server->sequence_number);
 	cifs_pdu->Signature.Sequence.Reserved = 0;
 	
-	*pexpected_response_sequence_number = ses->sequence_number++;
-	ses->sequence_number++;
+	*pexpected_response_sequence_number = server->sequence_number++;
+	server->sequence_number++;
 	spin_unlock(&GlobalMid_Lock);
 
-	rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature);
+	rc = cifs_calculate_signature(cifs_pdu, server->mac_signing_key,smb_signature);
 	if(rc)
 		memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
 	else
@@ -190,7 +190,7 @@
 	hmac_md5_update((const unsigned char *) unicode_buf,
 		(user_name_len+dom_name_len)*2,&ctx);
 
-	hmac_md5_final(ses->mac_signing_key,&ctx);
+	hmac_md5_final(ses->server->mac_signing_key,&ctx);
 	kfree(ucase_buf);
 	kfree(unicode_buf);
 	return 0;
@@ -200,7 +200,7 @@
 	struct HMACMD5Context context;
 	memcpy(v2_session_response + 8, ses->server->cryptKey,8);
 	/* gen_blob(v2_session_response + 16); */
-	hmac_md5_init_limK_to_64(ses->mac_signing_key, 16, &context);
+	hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context);
 
 	hmac_md5_update(ses->server->cryptKey,8,&context);
 /*	hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifsfs.c	2005-04-07 17:54:06 -07:00
@@ -559,6 +559,10 @@
 	.flush = cifs_flush,
 	.mmap  = cifs_file_mmap,
 	.sendfile = generic_file_sendfile,
+#ifdef CONFIG_CIFS_POSIX
+	.ioctl	= cifs_ioctl,
+#endif /* CONFIG_CIFS_POSIX */
+
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 	.readv = generic_file_readv,
 	.writev = generic_file_writev,
@@ -579,6 +583,10 @@
 	.fsync = cifs_fsync,
 	.flush = cifs_flush,
 	.sendfile = generic_file_sendfile, /* BB removeme BB */
+#ifdef CONFIG_CIFS_POSIX
+	.ioctl  = cifs_ioctl,
+#endif /* CONFIG_CIFS_POSIX */
+
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 	.dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
diff -Nru a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
--- a/fs/cifs/cifsfs.h	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifsfs.h	2005-04-07 17:54:06 -07:00
@@ -91,8 +91,10 @@
 			const char *symname);
 extern int	cifs_removexattr(struct dentry *, const char *);
 extern int 	cifs_setxattr(struct dentry *, const char *, const void *,
-			 size_t, int);
+			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.31"
+extern int cifs_ioctl (struct inode * inode, struct file * filep,
+		       unsigned int command, unsigned long arg);
+#define CIFS_VERSION   "1.32"
 #endif				/* _CIFSFS_H */
diff -Nru a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
--- a/fs/cifs/cifsglob.h	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifsglob.h	2005-04-07 17:54:06 -07:00
@@ -149,6 +149,8 @@
 	__u16 timeZone;
 	char cryptKey[CIFS_CRYPTO_KEY_SIZE];
 	char workstation_RFC1001_name[16]; /* 16th byte is always zero */
+	__u32 sequence_number; /* needed for CIFS PDU signature */
+	char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; 
 };
 
 /*
@@ -174,17 +176,16 @@
 	struct TCP_Server_Info *server;	/* pointer to server info */
 	atomic_t inUse; /* # of mounts (tree connections) on this ses */
 	enum statusEnum status;
-	__u32 sequence_number;  /* needed for CIFS PDU signature */
 	__u16 ipc_tid;		/* special tid for connection to IPC share */
 	__u16 flags;
-	char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];	
-	char *serverOS;		/* name of operating system underlying the server */
-	char *serverNOS;	/* name of network operating system that the server is running */
+	char *serverOS;		/* name of operating system underlying server */
+	char *serverNOS;	/* name of network operating system of server */
 	char *serverDomain;	/* security realm of server */
 	int Suid;		/* remote smb uid  */
 	uid_t linux_uid;        /* local Linux uid */
 	int capabilities;
-	char serverName[SERVER_NAME_LEN_WITH_NULL * 2];	/* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */
+	char serverName[SERVER_NAME_LEN_WITH_NULL * 2];	/* BB make bigger for 
+				TCP names - will ipv6 and sctp addresses fit? */
 	char userName[MAX_USERNAME_SIZE + 1];
 	char domainName[MAX_USERNAME_SIZE + 1];
 	char * password;
diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
--- a/fs/cifs/cifspdu.h	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifspdu.h	2005-04-07 17:54:06 -07:00
@@ -762,6 +762,16 @@
 	LOCKING_ANDX_RANGE Locks[1];
 } LOCK_REQ;
 
+
+typedef struct cifs_posix_lock {
+	__le16  lock_type;  /* 0 = Read, 1 = Write, 2 = Unlock */
+	__le16  lock_flags; /* 1 = Wait (only valid for setlock) */
+	__le32  pid;
+	__le64	start;
+	__le64	length;
+	/* BB what about additional owner info to identify network client */
+} CIFS_POSIX_LOCK;
+
 typedef struct smb_com_lock_rsp {
 	struct smb_hdr hdr;	/* wct = 2 */
 	__u8 AndXCommand;
@@ -1098,6 +1108,8 @@
 #define SMB_QUERY_POSIX_ACL             0x204
 #define SMB_QUERY_XATTR                 0x205
 #define SMB_QUERY_ATTR_FLAGS            0x206  /* append,immutable etc. */
+#define SMB_QUERY_POSIX_PERMISSION      0x207
+#define SMB_QUERY_POSIX_LOCK            0x208
 #define SMB_QUERY_FILE_INTERNAL_INFO    0x3ee
 #define SMB_QUERY_FILE_ACCESS_INFO      0x3f0
 #define SMB_QUERY_FILE_NAME_INFO2       0x3f1 /* 0x30 bytes */
@@ -1116,6 +1128,7 @@
 #define SMB_SET_POSIX_ACL               0x204
 #define SMB_SET_XATTR                   0x205
 #define SMB_SET_ATTR_FLAGS              0x206  /* append, immutable etc. */
+#define SMB_SET_POSIX_LOCK              0x208
 #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
@@ -1237,9 +1250,25 @@
 	struct smb_hdr hdr;	/* wct = 10 + SetupCount */
 	struct trans2_resp t2;
 	__u16 ByteCount;
-	__u16 Reserved2;	/* parameter word reserved - present for infolevels > 100 */
+	__u16 Reserved2;	/* parameter word reserved - 
+					present for infolevels > 100 */
+};
+
+struct smb_t2_qfi_req {
+        struct	smb_hdr hdr;
+        struct	trans2_req t2;
+	__u8	Pad;
+	__u16	Fid;
+	__le16	InformationLevel;
 };
 
+struct smb_t2_qfi_rsp {
+        struct smb_hdr hdr;     /* wct = 10 + SetupCount */
+        struct trans2_resp t2;
+        __u16 ByteCount;
+        __u16 Reserved2;        /* parameter word reserved - 
+					present for infolevels > 100 */
+};
 
 /*
  * Flags on T2 FINDFIRST and FINDNEXT 
@@ -1524,8 +1553,9 @@
 } FILE_SYSTEM_UNIX_INFO;	/* Unix extensions info, level 0x200 */
 /* Linux/Unix extensions capability flags */
 #define CIFS_UNIX_FCNTL_CAP             0x00000001 /* support for fcntl locks */
-#define CIFS_UNIX_POSIX_ACL_CAP         0x00000002
-#define CIFS_UNIX_XATTR_CAP             0x00000004 /*support for new namespace*/
+#define CIFS_UNIX_POSIX_ACL_CAP         0x00000002 /* support getfacl/setfacl */
+#define CIFS_UNIX_XATTR_CAP             0x00000004 /* support new namespace   */
+#define CIFS_UNIX_EXTATTR_CAP           0x00000008 /* support chattr/chflag   */
 
 typedef struct {
 	/* For undefined recommended transfer size return -1 in that field */
@@ -1971,14 +2001,39 @@
 	char path[1024];  
 };
 
-typedef struct {
+typedef struct file_xattr_info {
 	/* BB do we need another field for flags? BB */
 	__u32 xattr_name_len;
 	__u32 xattr_value_len;
 	char  xattr_name[0];
 	/* followed by xattr_value[xattr_value_len], no pad */
-} FILE_XATTR_INFO;	/* extended attribute, info level 205 */
+} FILE_XATTR_INFO;	/* extended attribute, info level 0x205 */
+
 
+/* flags for chattr command */
+#define EXT_SECURE_DELETE		0x00000001 /* EXT3_SECRM_FL */
+#define EXT_ENABLE_UNDELETE		0x00000002 /* EXT3_UNRM_FL */
+/* Reserved for compress file 0x4 */
+#define EXT_SYNCHRONOUS			0x00000008 /* EXT3_SYNC_FL */
+#define EXT_IMMUTABLE_FL		0x00000010 /* EXT3_IMMUTABLE_FL */
+#define EXT_OPEN_APPEND_ONLY		0x00000020 /* EXT3_APPEND_FL */
+#define EXT_DO_NOT_BACKUP		0x00000040 /* EXT3_NODUMP_FL */
+#define EXT_NO_UPDATE_ATIME		0x00000080 /* EXT3_NOATIME_FL */
+/* 0x100 through 0x800 reserved for compression flags and are GET-ONLY */
+#define EXT_HASH_TREE_INDEXED_DIR	0x00001000 /* GET-ONLY EXT3_INDEX_FL */
+/* 0x2000 reserved for IMAGIC_FL */
+#define EXT_JOURNAL_THIS_FILE	0x00004000 /* GET-ONLY EXT3_JOURNAL_DATA_FL */
+/* 0x8000 reserved for EXT3_NOTAIL_FL */
+#define EXT_SYNCHRONOUS_DIR		0x00010000 /* EXT3_DIRSYNC_FL */
+#define EXT_TOPDIR			0x00020000 /* EXT3_TOPDIR_FL */
+
+#define EXT_SET_MASK			0x000300FF
+#define EXT_GET_MASK			0x0003DFFF
+
+typedef struct file_chattr_info {
+	__le64	mask; /* list of all possible attribute bits */
+	__le64	mode; /* list of actual attribute bits on this inode */
+} FILE_CHATTR_INFO;  /* ext attributes (chattr, chflags) level 0x206 */
 
 #endif 
 
diff -Nru a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
--- a/fs/cifs/cifsproto.h	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifsproto.h	2005-04-07 17:54:06 -07:00
@@ -212,6 +212,8 @@
 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName, __u64 * inode_number,
 			const struct nls_table *nls_codepage);
+extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen,
+			const struct nls_table * codepage);
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
 
 extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
@@ -230,7 +232,7 @@
 
 extern int cifs_reconnect(struct TCP_Server_Info *server);
 
-extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *);
+extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
 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);
@@ -264,6 +266,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);
+extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
+                const int netfid, __u64 * pExtAttrBits, __u64 *pMask);
 #endif			/* _CIFSPROTO_H */
diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
--- a/fs/cifs/cifssmb.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/cifssmb.c	2005-04-07 17:54:06 -07:00
@@ -2072,7 +2072,90 @@
 	return rc;
 }
 
-#endif
+/* BB fix tabs in this function FIXME BB */
+int
+CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
+                const int netfid, __u64 * pExtAttrBits, __u64 *pMask)
+{
+        int rc = 0;
+        struct smb_t2_qfi_req *pSMB = NULL;
+        struct smb_t2_qfi_rsp *pSMBr = NULL;
+        int bytes_returned;
+        __u16 params, byte_count;
+
+        cFYI(1,("In GetExtAttr"));
+        if(tcon == NULL)
+                return -ENODEV;
+
+GetExtAttrRetry:
+        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                      (void **) &pSMBr);
+        if (rc)
+                return rc;
+
+        params = 2 /* level */ +2 /* fid */;
+        pSMB->t2.TotalDataCount = 0;
+        pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+        /* BB find exact max data count below from sess structure BB */
+        pSMB->t2.MaxDataCount = cpu_to_le16(4000);
+        pSMB->t2.MaxSetupCount = 0;
+        pSMB->t2.Reserved = 0;
+        pSMB->t2.Flags = 0;
+        pSMB->t2.Timeout = 0;
+        pSMB->t2.Reserved2 = 0;
+        pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+			Fid) - 4);
+        pSMB->t2.DataCount = 0;
+        pSMB->t2.DataOffset = 0;
+        pSMB->t2.SetupCount = 1;
+        pSMB->t2.Reserved3 = 0;
+        pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+        byte_count = params + 1 /* pad */ ;
+        pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+        pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
+        pSMB->Pad = 0;
+	pSMB->Fid = netfid;
+        pSMB->hdr.smb_buf_length += byte_count;
+        pSMB->t2.ByteCount = cpu_to_le16(byte_count);
+
+        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+        if (rc) {
+                cFYI(1, ("error %d in GetExtAttr", rc));
+        } else {
+                /* decode response */
+                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+                if (rc || (pSMBr->ByteCount < 2))
+                /* BB also check enough total bytes returned */
+                        /* If rc should we check for EOPNOSUPP and
+                        disable the srvino flag? or in caller? */
+                        rc = -EIO;      /* bad smb */
+                else {
+                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
+                        struct file_chattr_info * pfinfo;
+                        /* BB Do we need a cast or hash here ? */
+                        if(count != 16) {
+                                cFYI(1, ("Illegal size ret in GetExtAttr"));
+                                rc = -EIO;
+                                goto GetExtAttrOut;
+                        }
+                        pfinfo = (struct file_chattr_info *)
+                                (data_offset + (char *) &pSMBr->hdr.Protocol);
+                        *pExtAttrBits = le64_to_cpu(pfinfo->mode);
+			*pMask = le64_to_cpu(pfinfo->mask);
+                }
+        }
+GetExtAttrOut:
+        cifs_buf_release(pSMB);
+        if (rc == -EAGAIN)
+                goto GetExtAttrRetry;
+        return rc;
+}
+
+
+#endif /* CONFIG_POSIX */
 
 int
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c
--- a/fs/cifs/connect.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/connect.c	2005-04-07 17:54:06 -07:00
@@ -72,6 +72,7 @@
 	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 remap:1;   /* set to remap seven reserved chars in filenames */
 	unsigned int rsize;
 	unsigned int wsize;
 	unsigned int sockopt;
@@ -182,7 +183,8 @@
 			spin_lock(&GlobalMid_Lock);
 			if(server->tcpStatus != CifsExiting)
 				server->tcpStatus = CifsGood;
-			spin_unlock(&GlobalMid_Lock);
+			server->sequence_number = 0;
+			spin_unlock(&GlobalMid_Lock);			
 	/*		atomic_set(&server->inFlight,0);*/
 			wake_up(&server->response_q);
 		}
@@ -770,6 +772,10 @@
 			vol->noperm = 0;
 		} else if (strnicmp(data, "noperm", 6) == 0) {
 			vol->noperm = 1;
+		} else if (strnicmp(data, "mapchars", 8) == 0) {
+			vol->remap = 1;
+		} else if (strnicmp(data, "nomapchars", 10) == 0) {
+			vol->remap = 0;
 		} else if (strnicmp(data, "setuids", 7) == 0) {
 			vol->setuids = 1;
 		} else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1352,6 +1358,7 @@
 			} else
 				rc = 0;
 			memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
+			srvTcp->sequence_number = 0;
 		}
 	}
 
@@ -1419,6 +1426,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.remap)
+			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
 		if(volume_info.no_xattr)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
 		if(volume_info.direct_io) {
@@ -2959,6 +2968,7 @@
 	int rc = 0;
 	char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
 	int ntlmv2_flag = FALSE;
+	int first_time = 0;
 
 	/* what if server changes its buffer size after dropping the session? */
 	if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
@@ -2977,12 +2987,13 @@
 			spin_unlock(&GlobalMid_Lock);
 
 		}
+		first_time = 1;
 	}
 	if (!rc) {
 		pSesInfo->capabilities = pSesInfo->server->capabilities;
 		if(linuxExtEnabled == 0)
 			pSesInfo->capabilities &= (~CAP_UNIX);
-		pSesInfo->sequence_number = 0;
+	/*	pSesInfo->sequence_number = 0;*/
 		cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
 			pSesInfo->server->secMode,
 			pSesInfo->server->capabilities,
@@ -3015,7 +3026,10 @@
 						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, */
+				/*		if(first_time)
+							cifs_calculate_ntlmv2_mac_key(
+							  pSesInfo->server->mac_signing_key, 
+							  response, ntlm_session_key, */
 						kfree(v2_response);
 					/* BB Put dummy sig in SessSetup PDU? */
 					} else {
@@ -3028,9 +3042,11 @@
 						pSesInfo->server->cryptKey,
 						ntlm_session_key);
 
-					cifs_calculate_mac_key(pSesInfo->mac_signing_key,
-						ntlm_session_key,
-						pSesInfo->password);
+					if(first_time)
+						cifs_calculate_mac_key(
+							pSesInfo->server->mac_signing_key,
+							ntlm_session_key,
+							pSesInfo->password);
 				}
 			/* for better security the weaker lanman hash not sent
 			   in AuthSessSetup so we no longer calculate it */
@@ -3046,8 +3062,11 @@
 				pSesInfo->server->cryptKey,
 				ntlm_session_key);
 
-			cifs_calculate_mac_key(pSesInfo->mac_signing_key, 
-				ntlm_session_key, pSesInfo->password);
+			if(first_time) 		
+				cifs_calculate_mac_key(
+					pSesInfo->server->mac_signing_key,
+					ntlm_session_key, pSesInfo->password);
+
 			rc = CIFSSessSetup(xid, pSesInfo,
 				ntlm_session_key, nls_info);
 		}
diff -Nru a/fs/cifs/dir.c b/fs/cifs/dir.c
--- a/fs/cifs/dir.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/dir.c	2005-04-07 17:54:06 -07:00
@@ -284,51 +284,48 @@
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
 		} else if(newinode) {
-			pCifsFile = (struct cifsFileInfo *)
+			pCifsFile =
 			   kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
-		
-			if (pCifsFile) {
-				memset((char *)pCifsFile, 0,
-				       sizeof (struct cifsFileInfo));
-				pCifsFile->netfid = fileHandle;
-				pCifsFile->pid = current->tgid;
-				pCifsFile->pInode = newinode;
-				pCifsFile->invalidHandle = FALSE;
-				pCifsFile->closePend     = FALSE;
-				init_MUTEX(&pCifsFile->fh_sem);
-				/* put the following in at open now */
-				/* pCifsFile->pfile = file; */ 
-				write_lock(&GlobalSMBSeslock);
-				list_add(&pCifsFile->tlist,&pTcon->openFileList);
-				pCifsInode = CIFS_I(newinode);
-				if(pCifsInode) {
+			
+			if(pCifsFile == NULL)
+				goto cifs_create_out;
+			memset((char *)pCifsFile, 0,
+			       sizeof (struct cifsFileInfo));
+			pCifsFile->netfid = fileHandle;
+			pCifsFile->pid = current->tgid;
+			pCifsFile->pInode = newinode;
+			pCifsFile->invalidHandle = FALSE;
+			pCifsFile->closePend     = FALSE;
+			init_MUTEX(&pCifsFile->fh_sem);
+			/* set the following in open now 
+				pCifsFile->pfile = file; */
+			write_lock(&GlobalSMBSeslock);
+			list_add(&pCifsFile->tlist,&pTcon->openFileList);
+			pCifsInode = CIFS_I(newinode);
+			if(pCifsInode) {
 				/* if readable file instance put first in list*/
-					if (write_only == TRUE) {
-                                        	list_add_tail(&pCifsFile->flist,
-							&pCifsInode->openFileList);
-					} else {
-						list_add(&pCifsFile->flist,
-							&pCifsInode->openFileList);
-					}
-					if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-						pCifsInode->clientCanCacheAll = TRUE;
-						pCifsInode->clientCanCacheRead = TRUE;
-						cFYI(1,("Exclusive Oplock granted on inode %p",
-							newinode));
-					} else if((oplock & 0xF) == OPLOCK_READ)
-						pCifsInode->clientCanCacheRead = TRUE;
+				if (write_only == TRUE) {
+                                       	list_add_tail(&pCifsFile->flist,
+						&pCifsInode->openFileList);
+				} else {
+					list_add(&pCifsFile->flist,
+						&pCifsInode->openFileList);
 				}
-				write_unlock(&GlobalSMBSeslock);
+				if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
+					pCifsInode->clientCanCacheAll = TRUE;
+					pCifsInode->clientCanCacheRead = TRUE;
+					cFYI(1,("Exclusive Oplock for inode %p",
+						newinode));
+				} else if((oplock & 0xF) == OPLOCK_READ)
+					pCifsInode->clientCanCacheRead = TRUE;
 			}
+			write_unlock(&GlobalSMBSeslock);
 		}
 	} 
-
-	if (buf)
-	    kfree(buf);
-	if (full_path)
-	    kfree(full_path);
+cifs_create_out:
+	kfree(buf);
+	kfree(full_path);
 	FreeXid(xid);
-
 	return rc;
 }
 
@@ -375,10 +372,8 @@
 		}
 	}
 
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
-
 	return rc;
 }
 
@@ -447,8 +442,7 @@
 		if file exists or not but no access BB */
 	}
 
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 	return ERR_PTR(rc);
 }
@@ -478,8 +472,7 @@
 
 	cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path));
 
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 	return rc;
 }
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/file.c	2005-04-07 17:54:06 -07:00
@@ -465,8 +465,10 @@
 				write_lock(&file->f_owner.lock);
 			}
 		}
+		write_lock(&GlobalSMBSeslock);
 		list_del(&pSMBFile->flist);
 		list_del(&pSMBFile->tlist);
+		write_unlock(&GlobalSMBSeslock);
 		write_unlock(&file->f_owner.lock);
 		kfree(pSMBFile->search_resume_name);
 		kfree(file->private_data);
diff -Nru a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
--- a/fs/cifs/ioctl.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/ioctl.c	2005-04-07 17:54:06 -07:00
@@ -20,30 +20,77 @@
  *   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"
+#include "cifsfs.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
+	__u64	ExtAttrBits = 0;
+	__u64	ExtAttrMask = 0;
+	__u64   caps;
+#endif /* CONFIG_CIFS_POSIX */
+	int xid;
+	struct cifs_sb_info *cifs_sb;
+	struct cifsTconInfo *tcon;
+	struct cifsFileInfo *pSMBFile =
+		(struct cifsFileInfo *)filep->private_data;
+
+	xid = GetXid();
+
+	cifs_sb = CIFS_SB(inode->i_sb);
+	tcon = cifs_sb->tcon;
+	if (pSMBFile == NULL)
+		goto cifs_ioctl_out;
+
+#ifdef CONFIG_CIFS_POSIX
+	if(tcon)
+		caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
+	else {
+		rc = -EIO;
+		goto cifs_ioctl_out;
+	}
+
 	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;
+			if(CIFS_UNIX_EXTATTR_CAP & caps) {
+				rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
+					&ExtAttrBits, &ExtAttrMask);
+				if(rc == 0)
+					rc = put_user(ExtAttrBits &
+						EXT2_FL_USER_VISIBLE,
+						(int __user *)arg);
+			}
+			break;
+
 		case EXT2_IOC_SETFLAGS:
+			if(CIFS_UNIX_EXTATTR_CAP & caps) {
+				if(get_user(ExtAttrBits,(int __user *)arg)) {
+					rc = -EFAULT;
+					goto cifs_ioctl_out;
+				}
+			  /* rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
+					extAttrBits, &ExtAttrMask);*/
+				
+			}
 			cFYI(1,("set flags not implemented yet"));
-			return -EOPNOTSUPP;
+			break;
 		default:
 			cFYI(1,("unsupported ioctl"));
 			return rc;
 	}
 #endif /* CONFIG_CIFS_POSIX */
+
+cifs_ioctl_out:
+	FreeXid(xid);
 	return rc;
 } 
diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c
--- a/fs/cifs/misc.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/misc.c	2005-04-07 17:54:06 -07:00
@@ -514,3 +514,72 @@
 	printk( " | %s\n", debug_line);
 	return;
 }
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+/* Windows maps these to the user defined 16 bit Unicode range since they are
+   reserved symbols (along with \ and /), otherwise illegal to store
+   in filenames in NTFS */
+#define UNI_ASTERIK     cpu_to_le16('*' + 0xF000)
+#define UNI_QUESTION    cpu_to_le16('?' + 0xF000)
+#define UNI_COLON       cpu_to_le16(':' + 0xF000)
+#define UNI_GRTRTHAN    cpu_to_le16('>' + 0xF000)
+#define UNI_LESSTHAN    cpu_to_le16('<' + 0xF000)
+#define UNI_PIPE        cpu_to_le16('|' + 0xF000)
+#define UNI_SLASH       cpu_to_le16('\\' + 0xF000)
+
+/* Convert 16 bit Unicode pathname from wire format to string in current code
+   page.  Conversion may involve remapping up the seven characters that are
+   only legal in POSIX-like OS (if they are present in the string). Path
+   names are little endian 16 bit Unicode on the wire */
+int
+cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
+		    const struct nls_table * cp)
+{
+	int i,j,len;
+	wchar_t src_char;
+
+	for(i = 0, j = 0; i < maxlen; i++) {
+		src_char = le16_to_cpu(source[i]);
+		switch (src_char) {
+			case 0:
+				goto cUCS_out; /* BB check this BB */
+			case UNI_COLON:
+				target[j] = ':';
+				break;
+			case UNI_ASTERIK:
+				target[j] = '*';
+				break;
+			case UNI_QUESTION:
+				target[j] = '?';
+				break;
+			case UNI_SLASH:
+				target[j] = '\\'; /* BB check this - is there risk here of converting path sep BB */
+				break;
+			case UNI_PIPE:
+				target[j] = '|';
+				break;
+			case UNI_GRTRTHAN:
+				target[j] = '>';
+				break;
+			case UNI_LESSTHAN:
+				target[j] = '<';
+			default: 
+				len = cp->uni2char(src_char, &target[j], 
+						NLS_MAX_CHARSET_SIZE);
+				if(len > 0) {
+					j += len;
+					continue;
+				} else {
+					target[j] = '?';
+				}
+		}
+		j++;
+		/* check to make sure we do not overrun callers allocated temp buffer */
+		if(j >= (2 * NAME_MAX))
+			break;
+	}
+cUCS_out:
+	target[j] = 0;
+	return j;
+}
+#endif /* CIFS_EXPERIMENTAL */
diff -Nru a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
--- a/fs/cifs/netmisc.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/netmisc.c	2005-04-07 17:54:06 -07:00
@@ -206,7 +206,7 @@
 	{
 	ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {
 	ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {
-	ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, {
+	ERRDOS, ERRinvlevel, NT_STATUS_INVALID_INFO_CLASS}, {
 	ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, {
 	ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, {
 	ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, {
diff -Nru a/fs/cifs/readdir.c b/fs/cifs/readdir.c
--- a/fs/cifs/readdir.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/readdir.c	2005-04-07 17:54:06 -07:00
@@ -323,6 +323,7 @@
 
 	cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
 
+ffirst_retry:
 	/* test for Unix extensions */
 	if (pTcon->ses->capabilities & CAP_UNIX) {
 		cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; 
@@ -336,6 +337,11 @@
 		&cifsFile->netfid, &cifsFile->srch_inf); 
 	if(rc == 0)
 		cifsFile->invalidHandle = FALSE;
+	if((rc == -EOPNOTSUPP) && 
+		(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
+		goto ffirst_retry;
+	}
 	kfree(full_path);
 	return rc;
 }
@@ -594,7 +600,14 @@
 	if(unicode) {
 		/* BB fixme - test with long names */
 		/* Note converted filename can be longer than in unicode */
-		pqst->len = cifs_strfromUCS_le((char *)pqst->name,(wchar_t *)filename,len/2,nlt);
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
+			pqst->len = cifs_convertUCSpath((char *)pqst->name,
+					(__le16 *)filename, len/2, nlt);
+		else
+#endif /* CIFS_EXPERIMENTAL */
+			pqst->len = cifs_strfromUCS_le((char *)pqst->name,
+					(wchar_t *)filename,len/2,nlt);
 	} else {
 		pqst->name = filename;
 		pqst->len = len;
@@ -823,7 +836,11 @@
 		end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
 			smbCalcSize((struct smb_hdr *)
 				    cifsFile->srch_inf.ntwrk_buf_start);
-		tmp_buf = kmalloc(NAME_MAX+1,GFP_KERNEL);
+		/* To be safe - for UCS to UTF-8 with strings loaded
+		with the rare long characters alloc more to account for
+		such multibyte target UTF-8 characters. cifs_unicode.c,
+		which actually does the conversion, has the same limit */
+		tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
 		for(i=0;(i<num_to_fill) && (rc == 0);i++) {
 			if(current_entry == NULL) {
 				/* evaluate whether this case is an error */
diff -Nru a/fs/cifs/smberr.h b/fs/cifs/smberr.h
--- a/fs/cifs/smberr.h	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/smberr.h	2005-04-07 17:54:06 -07:00
@@ -22,94 +22,155 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
  */
 
-#define SUCCESS 0		/* The request was successful. */
-#define ERRDOS 0x01		/* Error is from the core DOS operating system set */
-#define ERRSRV 0x02		/* Error is generated by the file server daemon */
-#define ERRHRD 0x03		/* Error is a hardware error. */
-#define ERRCMD 0xFF		/*  Command was not in the "SMB" format. */
+#define SUCCESS	0x00	/* The request was successful. */
+#define ERRDOS	0x01	/* Error is from the core DOS operating system set */
+#define ERRSRV	0x02	/* Error is generated by the file server daemon */
+#define ERRHRD	0x03	/* Error is a hardware error. */
+#define ERRCMD	0xFF	/* Command was not in the "SMB" format. */
 
 /* The following error codes may be generated with the SUCCESS error class.*/
 
-#define SUCCESS 0		/* The request was successful. */
+/*#define SUCCESS	0	The request was successful. */
 
 /* The following error codes may be generated with the ERRDOS error class.*/
 
-#define ERRbadfunc 1		/* Invalid function. The server did not recognize or could not perform a system call generated by the server, e.g., set the DIRECTORY attribute on a data file, invalid seek mode. */
-#define ERRbadfile 2		/*File not found. The last component of a file's pathname could not be found. */
-#define ERRbadpath 3		/* Directory invalid. A directory component in a pathname could not be found. */
-#define ERRnofids 4		/* Too many open files. The server has no file handles available. */
-#define ERRnoaccess 5		/* Access denied, the client's context does not permit the requested function. This includes the following conditions: invalid rename command, write to Fid open for read only, read on Fid open for write only, attempt to delete a non-empty directory */
-#define ERRbadfid 6		/* Invalid file handle. The file handle specified was not recognized by the server. */
-#define ERRbadmcb 7		/* Memory control blocks destroyed. */
-#define ERRnomem 8		/* Insufficient server memory to perform the requested function. */
-#define ERRbadmem 9		/* Invalid memory block address. */
-#define ERRbadenv 10		/* Invalid environment. */
-#define ERRbadformat 11		/* Invalid format. */
-#define ERRbadaccess 12		/* Invalid open mode. */
-#define ERRbaddata 13		/* Invalid data (generated only by IOCTL calls within the server). */
-#define ERRbaddrive 15		/* Invalid drive specified. */
-#define ERRremcd 16		/* A Delete Directory request attempted to remove the server's current directory. */
-#define ERRdiffdevice 17	/* Not same device (e.g., a cross volume rename was attempted */
-#define ERRnofiles 18		/* A File Search command can find no more files matching the specified criteria. */
-#define ERRgeneral 31
-#define ERRbadshare 32		/* The sharing mode specified for an Open conflicts with existing FIDs on the file. */
-#define ERRlock 33		/* A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process. */
-#define ERRunsup     50
-#define ERRnosuchshare 67
-#define ERRfilexists 80		/* The file named in the request already exists. */
-#define ERRinvparm   87
-#define ERRdiskfull  112
-#define ERRinvname   123
-#define ERRinvlevel  124
-#define ERRdirnotempty 145
-#define ERRnotlocked   158
-#define ERRalreadyexists 183
-#define ERRbadpipe 230
-#define ERRpipebusy 231
-#define ERRpipeclosing 232
-#define ERRnotconnected 233
-#define ERRmoredata    234
-#define ERReasnotsupported 282
-#define ErrQuota 0x200		/* The operation would cause a quota limit to be exceeded. */
-#define ErrNotALink 0x201	/* A link operation was performed on a pathname that
-				   was not a link. */
-
-/* Following error codes may be generated with the ERRSRV error
-class.*/
-
-#define ERRerror 1		/* Non-specific error code. It is returned under the following conditions: resource other than disk space exhausted (e.g. TIDs), first SMB command was not negotiate, multiple negotiates attempted, and internal server error. */
-#define ERRbadpw 2		/* Bad password - name/password pair in a TreeConnect or Session Setup are invalid. */
-#define ERRbadtype 3		/* used for indicating DFS referral needed */
-#define ERRaccess 4		/* The client does not have the necessary access rights within the specified context for requested function. */
-#define ERRinvtid 5		/* The Tid specified in a command was invalid. */
-#define ERRinvnetname 6		/* Invalid network name in tree connect. */
-#define ERRinvdevice 7		/* Invalid device - printer request made to non-printer connection or non-printer request made to printer connection. */
-#define ERRqfull 49		/* Print queue full (files) -- returned by open print file. */
-#define ERRqtoobig 50		/* Print queue full -- no space. */
-#define ERRqeof         51	/* EOF on print queue dump */
-#define ERRinvpfid      52	/* Invalid print file FID. */
-#define ERRsmbcmd       64	/* The server did not recognize the command received. */
-#define ERRsrverror     65	/* The server encountered an internal error, e.g., system file unavailable. */
-#define ERRbadBID       66	/* (obsolete) */
-#define ERRfilespecs    67	/* The Fid and pathname parameters contained an invalid combination of values. */
-#define ERRbadLink      68	/* (obsolete) */
-#define ERRbadpermits   69	/* The access permissions specified for a file or directory are not a valid combination. */
-#define ERRbadPID       70
-#define ERRsetattrmode  71	/* attribute (mode) is invalid */
-#define ERRpaused       81	/* Server is paused */
-#define ERRmsgoff	82	/* reserved - messaging off */
-#define ERRnoroom       83	/* reserved - no room for message */
-#define ERRrmuns        87	/* reserved - too many remote names */
-#define ERRtimeout      88	/* operation timed out */
-#define ERRnoresource   89	/* No resources available for request */
-#define ERRtoomanyuids  90	/* Too many UIDs active on this session */
-#define ERRbaduid       91	/* The UID is not known as a valid user */
-#define ERRusempx      250	/* temporarily unable to use raw */
-#define ERRusestd      251	/* temporarily unable to use either raw or mpx */
-#define ERR_NOTIFY_ENUM_DIR 1024
-#define ERRaccountexpired 2239
-#define ERRbadclient      2240
-#define ERRbadLogonTime   2241
-#define ERRpasswordExpired 2242
-#define ERRnetlogonNotStarted 2455
-#define ERRnosupport       0xFFFF
+#define ERRbadfunc		1	/* Invalid function. The server did not
+					   recognize or could not perform a
+					   system call generated by the server,
+					   e.g., set the DIRECTORY attribute on
+					   a data file, invalid seek mode. */
+#define ERRbadfile		2	/* File not found. The last component
+					   of a file's pathname could not be
+					   found. */
+#define ERRbadpath		3	/* Directory invalid. A directory
+					   component in a pathname could not be
+					   found. */
+#define ERRnofids		4	/* Too many open files. The server has
+					   no file handles available. */
+#define ERRnoaccess		5	/* Access denied, the client's context
+					   does not permit the requested
+					   function. This includes the
+					   following conditions: invalid rename
+					   command, write to Fid open for read
+					   only, read on Fid open for write
+					   only, attempt to delete a non-empty
+					   directory */
+#define ERRbadfid		6	/* Invalid file handle. The file handle
+					   specified was not recognized by the
+					   server. */
+#define ERRbadmcb		7	/* Memory control blocks destroyed. */
+#define ERRnomem		8	/* Insufficient server memory to
+					   perform the requested function. */
+#define ERRbadmem		9	/* Invalid memory block address. */
+#define ERRbadenv		10	/* Invalid environment. */
+#define ERRbadformat		11	/* Invalid format. */
+#define ERRbadaccess		12	/* Invalid open mode. */
+#define ERRbaddata		13	/* Invalid data (generated only by
+					   IOCTL calls within the server). */
+#define ERRbaddrive		15	/* Invalid drive specified. */
+#define ERRremcd		16	/* A Delete Directory request attempted
+					   to remove the server's current
+					   directory. */
+#define ERRdiffdevice		17	/* Not same device (e.g., a cross
+					   volume rename was attempted */
+#define ERRnofiles		18	/* A File Search command can find no
+					   more files matching the specified
+					   criteria. */
+#define ERRgeneral		31
+#define ERRbadshare		32	/* The sharing mode specified for an
+					   Open conflicts with existing FIDs on
+					   the file. */
+#define ERRlock			33	/* A Lock request conflicted with an
+					   existing lock or specified an
+					   invalid mode, or an Unlock requested
+					   attempted to remove a lock held by
+					   another process. */
+#define ERRunsup		50
+#define ERRnosuchshare		67
+#define ERRfilexists		80	/* The file named in the request
+					   already exists. */
+#define ERRinvparm		87
+#define ERRdiskfull		112
+#define ERRinvname		123
+#define ERRinvlevel		124
+#define ERRdirnotempty		145
+#define ERRnotlocked		158
+#define ERRalreadyexists	183
+#define ERRbadpipe		230
+#define ERRpipebusy		231
+#define ERRpipeclosing		232
+#define ERRnotconnected		233
+#define ERRmoredata		234
+#define ERReasnotsupported	282
+#define ErrQuota		0x200	/* The operation would cause a quota
+					   limit to be exceeded. */
+#define ErrNotALink		0x201	/* A link operation was performed on a
+					   pathname that was not a link. */
+
+/* Following error codes may be generated with the ERRSRV error class.*/
+
+#define ERRerror		1	/* Non-specific error code. It is
+					   returned under the following
+					   conditions: resource other than disk
+					   space exhausted (e.g. TIDs), first
+					   SMB command was not negotiate,
+					   multiple negotiates attempted, and
+					   internal server error. */
+#define ERRbadpw		2	/* Bad password - name/password pair in
+					   a TreeConnect or Session Setup are
+					   invalid. */
+#define ERRbadtype		3	/* used for indicating DFS referral
+					   needed */
+#define ERRaccess		4	/* The client does not have the
+					   necessary access rights within the
+					   specified context for requested
+					   function. */
+#define ERRinvtid		5	/* The Tid specified in a command was
+					   invalid. */
+#define ERRinvnetname		6	/* Invalid network name in tree
+					   connect. */
+#define ERRinvdevice		7	/* Invalid device - printer request
+					   made to non-printer connection or
+					   non-printer request made to printer
+					   connection. */
+#define ERRqfull		49	/* Print queue full (files) -- returned
+					   by open print file. */
+#define ERRqtoobig		50	/* Print queue full -- no space. */
+#define ERRqeof			51	/* EOF on print queue dump */
+#define ERRinvpfid		52	/* Invalid print file FID. */
+#define ERRsmbcmd		64	/* The server did not recognize the
+					   command received. */
+#define ERRsrverror		65	/* The server encountered an internal
+					   error, e.g., system file
+					   unavailable. */
+#define ERRbadBID		66	/* (obsolete) */
+#define ERRfilespecs		67	/* The Fid and pathname parameters
+					   contained an invalid combination of
+					   values. */
+#define ERRbadLink		68	/* (obsolete) */
+#define ERRbadpermits		69	/* The access permissions specified for
+					   a file or directory are not a valid
+					   combination. */
+#define ERRbadPID		70
+#define ERRsetattrmode		71	/* attribute (mode) is invalid */
+#define ERRpaused		81	/* Server is paused */
+#define ERRmsgoff		82	/* reserved - messaging off */
+#define ERRnoroom		83	/* reserved - no room for message */
+#define ERRrmuns		87	/* reserved - too many remote names */
+#define ERRtimeout		88	/* operation timed out */
+#define ERRnoresource		89	/* No resources available for request
+					   */
+#define ERRtoomanyuids		90	/* Too many UIDs active on this session
+					   */
+#define ERRbaduid		91	/* The UID is not known as a valid user
+					   */
+#define ERRusempx		250	/* temporarily unable to use raw */
+#define ERRusestd		251	/* temporarily unable to use either raw
+					   or mpx */
+#define ERR_NOTIFY_ENUM_DIR	1024
+#define ERRaccountexpired	2239
+#define ERRbadclient		2240
+#define ERRbadLogonTime		2241
+#define ERRpasswordExpired	2242
+#define ERRnetlogonNotStarted	2455
+#define ERRnosupport		0xFFFF
diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c
--- a/fs/cifs/transport.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/transport.c	2005-04-07 17:54:06 -07:00
@@ -346,7 +346,7 @@
 	}
 
 	/* BB can we sign efficiently in this path? */
-	rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number);
+	rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
 
 	midQ->midState = MID_REQUEST_SUBMITTED;
 /*	rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, piovec,
@@ -475,7 +475,7 @@
 		return -EIO;
 	}
 
-	rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number);
+	rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
 
 	midQ->midState = MID_REQUEST_SUBMITTED;
 	rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
@@ -559,8 +559,7 @@
 	}
   
 	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-		cERROR(1,
-		       ("Frame too large received.  Length: %d  Xid: %d",
+		cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
 			receive_len, xid));
 		rc = -EIO;
 	} else {		/* rcvd frame is ok */
@@ -575,15 +574,20 @@
 			dump_smb(out_buf, 92);
 			/* convert the length into a more usable form */
 			if((receive_len > 24) &&
-			   (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) {
-				rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */
-				if(rc)
-					cFYI(1,("Unexpected signature received from server"));
+			   (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
+					SECMODE_SIGN_ENABLED))) {
+				rc = cifs_verify_signature(out_buf,
+						ses->server->mac_signing_key,
+						midQ->sequence_number+1);
+				if(rc) {
+					cERROR(1,("Unexpected packet signature received from server"));
+					/* BB FIXME - add code to kill session here */
+				}
 			}
 
 			*pbytes_returned = out_buf->smb_buf_length;
 
-			/* BB special case reconnect tid and reconnect uid here? */
+			/* BB special case reconnect tid and uid here? */
 			rc = map_smb_to_linux_error(out_buf);
 
 			/* convert ByteCount if necessary */
diff -Nru a/fs/cifs/xattr.c b/fs/cifs/xattr.c
--- a/fs/cifs/xattr.c	2005-04-07 17:54:06 -07:00
+++ b/fs/cifs/xattr.c	2005-04-07 17:54:06 -07:00
@@ -161,18 +161,20 @@
 			strlen(POSIX_ACL_XATTR_ACCESS));
 		if (temp == 0) {
 #ifdef CONFIG_CIFS_POSIX
-			rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,ea_value,
-				(const int)value_size, ACL_TYPE_ACCESS,
-				cifs_sb->local_nls);
+			if(sb->s_flags & MS_POSIXACL)
+				rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
+					ea_value, (const int)value_size, 
+					ACL_TYPE_ACCESS,cifs_sb->local_nls);
 			cFYI(1,("set POSIX ACL rc %d",rc));
 #else
 			cFYI(1,("set POSIX ACL not supported"));
 #endif
 		} else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
-			rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,ea_value,
-				(const int)value_size, ACL_TYPE_DEFAULT,
-				cifs_sb->local_nls);
+			if(sb->s_flags & MS_POSIXACL)
+				rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
+					ea_value, (const int)value_size, 
+					ACL_TYPE_DEFAULT, cifs_sb->local_nls);
 			cFYI(1,("set POSIX default ACL rc %d",rc));
 #else
 			cFYI(1,("set default POSIX ACL not supported"));
@@ -248,7 +250,8 @@
 			buf_size, cifs_sb->local_nls);
 	} else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
-		rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
+		if(sb->s_flags & MS_POSIXACL)
+			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
 				ea_value, buf_size, ACL_TYPE_ACCESS, 
 				cifs_sb->local_nls);
 #else 
@@ -256,7 +259,8 @@
 #endif /* CONFIG_CIFS_POSIX */
 	} else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
-		rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
+		if(sb->s_flags & MS_POSIXACL)
+			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
 				ea_value, buf_size, ACL_TYPE_DEFAULT, 
 				cifs_sb->local_nls);
 #else 
