[CIFS] Workaround various server bugs found in testing at connectathon
	- slow down negprot 1ms during mount when RFC1001 over port 139
	to give buggy servers time to clear sess_init
	- remap some plausible but incorrect SMB return codes to the
	right ones in truncate and hardlink paths

Signed-off-by: Steve French <sfrench@us.ibm.com>
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 25d7df4..6238da9 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -8,7 +8,8 @@
 cifs_user_read and cifs_readpages (when EAGAIN on send of smb
 on socket is returned over and over).  Add POSIX (advisory) byte range
 locking support (requires server with newest CIFS UNIX Extensions
-to the protocol implemented).
+to the protocol implemented). Slow down negprot slightly in port 139
+RFC1001 case to give session_init time on buggy servers.
 
 Version 1.40
 ------------
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 4cf10f2..b4dcdc2 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -99,5 +99,5 @@
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
 		       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.41"
+#define CIFS_VERSION   "1.42"
 #endif				/* _CIFSFS_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index b8f1baa..3651dec 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1476,6 +1476,14 @@
 			rc = smb_send(*csocket, smb_buf, 0x44,
 				(struct sockaddr *)psin_server);
 			kfree(ses_init_buf);
+			msleep(1); /* RFC1001 layer in at least one server 
+				      requires very short break before negprot
+				      presumably because not expecting negprot
+				      to follow so fast.  This is a simple
+				      solution that works without 
+				      complicating the code and causes no
+				      significant slowing down on mount
+				      for everyone else */
 		}
 		/* else the negprot may still work without this 
 		even though malloc failed */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 0a46a93..b21038b 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1166,7 +1166,7 @@
 						nfid, npid, FALSE);
 			atomic_dec(&open_file->wrtPending);
 			cFYI(1,("SetFSize for attrs rc = %d", rc));
-			if((rc == -EINVAL) ||(rc == -EOPNOTSUPP)) {
+			if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 				int bytes_written;
 				rc = CIFSSMBWrite(xid, pTcon,
 						  nfid, 0, attrs->ia_size,
@@ -1188,7 +1188,7 @@
 					   cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
-			if(rc == -EINVAL) {
+			if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 				__u16 netfid;
 				int oplock = FALSE;
 
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 0f99aae..ce86ec6 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -67,7 +67,7 @@
 					cifs_sb_target->local_nls, 
 					cifs_sb_target->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
-		if(rc == -EIO)
+		if((rc == -EIO) || (rc == -EINVAL))
 			rc = -EOPNOTSUPP;  
 	}