mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
cifs: periodically query network interfaces from server
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>
This commit is contained in:
parent
b54034a73b
commit
6e1c1c08cd
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -671,7 +671,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
{
|
||||
int rc;
|
||||
|
Loading…
Reference in New Issue
Block a user