cifs: do not send tree disconnect to ipc shares
[linux-2.6-microblaze.git] / fs / cifs / connect.c
index 121d8b4..ecac8ca 100644 (file)
@@ -392,16 +392,6 @@ cifs_echo_request(struct work_struct *work)
        int rc;
        struct TCP_Server_Info *server = container_of(work,
                                        struct TCP_Server_Info, echo.work);
-       unsigned long echo_interval;
-
-       /*
-        * If we need to renegotiate, set echo interval to zero to
-        * immediately call echo service where we can renegotiate.
-        */
-       if (server->tcpStatus == CifsNeedNegotiate)
-               echo_interval = 0;
-       else
-               echo_interval = server->echo_interval;
 
        /*
         * We cannot send an echo if it is disabled.
@@ -412,7 +402,7 @@ cifs_echo_request(struct work_struct *work)
            server->tcpStatus == CifsExiting ||
            server->tcpStatus == CifsNew ||
            (server->ops->can_echo && !server->ops->can_echo(server)) ||
-           time_before(jiffies, server->lstrp + echo_interval - HZ))
+           time_before(jiffies, server->lstrp + server->echo_interval - HZ))
                goto requeue_echo;
 
        rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
@@ -476,6 +466,7 @@ server_unresponsive(struct TCP_Server_Info *server)
         */
        if ((server->tcpStatus == CifsGood ||
            server->tcpStatus == CifsNeedNegotiate) &&
+           (!server->ops->can_echo || server->ops->can_echo(server)) &&
            time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {
                cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n",
                         (3 * server->echo_interval) / HZ);
@@ -1566,29 +1557,25 @@ out:
 /**
  * cifs_free_ipc - helper to release the session IPC tcon
  *
- * Needs to be called everytime a session is destroyed
+ * Needs to be called everytime a session is destroyed.
+ *
+ * On session close, the IPC is closed and the server must release all tcons of the session.
+ * No need to send a tree disconnect here.
+ *
+ * Besides, it will make the server to not close durable and resilient files on session close, as
+ * specified in MS-SMB2 3.3.5.6 Receiving an SMB2 LOGOFF Request.
  */
 static int
 cifs_free_ipc(struct cifs_ses *ses)
 {
-       int rc = 0, xid;
        struct cifs_tcon *tcon = ses->tcon_ipc;
 
        if (tcon == NULL)
                return 0;
 
-       if (ses->server->ops->tree_disconnect) {
-               xid = get_xid();
-               rc = ses->server->ops->tree_disconnect(xid, tcon);
-               free_xid(xid);
-       }
-
-       if (rc)
-               cifs_dbg(FYI, "failed to disconnect IPC tcon (rc=%d)\n", rc);
-
        tconInfoFree(tcon);
        ses->tcon_ipc = NULL;
-       return rc;
+       return 0;
 }
 
 static struct cifs_ses *
@@ -3158,17 +3145,29 @@ out:
 int
 cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname)
 {
-       int rc = 0;
+       int rc;
 
-       smb3_parse_devname(devname, ctx);
+       if (devname) {
+               cifs_dbg(FYI, "%s: devname=%s\n", __func__, devname);
+               rc = smb3_parse_devname(devname, ctx);
+               if (rc) {
+                       cifs_dbg(VFS, "%s: failed to parse %s: %d\n", __func__, devname, rc);
+                       return rc;
+               }
+       }
 
        if (mntopts) {
                char *ip;
 
-               cifs_dbg(FYI, "%s: mntopts=%s\n", __func__, mntopts);
                rc = smb3_parse_opt(mntopts, "ip", &ip);
-               if (!rc && !cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip,
-                                                strlen(ip))) {
+               if (rc) {
+                       cifs_dbg(VFS, "%s: failed to parse ip options: %d\n", __func__, rc);
+                       return rc;
+               }
+
+               rc = cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip));
+               kfree(ip);
+               if (!rc) {
                        cifs_dbg(VFS, "%s: failed to convert ip address\n", __func__);
                        return -EINVAL;
                }
@@ -3188,7 +3187,7 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const c
                return -EINVAL;
        }
 
-       return rc;
+       return 0;
 }
 
 static int