[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)
This commit is contained in:
Steve French 2006-07-14 22:37:11 +00:00
parent 9f737633e6
commit 3a5ff61c18
8 changed files with 49 additions and 18 deletions

View File

@ -1,3 +1,9 @@
Version 1.45
------------
Do not time out lockw calls when using posix extensions. Do not
time out requests if server still responding reasonably fast
on requests on other threads
Version 1.44
------------
Rewritten sessionsetup support, including support for legacy SMB

View File

@ -402,7 +402,6 @@ static struct quotactl_ops cifs_quotactl_ops = {
};
#endif
#ifdef CONFIG_CIFS_EXPERIMENTAL
static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
{
struct cifs_sb_info *cifs_sb;
@ -422,7 +421,7 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
tcon->tidStatus = CifsExiting;
up(&tcon->tconSem);
/* cancel_brl_requests(tcon); */
/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
/* cancel_notify_requests(tcon); */
if(tcon->ses && tcon->ses->server)
{
@ -438,7 +437,6 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
return;
}
#endif
static int cifs_remount(struct super_block *sb, int *flags, char *data)
{
@ -457,9 +455,7 @@ struct super_operations cifs_super_ops = {
unless later we add lazy close of inodes or unless the kernel forgets to call
us with the same number of releases (closes) as opens */
.show_options = cifs_show_options,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.umount_begin = cifs_umount_begin,
#endif
.remount_fs = cifs_remount,
};

View File

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

View File

@ -158,7 +158,8 @@ struct TCP_Server_Info {
/* 16th byte of RFC1001 workstation name is always null */
char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
__u32 sequence_number; /* needed for CIFS PDU signature */
char mac_signing_key[CIFS_SESS_KEY_SIZE + 16];
char mac_signing_key[CIFS_SESS_KEY_SIZE + 16];
unsigned long lstrp; /* when we got last response from this server */
};
/*

View File

@ -1484,6 +1484,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
char *data_offset;
struct cifs_posix_lock *parm_data;
int rc = 0;
int timeout = 0;
int bytes_returned = 0;
__u16 params, param_offset, offset, byte_count, count;
@ -1503,7 +1504,6 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
offset = param_offset + params;
@ -1529,8 +1529,13 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
(((char *) &pSMB->hdr.Protocol) + offset);
parm_data->lock_type = cpu_to_le16(lock_type);
if(waitFlag)
if(waitFlag) {
timeout = 3; /* blocking operation, no timeout */
parm_data->lock_flags = cpu_to_le16(1);
pSMB->Timeout = cpu_to_le32(-1);
} else
pSMB->Timeout = 0;
parm_data->pid = cpu_to_le32(current->tgid);
parm_data->start = cpu_to_le64(pLockData->fl_start);
parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
@ -1542,7 +1547,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
pSMB->hdr.smb_buf_length += byte_count;
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
(struct smb_hdr *) pSMBr, &bytes_returned, timeout);
if (rc) {
cFYI(1, ("Send error in Posix Lock = %d", rc));
} else if (get_flag) {

View File

@ -612,6 +612,10 @@ multi_t2_fnd:
#ifdef CONFIG_CIFS_STATS2
mid_entry->when_received = jiffies;
#endif
/* so we do not time out requests to server
which is still responding (since server could
be busy but not dead) */
server->lstrp = jiffies;
break;
}
}
@ -1969,7 +1973,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
}
cFYI(1,("Negotiate caps 0x%x",(int)cap));
#ifdef CONFIG_CIFS_DEBUG2
if(cap & CIFS_UNIX_FCNTL_CAP)
cFYI(1,("FCNTL cap"));
if(cap & CIFS_UNIX_EXTATTR_CAP)
cFYI(1,("EXTATTR cap"));
if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
cFYI(1,("POSIX path cap"));
if(cap & CIFS_UNIX_XATTR_CAP)
cFYI(1,("XATTR cap"));
if(cap & CIFS_UNIX_POSIX_ACL_CAP)
cFYI(1,("POSIX ACL cap"));
#endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
cFYI(1,("setting capabilities failed"));
}

View File

@ -644,8 +644,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
account for negative length which we can not accept over the
wire */
if (IS_GETLK(cmd)) {
if(experimEnabled &&
(cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
if((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_FCNTL_CAP &
le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
int posix_lock_type;
@ -683,8 +682,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
FreeXid(xid);
return rc;
}
if (experimEnabled &&
(cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_FCNTL_CAP &
le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
int posix_lock_type;

View File

@ -444,8 +444,9 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
if(timeout != MAX_SCHEDULE_TIMEOUT) {
timeout += jiffies;
wait_event(ses->server->response_q,
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
time_after(jiffies, timeout) ||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
(time_after(jiffies, timeout) &&
time_after(jiffies, ses->server->lstrp + HZ)) ||
((ses->server->tcpStatus != CifsGood) &&
(ses->server->tcpStatus != CifsNew)));
} else {
@ -710,9 +711,18 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
/* No user interrupts in wait - wreaks havoc with performance */
if(timeout != MAX_SCHEDULE_TIMEOUT) {
timeout += jiffies;
/* although we prefer not to time out if the server is still
responding - we will time out if the server takes
more than 15 (or 45 or 180) seconds to respond to this request
and has not responded to any request from other threads
on this client within a second (note that it is not worth
grabbing the GlobalMid_Lock and slowing things down in this
wait event to more accurately check the lstrsp field on some
arch since we are already in an error path that will retry */
wait_event(ses->server->response_q,
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
time_after(jiffies, timeout) ||
(time_after(jiffies, timeout) &&
time_after(jiffies, ses->server->lstrp + HZ)) ||
((ses->server->tcpStatus != CifsGood) &&
(ses->server->tcpStatus != CifsNew)));
} else {