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