[CIFS] Do not time out posix brl requests when using new posix setfileinfo
authorSteve French <sfrench@us.ibm.com>
Fri, 14 Jul 2006 22:37:11 +0000 (22:37 +0000)
committerSteve French <sfrench@us.ibm.com>
Fri, 11 Aug 2006 21:27:07 +0000 (21:27 +0000)
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)

fs/cifs/CHANGES
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/transport.c

index a61d17ed1827e3552a6808a8f705fdd2281d7fe4..acb843b9bc3b7aca67cbc3343190ff16cf50f235 100644 (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
index c28ede599946842568356378cec5ed3eaff3f139..3cd750029be29e3dadf30f41514f4698039a647d 100644 (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,
 };
 
index 8f75c6f24701ff4e5a63f99cccb3b316830204bc..39ee8ef3bdeb01a63eba58d56611cee6211c7c40 100644 (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 */
index 6d7cf5f3bc0bdb3549b7e038fdd099ada89bee3c..39b43e6a7509d0610613d4da20724ebae8f2ce74 100644 (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 */
 };
 
 /*
index 19678c575dfc4bcc786d158a20f56a450caccec1..c03c42ee9eb9e549dea7668c54318cc2ddbf7cb3 100644 (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) {
index 876eb9ef85fecd83ae57042b2114cdd3b8355e00..c4aedcf5c92415d85aa5e4f1cddb757a6e6a4ea5 100644 (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"));
                                }
index 944d2b9e092d27262e6ec669ff792bdb8a4e0df4..52e2e4c8794b752dca6bec6809aced17a0ddfd73 100644 (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;
index 17ba329e2b3de5cbf02b973cf0b3a04515736b43..95e23ca670a8002ab3656cbc46423051d05ffbf2 100644 (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 {