diff options
| -rw-r--r-- | fs/cifs/Kconfig | 1 | ||||
| -rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 9 | ||||
| -rw-r--r-- | fs/cifs/cifsencrypt.c | 5 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 3 | ||||
| -rw-r--r-- | fs/cifs/file.c | 8 | ||||
| -rw-r--r-- | fs/cifs/link.c | 3 | ||||
| -rw-r--r-- | fs/cifs/misc.c | 116 | ||||
| -rw-r--r-- | fs/cifs/readdir.c | 3 | ||||
| -rw-r--r-- | fs/cifs/smbencrypt.c | 3 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 62 |
11 files changed, 130 insertions, 85 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index ee45648b0d1a..7cb0f7f847e4 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
| @@ -3,6 +3,7 @@ config CIFS | |||
| 3 | depends on INET | 3 | depends on INET |
| 4 | select NLS | 4 | select NLS |
| 5 | select CRYPTO | 5 | select CRYPTO |
| 6 | select CRYPTO_MD4 | ||
| 6 | select CRYPTO_MD5 | 7 | select CRYPTO_MD5 |
| 7 | select CRYPTO_HMAC | 8 | select CRYPTO_HMAC |
| 8 | select CRYPTO_ARC4 | 9 | select CRYPTO_ARC4 |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index f1c68629f277..0a265ad9e426 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
| @@ -282,8 +282,6 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) | |||
| 282 | cFYI(1, "in %s", __func__); | 282 | cFYI(1, "in %s", __func__); |
| 283 | BUG_ON(IS_ROOT(mntpt)); | 283 | BUG_ON(IS_ROOT(mntpt)); |
| 284 | 284 | ||
| 285 | xid = GetXid(); | ||
| 286 | |||
| 287 | /* | 285 | /* |
| 288 | * The MSDFS spec states that paths in DFS referral requests and | 286 | * The MSDFS spec states that paths in DFS referral requests and |
| 289 | * responses must be prefixed by a single '\' character instead of | 287 | * responses must be prefixed by a single '\' character instead of |
| @@ -293,7 +291,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) | |||
| 293 | mnt = ERR_PTR(-ENOMEM); | 291 | mnt = ERR_PTR(-ENOMEM); |
| 294 | full_path = build_path_from_dentry(mntpt); | 292 | full_path = build_path_from_dentry(mntpt); |
| 295 | if (full_path == NULL) | 293 | if (full_path == NULL) |
| 296 | goto free_xid; | 294 | goto cdda_exit; |
| 297 | 295 | ||
| 298 | cifs_sb = CIFS_SB(mntpt->d_inode->i_sb); | 296 | cifs_sb = CIFS_SB(mntpt->d_inode->i_sb); |
| 299 | tlink = cifs_sb_tlink(cifs_sb); | 297 | tlink = cifs_sb_tlink(cifs_sb); |
| @@ -303,9 +301,11 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) | |||
| 303 | } | 301 | } |
| 304 | ses = tlink_tcon(tlink)->ses; | 302 | ses = tlink_tcon(tlink)->ses; |
| 305 | 303 | ||
| 304 | xid = GetXid(); | ||
| 306 | rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, | 305 | rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, |
| 307 | &num_referrals, &referrals, | 306 | &num_referrals, &referrals, |
| 308 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 307 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 308 | FreeXid(xid); | ||
| 309 | 309 | ||
| 310 | cifs_put_tlink(tlink); | 310 | cifs_put_tlink(tlink); |
| 311 | 311 | ||
| @@ -338,8 +338,7 @@ success: | |||
| 338 | free_dfs_info_array(referrals, num_referrals); | 338 | free_dfs_info_array(referrals, num_referrals); |
| 339 | free_full_path: | 339 | free_full_path: |
| 340 | kfree(full_path); | 340 | kfree(full_path); |
| 341 | free_xid: | 341 | cdda_exit: |
| 342 | FreeXid(xid); | ||
| 343 | cFYI(1, "leaving %s" , __func__); | 342 | cFYI(1, "leaving %s" , __func__); |
| 344 | return mnt; | 343 | return mnt; |
| 345 | } | 344 | } |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 0db5f1de0227..a51585f9852b 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
| @@ -657,9 +657,10 @@ calc_seckey(struct cifsSesInfo *ses) | |||
| 657 | get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); | 657 | get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); |
| 658 | 658 | ||
| 659 | tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); | 659 | tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); |
| 660 | if (!tfm_arc4 || IS_ERR(tfm_arc4)) { | 660 | if (IS_ERR(tfm_arc4)) { |
| 661 | rc = PTR_ERR(tfm_arc4); | ||
| 661 | cERROR(1, "could not allocate crypto API arc4\n"); | 662 | cERROR(1, "could not allocate crypto API arc4\n"); |
| 662 | return PTR_ERR(tfm_arc4); | 663 | return rc; |
| 663 | } | 664 | } |
| 664 | 665 | ||
| 665 | desc.tfm = tfm_arc4; | 666 | desc.tfm = tfm_arc4; |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 14789a97304e..4a3330235d55 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -127,5 +127,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
| 127 | extern const struct export_operations cifs_export_ops; | 127 | extern const struct export_operations cifs_export_ops; |
| 128 | #endif /* EXPERIMENTAL */ | 128 | #endif /* EXPERIMENTAL */ |
| 129 | 129 | ||
| 130 | #define CIFS_VERSION "1.69" | 130 | #define CIFS_VERSION "1.70" |
| 131 | #endif /* _CIFSFS_H */ | 131 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3106f5e5c633..46c66ed01af4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -4914,7 +4914,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, | |||
| 4914 | __u16 fid, __u32 pid_of_opener, bool SetAllocation) | 4914 | __u16 fid, __u32 pid_of_opener, bool SetAllocation) |
| 4915 | { | 4915 | { |
| 4916 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | 4916 | struct smb_com_transaction2_sfi_req *pSMB = NULL; |
| 4917 | char *data_offset; | ||
| 4918 | struct file_end_of_file_info *parm_data; | 4917 | struct file_end_of_file_info *parm_data; |
| 4919 | int rc = 0; | 4918 | int rc = 0; |
| 4920 | __u16 params, param_offset, offset, byte_count, count; | 4919 | __u16 params, param_offset, offset, byte_count, count; |
| @@ -4938,8 +4937,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, | |||
| 4938 | param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; | 4937 | param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; |
| 4939 | offset = param_offset + params; | 4938 | offset = param_offset + params; |
| 4940 | 4939 | ||
| 4941 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | ||
| 4942 | |||
| 4943 | count = sizeof(struct file_end_of_file_info); | 4940 | count = sizeof(struct file_end_of_file_info); |
| 4944 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4941 | pSMB->MaxParameterCount = cpu_to_le16(2); |
| 4945 | /* BB find exact max SMB PDU from sess structure BB */ | 4942 | /* BB find exact max SMB PDU from sess structure BB */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0de17c1db608..74c0a282d012 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -346,7 +346,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
| 346 | struct cifsTconInfo *tcon; | 346 | struct cifsTconInfo *tcon; |
| 347 | struct tcon_link *tlink; | 347 | struct tcon_link *tlink; |
| 348 | struct cifsFileInfo *pCifsFile = NULL; | 348 | struct cifsFileInfo *pCifsFile = NULL; |
| 349 | struct cifsInodeInfo *pCifsInode; | ||
| 350 | char *full_path = NULL; | 349 | char *full_path = NULL; |
| 351 | bool posix_open_ok = false; | 350 | bool posix_open_ok = false; |
| 352 | __u16 netfid; | 351 | __u16 netfid; |
| @@ -361,8 +360,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
| 361 | } | 360 | } |
| 362 | tcon = tlink_tcon(tlink); | 361 | tcon = tlink_tcon(tlink); |
| 363 | 362 | ||
| 364 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | ||
| 365 | |||
| 366 | full_path = build_path_from_dentry(file->f_path.dentry); | 363 | full_path = build_path_from_dentry(file->f_path.dentry); |
| 367 | if (full_path == NULL) { | 364 | if (full_path == NULL) { |
| 368 | rc = -ENOMEM; | 365 | rc = -ENOMEM; |
| @@ -1146,7 +1143,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
| 1146 | char *write_data; | 1143 | char *write_data; |
| 1147 | int rc = -EFAULT; | 1144 | int rc = -EFAULT; |
| 1148 | int bytes_written = 0; | 1145 | int bytes_written = 0; |
| 1149 | struct cifs_sb_info *cifs_sb; | ||
| 1150 | struct inode *inode; | 1146 | struct inode *inode; |
| 1151 | struct cifsFileInfo *open_file; | 1147 | struct cifsFileInfo *open_file; |
| 1152 | 1148 | ||
| @@ -1154,7 +1150,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
| 1154 | return -EFAULT; | 1150 | return -EFAULT; |
| 1155 | 1151 | ||
| 1156 | inode = page->mapping->host; | 1152 | inode = page->mapping->host; |
| 1157 | cifs_sb = CIFS_SB(inode->i_sb); | ||
| 1158 | 1153 | ||
| 1159 | offset += (loff_t)from; | 1154 | offset += (loff_t)from; |
| 1160 | write_data = kmap(page); | 1155 | write_data = kmap(page); |
| @@ -1667,7 +1662,8 @@ static ssize_t | |||
| 1667 | cifs_iovec_write(struct file *file, const struct iovec *iov, | 1662 | cifs_iovec_write(struct file *file, const struct iovec *iov, |
| 1668 | unsigned long nr_segs, loff_t *poffset) | 1663 | unsigned long nr_segs, loff_t *poffset) |
| 1669 | { | 1664 | { |
| 1670 | size_t total_written = 0, written = 0; | 1665 | size_t total_written = 0; |
| 1666 | unsigned int written = 0; | ||
| 1671 | unsigned long num_pages, npages; | 1667 | unsigned long num_pages, npages; |
| 1672 | size_t copied, len, cur_len, i; | 1668 | size_t copied, len, cur_len, i; |
| 1673 | struct kvec *to_send; | 1669 | struct kvec *to_send; |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 02cd60aefbff..e8804d373404 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -55,8 +55,9 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | |||
| 55 | 55 | ||
| 56 | md5 = crypto_alloc_shash("md5", 0, 0); | 56 | md5 = crypto_alloc_shash("md5", 0, 0); |
| 57 | if (IS_ERR(md5)) { | 57 | if (IS_ERR(md5)) { |
| 58 | rc = PTR_ERR(md5); | ||
| 58 | cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); | 59 | cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); |
| 59 | return PTR_ERR(md5); | 60 | return rc; |
| 60 | } | 61 | } |
| 61 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); | 62 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); |
| 62 | sdescmd5 = kmalloc(size, GFP_KERNEL); | 63 | sdescmd5 = kmalloc(size, GFP_KERNEL); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index a09e077ba925..2a930a752a78 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
| @@ -236,10 +236,7 @@ __u16 GetNextMid(struct TCP_Server_Info *server) | |||
| 236 | { | 236 | { |
| 237 | __u16 mid = 0; | 237 | __u16 mid = 0; |
| 238 | __u16 last_mid; | 238 | __u16 last_mid; |
| 239 | int collision; | 239 | bool collision; |
| 240 | |||
| 241 | if (server == NULL) | ||
| 242 | return mid; | ||
| 243 | 240 | ||
| 244 | spin_lock(&GlobalMid_Lock); | 241 | spin_lock(&GlobalMid_Lock); |
| 245 | last_mid = server->CurrentMid; /* we do not want to loop forever */ | 242 | last_mid = server->CurrentMid; /* we do not want to loop forever */ |
| @@ -252,24 +249,38 @@ __u16 GetNextMid(struct TCP_Server_Info *server) | |||
| 252 | (and it would also have to have been a request that | 249 | (and it would also have to have been a request that |
| 253 | did not time out) */ | 250 | did not time out) */ |
| 254 | while (server->CurrentMid != last_mid) { | 251 | while (server->CurrentMid != last_mid) { |
| 255 | struct list_head *tmp; | ||
| 256 | struct mid_q_entry *mid_entry; | 252 | struct mid_q_entry *mid_entry; |
| 253 | unsigned int num_mids; | ||
| 257 | 254 | ||
| 258 | collision = 0; | 255 | collision = false; |
| 259 | if (server->CurrentMid == 0) | 256 | if (server->CurrentMid == 0) |
| 260 | server->CurrentMid++; | 257 | server->CurrentMid++; |
| 261 | 258 | ||
| 262 | list_for_each(tmp, &server->pending_mid_q) { | 259 | num_mids = 0; |
| 263 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 260 | list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { |
| 264 | 261 | ++num_mids; | |
| 265 | if ((mid_entry->mid == server->CurrentMid) && | 262 | if (mid_entry->mid == server->CurrentMid && |
| 266 | (mid_entry->midState == MID_REQUEST_SUBMITTED)) { | 263 | mid_entry->midState == MID_REQUEST_SUBMITTED) { |
| 267 | /* This mid is in use, try a different one */ | 264 | /* This mid is in use, try a different one */ |
| 268 | collision = 1; | 265 | collision = true; |
| 269 | break; | 266 | break; |
| 270 | } | 267 | } |
| 271 | } | 268 | } |
| 272 | if (collision == 0) { | 269 | |
| 270 | /* | ||
| 271 | * if we have more than 32k mids in the list, then something | ||
| 272 | * is very wrong. Possibly a local user is trying to DoS the | ||
| 273 | * box by issuing long-running calls and SIGKILL'ing them. If | ||
| 274 | * we get to 2^16 mids then we're in big trouble as this | ||
| 275 | * function could loop forever. | ||
| 276 | * | ||
| 277 | * Go ahead and assign out the mid in this situation, but force | ||
| 278 | * an eventual reconnect to clean out the pending_mid_q. | ||
| 279 | */ | ||
| 280 | if (num_mids > 32768) | ||
| 281 | server->tcpStatus = CifsNeedReconnect; | ||
| 282 | |||
| 283 | if (!collision) { | ||
| 273 | mid = server->CurrentMid; | 284 | mid = server->CurrentMid; |
| 274 | break; | 285 | break; |
| 275 | } | 286 | } |
| @@ -381,29 +392,31 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
| 381 | } | 392 | } |
| 382 | 393 | ||
| 383 | static int | 394 | static int |
| 384 | checkSMBhdr(struct smb_hdr *smb, __u16 mid) | 395 | check_smb_hdr(struct smb_hdr *smb, __u16 mid) |
| 385 | { | 396 | { |
| 386 | /* Make sure that this really is an SMB, that it is a response, | 397 | /* does it have the right SMB "signature" ? */ |
| 387 | and that the message ids match */ | 398 | if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) { |
| 388 | if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && | 399 | cERROR(1, "Bad protocol string signature header 0x%x", |
| 389 | (mid == smb->Mid)) { | 400 | *(unsigned int *)smb->Protocol); |
| 390 | if (smb->Flags & SMBFLG_RESPONSE) | 401 | return 1; |
| 391 | return 0; | 402 | } |
| 392 | else { | 403 | |
| 393 | /* only one valid case where server sends us request */ | 404 | /* Make sure that message ids match */ |
| 394 | if (smb->Command == SMB_COM_LOCKING_ANDX) | 405 | if (mid != smb->Mid) { |
| 395 | return 0; | 406 | cERROR(1, "Mids do not match. received=%u expected=%u", |
| 396 | else | 407 | smb->Mid, mid); |
| 397 | cERROR(1, "Received Request not response"); | 408 | return 1; |
| 398 | } | ||
| 399 | } else { /* bad signature or mid */ | ||
| 400 | if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) | ||
| 401 | cERROR(1, "Bad protocol string signature header %x", | ||
| 402 | *(unsigned int *) smb->Protocol); | ||
| 403 | if (mid != smb->Mid) | ||
| 404 | cERROR(1, "Mids do not match"); | ||
| 405 | } | 409 | } |
| 406 | cERROR(1, "bad smb detected. The Mid=%d", smb->Mid); | 410 | |
| 411 | /* if it's a response then accept */ | ||
| 412 | if (smb->Flags & SMBFLG_RESPONSE) | ||
| 413 | return 0; | ||
| 414 | |||
| 415 | /* only one valid case where server sends us request */ | ||
| 416 | if (smb->Command == SMB_COM_LOCKING_ANDX) | ||
| 417 | return 0; | ||
| 418 | |||
| 419 | cERROR(1, "Server sent request, not response. mid=%u", smb->Mid); | ||
| 407 | return 1; | 420 | return 1; |
| 408 | } | 421 | } |
| 409 | 422 | ||
| @@ -448,7 +461,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) | |||
| 448 | return 1; | 461 | return 1; |
| 449 | } | 462 | } |
| 450 | 463 | ||
| 451 | if (checkSMBhdr(smb, mid)) | 464 | if (check_smb_hdr(smb, mid)) |
| 452 | return 1; | 465 | return 1; |
| 453 | clc_len = smbCalcSize_LE(smb); | 466 | clc_len = smbCalcSize_LE(smb); |
| 454 | 467 | ||
| @@ -465,25 +478,26 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) | |||
| 465 | if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) | 478 | if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) |
| 466 | return 0; /* bcc wrapped */ | 479 | return 0; /* bcc wrapped */ |
| 467 | } | 480 | } |
| 468 | cFYI(1, "Calculated size %d vs length %d mismatch for mid %d", | 481 | cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u", |
| 469 | clc_len, 4 + len, smb->Mid); | 482 | clc_len, 4 + len, smb->Mid); |
| 470 | /* Windows XP can return a few bytes too much, presumably | 483 | |
| 471 | an illegal pad, at the end of byte range lock responses | 484 | if (4 + len < clc_len) { |
| 472 | so we allow for that three byte pad, as long as actual | 485 | cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u", |
| 473 | received length is as long or longer than calculated length */ | ||
| 474 | /* We have now had to extend this more, since there is a | ||
| 475 | case in which it needs to be bigger still to handle a | ||
| 476 | malformed response to transact2 findfirst from WinXP when | ||
| 477 | access denied is returned and thus bcc and wct are zero | ||
| 478 | but server says length is 0x21 bytes too long as if the server | ||
| 479 | forget to reset the smb rfc1001 length when it reset the | ||
| 480 | wct and bcc to minimum size and drop the t2 parms and data */ | ||
| 481 | if ((4+len > clc_len) && (len <= clc_len + 512)) | ||
| 482 | return 0; | ||
| 483 | else { | ||
| 484 | cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d", | ||
| 485 | len, smb->Mid); | 486 | len, smb->Mid); |
| 486 | return 1; | 487 | return 1; |
| 488 | } else if (len > clc_len + 512) { | ||
| 489 | /* | ||
| 490 | * Some servers (Windows XP in particular) send more | ||
| 491 | * data than the lengths in the SMB packet would | ||
| 492 | * indicate on certain calls (byte range locks and | ||
| 493 | * trans2 find first calls in particular). While the | ||
| 494 | * client can handle such a frame by ignoring the | ||
| 495 | * trailing data, we choose limit the amount of extra | ||
| 496 | * data to 512 bytes. | ||
| 497 | */ | ||
| 498 | cERROR(1, "RFC1001 size %u more than 512 bytes larger " | ||
| 499 | "than SMB for mid=%u", len, smb->Mid); | ||
| 500 | return 1; | ||
| 487 | } | 501 | } |
| 488 | } | 502 | } |
| 489 | return 0; | 503 | return 0; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 7f25cc3d2256..f8e4cd2a7912 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -764,7 +764,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
| 764 | { | 764 | { |
| 765 | int rc = 0; | 765 | int rc = 0; |
| 766 | int xid, i; | 766 | int xid, i; |
| 767 | struct cifs_sb_info *cifs_sb; | ||
| 768 | struct cifsTconInfo *pTcon; | 767 | struct cifsTconInfo *pTcon; |
| 769 | struct cifsFileInfo *cifsFile = NULL; | 768 | struct cifsFileInfo *cifsFile = NULL; |
| 770 | char *current_entry; | 769 | char *current_entry; |
| @@ -775,8 +774,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
| 775 | 774 | ||
| 776 | xid = GetXid(); | 775 | xid = GetXid(); |
| 777 | 776 | ||
| 778 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
| 779 | |||
| 780 | /* | 777 | /* |
| 781 | * Ensure FindFirst doesn't fail before doing filldir() for '.' and | 778 | * Ensure FindFirst doesn't fail before doing filldir() for '.' and |
| 782 | * '..'. Otherwise we won't be able to notify VFS in case of failure. | 779 | * '..'. Otherwise we won't be able to notify VFS in case of failure. |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index b5450e9f40c0..b5041c849981 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
| @@ -58,8 +58,9 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) | |||
| 58 | 58 | ||
| 59 | md4 = crypto_alloc_shash("md4", 0, 0); | 59 | md4 = crypto_alloc_shash("md4", 0, 0); |
| 60 | if (IS_ERR(md4)) { | 60 | if (IS_ERR(md4)) { |
| 61 | rc = PTR_ERR(md4); | ||
| 61 | cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); | 62 | cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); |
| 62 | return PTR_ERR(md4); | 63 | return rc; |
| 63 | } | 64 | } |
| 64 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); | 65 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); |
| 65 | sdescmd4 = kmalloc(size, GFP_KERNEL); | 66 | sdescmd4 = kmalloc(size, GFP_KERNEL); |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index c1ccca1a933f..b8c5e2eb43d0 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -236,9 +236,9 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) | |||
| 236 | server->tcpStatus = CifsNeedReconnect; | 236 | server->tcpStatus = CifsNeedReconnect; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | if (rc < 0) { | 239 | if (rc < 0 && rc != -EINTR) |
| 240 | cERROR(1, "Error %d sending data on socket to server", rc); | 240 | cERROR(1, "Error %d sending data on socket to server", rc); |
| 241 | } else | 241 | else |
| 242 | rc = 0; | 242 | rc = 0; |
| 243 | 243 | ||
| 244 | /* Don't want to modify the buffer as a | 244 | /* Don't want to modify the buffer as a |
| @@ -570,17 +570,33 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 570 | #endif | 570 | #endif |
| 571 | 571 | ||
| 572 | mutex_unlock(&ses->server->srv_mutex); | 572 | mutex_unlock(&ses->server->srv_mutex); |
| 573 | cifs_small_buf_release(in_buf); | ||
| 574 | 573 | ||
| 575 | if (rc < 0) | 574 | if (rc < 0) { |
| 575 | cifs_small_buf_release(in_buf); | ||
| 576 | goto out; | 576 | goto out; |
| 577 | } | ||
| 577 | 578 | ||
| 578 | if (long_op == CIFS_ASYNC_OP) | 579 | if (long_op == CIFS_ASYNC_OP) { |
| 580 | cifs_small_buf_release(in_buf); | ||
| 579 | goto out; | 581 | goto out; |
| 582 | } | ||
| 580 | 583 | ||
| 581 | rc = wait_for_response(ses->server, midQ); | 584 | rc = wait_for_response(ses->server, midQ); |
| 582 | if (rc != 0) | 585 | if (rc != 0) { |
| 583 | goto out; | 586 | send_nt_cancel(ses->server, in_buf, midQ); |
| 587 | spin_lock(&GlobalMid_Lock); | ||
| 588 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
| 589 | midQ->callback = DeleteMidQEntry; | ||
| 590 | spin_unlock(&GlobalMid_Lock); | ||
| 591 | cifs_small_buf_release(in_buf); | ||
| 592 | atomic_dec(&ses->server->inFlight); | ||
| 593 | wake_up(&ses->server->request_q); | ||
| 594 | return rc; | ||
| 595 | } | ||
| 596 | spin_unlock(&GlobalMid_Lock); | ||
| 597 | } | ||
| 598 | |||
| 599 | cifs_small_buf_release(in_buf); | ||
| 584 | 600 | ||
| 585 | rc = sync_mid_result(midQ, ses->server); | 601 | rc = sync_mid_result(midQ, ses->server); |
| 586 | if (rc != 0) { | 602 | if (rc != 0) { |
| @@ -724,8 +740,19 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 724 | goto out; | 740 | goto out; |
| 725 | 741 | ||
| 726 | rc = wait_for_response(ses->server, midQ); | 742 | rc = wait_for_response(ses->server, midQ); |
| 727 | if (rc != 0) | 743 | if (rc != 0) { |
| 728 | goto out; | 744 | send_nt_cancel(ses->server, in_buf, midQ); |
| 745 | spin_lock(&GlobalMid_Lock); | ||
| 746 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
| 747 | /* no longer considered to be "in-flight" */ | ||
| 748 | midQ->callback = DeleteMidQEntry; | ||
| 749 | spin_unlock(&GlobalMid_Lock); | ||
| 750 | atomic_dec(&ses->server->inFlight); | ||
| 751 | wake_up(&ses->server->request_q); | ||
| 752 | return rc; | ||
| 753 | } | ||
| 754 | spin_unlock(&GlobalMid_Lock); | ||
| 755 | } | ||
| 729 | 756 | ||
| 730 | rc = sync_mid_result(midQ, ses->server); | 757 | rc = sync_mid_result(midQ, ses->server); |
| 731 | if (rc != 0) { | 758 | if (rc != 0) { |
| @@ -922,10 +949,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
| 922 | } | 949 | } |
| 923 | } | 950 | } |
| 924 | 951 | ||
| 925 | if (wait_for_response(ses->server, midQ) == 0) { | 952 | rc = wait_for_response(ses->server, midQ); |
| 926 | /* We got the response - restart system call. */ | 953 | if (rc) { |
| 927 | rstart = 1; | 954 | send_nt_cancel(ses->server, in_buf, midQ); |
| 955 | spin_lock(&GlobalMid_Lock); | ||
| 956 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
| 957 | /* no longer considered to be "in-flight" */ | ||
| 958 | midQ->callback = DeleteMidQEntry; | ||
| 959 | spin_unlock(&GlobalMid_Lock); | ||
| 960 | return rc; | ||
| 961 | } | ||
| 962 | spin_unlock(&GlobalMid_Lock); | ||
| 928 | } | 963 | } |
| 964 | |||
| 965 | /* We got the response - restart system call. */ | ||
| 966 | rstart = 1; | ||
| 929 | } | 967 | } |
| 930 | 968 | ||
| 931 | rc = sync_mid_result(midQ, ses->server); | 969 | rc = sync_mid_result(midQ, ses->server); |
