[CIFS] Do not time out posix brl requests when using new posix setfileinfo request and do not time out slow requests to a server that is still responding well to other threads

Suggested by jra of Samba team

Signed-off-by: Steve French <sfrench@us.ibm.com>
(cherry picked from 89b57148115479eef074b8d3f86c4c86c96ac969 commit)

+49 -18
+6
fs/cifs/CHANGES
··· 1 + Version 1.45 2 + ------------ 3 + Do not time out lockw calls when using posix extensions. Do not 4 + time out requests if server still responding reasonably fast 5 + on requests on other threads 6 + 1 7 Version 1.44 2 8 ------------ 3 9 Rewritten sessionsetup support, including support for legacy SMB
+1 -5
fs/cifs/cifsfs.c
··· 402 402 }; 403 403 #endif 404 404 405 - #ifdef CONFIG_CIFS_EXPERIMENTAL 406 405 static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) 407 406 { 408 407 struct cifs_sb_info *cifs_sb; ··· 421 422 tcon->tidStatus = CifsExiting; 422 423 up(&tcon->tconSem); 423 424 424 - /* cancel_brl_requests(tcon); */ 425 + /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ 425 426 /* cancel_notify_requests(tcon); */ 426 427 if(tcon->ses && tcon->ses->server) 427 428 { ··· 437 438 438 439 return; 439 440 } 440 - #endif 441 441 442 442 static int cifs_remount(struct super_block *sb, int *flags, char *data) 443 443 { ··· 455 457 unless later we add lazy close of inodes or unless the kernel forgets to call 456 458 us with the same number of releases (closes) as opens */ 457 459 .show_options = cifs_show_options, 458 - #ifdef CONFIG_CIFS_EXPERIMENTAL 459 460 .umount_begin = cifs_umount_begin, 460 - #endif 461 461 .remount_fs = cifs_remount, 462 462 }; 463 463
+1 -1
fs/cifs/cifsfs.h
··· 100 100 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 101 101 extern int cifs_ioctl (struct inode * inode, struct file * filep, 102 102 unsigned int command, unsigned long arg); 103 - #define CIFS_VERSION "1.44" 103 + #define CIFS_VERSION "1.45" 104 104 #endif /* _CIFSFS_H */
+2 -1
fs/cifs/cifsglob.h
··· 158 158 /* 16th byte of RFC1001 workstation name is always null */ 159 159 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; 160 160 __u32 sequence_number; /* needed for CIFS PDU signature */ 161 - char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; 161 + char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; 162 + unsigned long lstrp; /* when we got last response from this server */ 162 163 }; 163 164 164 165 /*
+8 -3
fs/cifs/cifssmb.c
··· 1484 1484 char *data_offset; 1485 1485 struct cifs_posix_lock *parm_data; 1486 1486 int rc = 0; 1487 + int timeout = 0; 1487 1488 int bytes_returned = 0; 1488 1489 __u16 params, param_offset, offset, byte_count, count; 1489 1490 ··· 1504 1503 pSMB->MaxSetupCount = 0; 1505 1504 pSMB->Reserved = 0; 1506 1505 pSMB->Flags = 0; 1507 - pSMB->Timeout = 0; 1508 1506 pSMB->Reserved2 = 0; 1509 1507 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 1510 1508 offset = param_offset + params; ··· 1529 1529 (((char *) &pSMB->hdr.Protocol) + offset); 1530 1530 1531 1531 parm_data->lock_type = cpu_to_le16(lock_type); 1532 - if(waitFlag) 1532 + if(waitFlag) { 1533 + timeout = 3; /* blocking operation, no timeout */ 1533 1534 parm_data->lock_flags = cpu_to_le16(1); 1535 + pSMB->Timeout = cpu_to_le32(-1); 1536 + } else 1537 + pSMB->Timeout = 0; 1538 + 1534 1539 parm_data->pid = cpu_to_le32(current->tgid); 1535 1540 parm_data->start = cpu_to_le64(pLockData->fl_start); 1536 1541 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ ··· 1547 1542 pSMB->hdr.smb_buf_length += byte_count; 1548 1543 pSMB->ByteCount = cpu_to_le16(byte_count); 1549 1544 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1550 - (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1545 + (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1551 1546 if (rc) { 1552 1547 cFYI(1, ("Send error in Posix Lock = %d", rc)); 1553 1548 } else if (get_flag) {
+16 -1
fs/cifs/connect.c
··· 612 612 #ifdef CONFIG_CIFS_STATS2 613 613 mid_entry->when_received = jiffies; 614 614 #endif 615 + /* so we do not time out requests to server 616 + which is still responding (since server could 617 + be busy but not dead) */ 618 + server->lstrp = jiffies; 615 619 break; 616 620 } 617 621 } ··· 1973 1969 } 1974 1970 1975 1971 cFYI(1,("Negotiate caps 0x%x",(int)cap)); 1976 - 1972 + #ifdef CONFIG_CIFS_DEBUG2 1973 + if(cap & CIFS_UNIX_FCNTL_CAP) 1974 + cFYI(1,("FCNTL cap")); 1975 + if(cap & CIFS_UNIX_EXTATTR_CAP) 1976 + cFYI(1,("EXTATTR cap")); 1977 + if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 1978 + cFYI(1,("POSIX path cap")); 1979 + if(cap & CIFS_UNIX_XATTR_CAP) 1980 + cFYI(1,("XATTR cap")); 1981 + if(cap & CIFS_UNIX_POSIX_ACL_CAP) 1982 + cFYI(1,("POSIX ACL cap")); 1983 + #endif /* CIFS_DEBUG2 */ 1977 1984 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 1978 1985 cFYI(1,("setting capabilities failed")); 1979 1986 }
+2 -4
fs/cifs/file.c
··· 644 644 account for negative length which we can not accept over the 645 645 wire */ 646 646 if (IS_GETLK(cmd)) { 647 - if(experimEnabled && 648 - (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 647 + if((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 649 648 (CIFS_UNIX_FCNTL_CAP & 650 649 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) { 651 650 int posix_lock_type; ··· 682 683 FreeXid(xid); 683 684 return rc; 684 685 } 685 - if (experimEnabled && 686 - (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 686 + if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 687 687 (CIFS_UNIX_FCNTL_CAP & 688 688 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) { 689 689 int posix_lock_type;
+13 -3
fs/cifs/transport.c
··· 444 444 if(timeout != MAX_SCHEDULE_TIMEOUT) { 445 445 timeout += jiffies; 446 446 wait_event(ses->server->response_q, 447 - (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 448 - time_after(jiffies, timeout) || 447 + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 448 + (time_after(jiffies, timeout) && 449 + time_after(jiffies, ses->server->lstrp + HZ)) || 449 450 ((ses->server->tcpStatus != CifsGood) && 450 451 (ses->server->tcpStatus != CifsNew))); 451 452 } else { ··· 711 710 /* No user interrupts in wait - wreaks havoc with performance */ 712 711 if(timeout != MAX_SCHEDULE_TIMEOUT) { 713 712 timeout += jiffies; 713 + /* although we prefer not to time out if the server is still 714 + responding - we will time out if the server takes 715 + more than 15 (or 45 or 180) seconds to respond to this request 716 + and has not responded to any request from other threads 717 + on this client within a second (note that it is not worth 718 + grabbing the GlobalMid_Lock and slowing things down in this 719 + wait event to more accurately check the lstrsp field on some 720 + arch since we are already in an error path that will retry */ 714 721 wait_event(ses->server->response_q, 715 722 (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 716 - time_after(jiffies, timeout) || 723 + (time_after(jiffies, timeout) && 724 + time_after(jiffies, ses->server->lstrp + HZ)) || 717 725 ((ses->server->tcpStatus != CifsGood) && 718 726 (ses->server->tcpStatus != CifsNew))); 719 727 } else {