فهرست منبع

[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>

Steve French 19 سال پیش
والد
کامیت
083d3a2cff
5فایلهای تغییر یافته به همراه14 افزوده شده و 5 حذف شده
  1. 2 1
      fs/cifs/CHANGES
  2. 1 1
      fs/cifs/cifsfs.h
  3. 8 0
      fs/cifs/connect.c
  4. 2 2
      fs/cifs/inode.c
  5. 1 1
      fs/cifs/link.c

+ 2 - 1
fs/cifs/CHANGES

@@ -8,7 +8,8 @@ max smb buffer size when CIFSMaxBufSize over 64K.  Fix oops in
 cifs_user_read and cifs_readpages (when EAGAIN on send of smb
 cifs_user_read and cifs_readpages (when EAGAIN on send of smb
 on socket is returned over and over).  Add POSIX (advisory) byte range
 on socket is returned over and over).  Add POSIX (advisory) byte range
 locking support (requires server with newest CIFS UNIX Extensions
 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
 Version 1.40
 ------------
 ------------

+ 1 - 1
fs/cifs/cifsfs.h

@@ -99,5 +99,5 @@ extern ssize_t	cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
 		       unsigned int command, unsigned long arg);
 		       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.41"
+#define CIFS_VERSION   "1.42"
 #endif				/* _CIFSFS_H */
 #endif				/* _CIFSFS_H */

+ 8 - 0
fs/cifs/connect.c

@@ -1476,6 +1476,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
 			rc = smb_send(*csocket, smb_buf, 0x44,
 			rc = smb_send(*csocket, smb_buf, 0x44,
 				(struct sockaddr *)psin_server);
 				(struct sockaddr *)psin_server);
 			kfree(ses_init_buf);
 			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 
 		/* else the negprot may still work without this 
 		even though malloc failed */
 		even though malloc failed */

+ 2 - 2
fs/cifs/inode.c

@@ -1166,7 +1166,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 						nfid, npid, FALSE);
 						nfid, npid, FALSE);
 			atomic_dec(&open_file->wrtPending);
 			atomic_dec(&open_file->wrtPending);
 			cFYI(1,("SetFSize for attrs rc = %d", rc));
 			cFYI(1,("SetFSize for attrs rc = %d", rc));
-			if((rc == -EINVAL) ||(rc == -EOPNOTSUPP)) {
+			if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 				int bytes_written;
 				int bytes_written;
 				rc = CIFSSMBWrite(xid, pTcon,
 				rc = CIFSSMBWrite(xid, pTcon,
 						  nfid, 0, attrs->ia_size,
 						  nfid, 0, attrs->ia_size,
@@ -1188,7 +1188,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 					   cifs_sb->mnt_cifs_flags &
 					   cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
 			cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
-			if(rc == -EINVAL) {
+			if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 				__u16 netfid;
 				__u16 netfid;
 				int oplock = FALSE;
 				int oplock = FALSE;
 
 

+ 1 - 1
fs/cifs/link.c

@@ -67,7 +67,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
 					cifs_sb_target->local_nls, 
 					cifs_sb_target->local_nls, 
 					cifs_sb_target->mnt_cifs_flags &
 					cifs_sb_target->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
-		if(rc == -EIO)
+		if((rc == -EIO) || (rc == -EINVAL))
 			rc = -EOPNOTSUPP;  
 			rc = -EOPNOTSUPP;  
 	}
 	}