Skip to content

Commit

Permalink
[CIFS] Do not time out posix brl requests when using new posix setfil…
Browse files Browse the repository at this point in the history
…einfo

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)
  • Loading branch information
Steve French committed Aug 11, 2006
1 parent 9f73763 commit 3a5ff61
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 18 deletions.
6 changes: 6 additions & 0 deletions fs/cifs/CHANGES
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 1 addition & 5 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -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,
};

Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
3 changes: 2 additions & 1 deletion fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};

/*
Expand Down
11 changes: 8 additions & 3 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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 */
Expand All @@ -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) {
Expand Down
17 changes: 16 additions & 1 deletion fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
#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;
}
}
Expand Down Expand Up @@ -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"));
}
Expand Down
6 changes: 2 additions & 4 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
16 changes: 13 additions & 3 deletions fs/cifs/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 3a5ff61

Please sign in to comment.