diff options
author | Steve French <sfrench@us.ibm.com> | 2006-03-03 04:53:36 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-03-03 04:53:36 -0500 |
commit | 083d3a2cff514c5301f3a043642940d4d5371b22 (patch) | |
tree | 9dd82892244234401b54fe4133d3c2947b8a3b90 /fs/cifs | |
parent | a4e85b5f620f59bd9308e29f833648f792d422f7 (diff) |
[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>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/CHANGES | 3 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/connect.c | 8 | ||||
-rw-r--r-- | fs/cifs/inode.c | 4 | ||||
-rw-r--r-- | fs/cifs/link.c | 2 |
5 files changed, 14 insertions, 5 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 25d7df4a00c3..6238da96cc77 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -8,7 +8,8 @@ max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in | |||
8 | cifs_user_read and cifs_readpages (when EAGAIN on send of smb | 8 | cifs_user_read and cifs_readpages (when EAGAIN on send of smb |
9 | on socket is returned over and over). Add POSIX (advisory) byte range | 9 | on socket is returned over and over). Add POSIX (advisory) byte range |
10 | locking support (requires server with newest CIFS UNIX Extensions | 10 | locking support (requires server with newest CIFS UNIX Extensions |
11 | to the protocol implemented). | 11 | to the protocol implemented). Slow down negprot slightly in port 139 |
12 | RFC1001 case to give session_init time on buggy servers. | ||
12 | 13 | ||
13 | Version 1.40 | 14 | Version 1.40 |
14 | ------------ | 15 | ------------ |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 4cf10f23cda9..b4dcdc2052a0 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | |||
99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
101 | unsigned int command, unsigned long arg); | 101 | unsigned int command, unsigned long arg); |
102 | #define CIFS_VERSION "1.41" | 102 | #define CIFS_VERSION "1.42" |
103 | #endif /* _CIFSFS_H */ | 103 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index b8f1baabd343..3651deca4f24 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1476,6 +1476,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1476 | rc = smb_send(*csocket, smb_buf, 0x44, | 1476 | rc = smb_send(*csocket, smb_buf, 0x44, |
1477 | (struct sockaddr *)psin_server); | 1477 | (struct sockaddr *)psin_server); |
1478 | kfree(ses_init_buf); | 1478 | kfree(ses_init_buf); |
1479 | msleep(1); /* RFC1001 layer in at least one server | ||
1480 | requires very short break before negprot | ||
1481 | presumably because not expecting negprot | ||
1482 | to follow so fast. This is a simple | ||
1483 | solution that works without | ||
1484 | complicating the code and causes no | ||
1485 | significant slowing down on mount | ||
1486 | for everyone else */ | ||
1479 | } | 1487 | } |
1480 | /* else the negprot may still work without this | 1488 | /* else the negprot may still work without this |
1481 | even though malloc failed */ | 1489 | even though malloc failed */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0a46a9395ec4..b21038b99fc2 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1166,7 +1166,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1166 | nfid, npid, FALSE); | 1166 | nfid, npid, FALSE); |
1167 | atomic_dec(&open_file->wrtPending); | 1167 | atomic_dec(&open_file->wrtPending); |
1168 | cFYI(1,("SetFSize for attrs rc = %d", rc)); | 1168 | cFYI(1,("SetFSize for attrs rc = %d", rc)); |
1169 | if((rc == -EINVAL) ||(rc == -EOPNOTSUPP)) { | 1169 | if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
1170 | int bytes_written; | 1170 | int bytes_written; |
1171 | rc = CIFSSMBWrite(xid, pTcon, | 1171 | rc = CIFSSMBWrite(xid, pTcon, |
1172 | nfid, 0, attrs->ia_size, | 1172 | nfid, 0, attrs->ia_size, |
@@ -1188,7 +1188,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1188 | cifs_sb->mnt_cifs_flags & | 1188 | cifs_sb->mnt_cifs_flags & |
1189 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1189 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1190 | cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); | 1190 | cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); |
1191 | if(rc == -EINVAL) { | 1191 | if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
1192 | __u16 netfid; | 1192 | __u16 netfid; |
1193 | int oplock = FALSE; | 1193 | int oplock = FALSE; |
1194 | 1194 | ||
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 0f99aae33162..ce86ec69fe01 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -67,7 +67,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, | |||
67 | cifs_sb_target->local_nls, | 67 | cifs_sb_target->local_nls, |
68 | cifs_sb_target->mnt_cifs_flags & | 68 | cifs_sb_target->mnt_cifs_flags & |
69 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 69 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
70 | if(rc == -EIO) | 70 | if((rc == -EIO) || (rc == -EINVAL)) |
71 | rc = -EOPNOTSUPP; | 71 | rc = -EOPNOTSUPP; |
72 | } | 72 | } |
73 | 73 | ||