]> git.ipfire.org Git - people/ms/linux.git/commitdiff
cifs: periodically query network interfaces from server
authorShyam Prasad N <sprasad@microsoft.com>
Mon, 6 Jun 2022 09:17:56 +0000 (09:17 +0000)
committerSteve French <stfrench@microsoft.com>
Thu, 23 Jun 2022 00:51:43 +0000 (19:51 -0500)
Currently, we only query the server for network interfaces
information at the time of mount, and never afterwards.
This can be a problem, especially for services like Azure,
where the IP address of the channel endpoints can change
over time.

With this change, we schedule a 600s polling of this info
from the server for each tree connect.

An alternative for periodic polling was to do this only at
the time of reconnect. But this could delay the reconnect
time slightly. Also, there are some challenges w.r.t how
we have cifs_reconnect implemented today.

Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/smb2ops.c

index 7fc2addc95a3e111ddd1200f0f5775c8cba150d6..a643c84ff1e93077e7b3d53989b4147a34cb7c2f 100644 (file)
@@ -80,6 +80,9 @@
 #define SMB_DNS_RESOLVE_INTERVAL_MIN     120
 #define SMB_DNS_RESOLVE_INTERVAL_DEFAULT 600
 
+/* smb multichannel query server interfaces interval in seconds */
+#define SMB_INTERFACE_POLL_INTERVAL    600
+
 /* maximum number of PDUs in one compound */
 #define MAX_COMPOUND 5
 
@@ -1255,6 +1258,7 @@ struct cifs_tcon {
 #ifdef CONFIG_CIFS_DFS_UPCALL
        struct list_head ulist; /* cache update list */
 #endif
+       struct delayed_work     query_interfaces; /* query interfaces workqueue job */
 };
 
 /*
index 00c4a8aa26497d5a1d2c33f660bcb11cec386ef7..d59aebefa71cd3a93e9495073728059e0cc0a7d9 100644 (file)
@@ -641,6 +641,8 @@ cifs_chan_is_iface_active(struct cifs_ses *ses,
                          struct TCP_Server_Info *server);
 int
 cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
+int
+SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon);
 
 void extract_unc_hostname(const char *unc, const char **h, size_t *len);
 int copy_path_name(char *dst, const char *src);
index d8aae257649fac30432bb34693fe4ac99e7e14bd..e666d2643edebb032b4a1285b05e1fd6f60dbdd0 100644 (file)
@@ -145,6 +145,25 @@ requeue_resolve:
        return rc;
 }
 
+static void smb2_query_server_interfaces(struct work_struct *work)
+{
+       int rc;
+       struct cifs_tcon *tcon = container_of(work,
+                                       struct cifs_tcon,
+                                       query_interfaces.work);
+
+       /*
+        * query server network interfaces, in case they change
+        */
+       rc = SMB3_request_interfaces(0, tcon);
+       if (rc) {
+               cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
+                               __func__, rc);
+       }
+
+       queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
+                          (SMB_INTERFACE_POLL_INTERVAL * HZ));
+}
 
 static void cifs_resolve_server(struct work_struct *work)
 {
@@ -2276,6 +2295,9 @@ cifs_put_tcon(struct cifs_tcon *tcon)
        list_del_init(&tcon->tcon_list);
        spin_unlock(&cifs_tcp_ses_lock);
 
+       /* cancel polling of interfaces */
+       cancel_delayed_work_sync(&tcon->query_interfaces);
+
        if (tcon->use_witness) {
                int rc;
 
@@ -2513,6 +2535,12 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
        tcon->local_lease = ctx->local_lease;
        INIT_LIST_HEAD(&tcon->pending_opens);
 
+       /* schedule query interfaces poll */
+       INIT_DELAYED_WORK(&tcon->query_interfaces,
+                         smb2_query_server_interfaces);
+       queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
+                          (SMB_INTERFACE_POLL_INTERVAL * HZ));
+
        spin_lock(&cifs_tcp_ses_lock);
        list_add(&tcon->tcon_list, &ses->tcon_list);
        spin_unlock(&cifs_tcp_ses_lock);
index db4ccf1d235e9a85a61dde5ac866fc3de0d4f901..8802995b2d3d634e0d4687115904f9f87fda82c8 100644 (file)
@@ -671,7 +671,7 @@ out:
        return rc;
 }
 
-static int
+int
 SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
 {
        int rc;