@@ -78,6 +78,8 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
7878 int rc ;
7979 int len ;
8080 char * unc , * ipaddr = NULL ;
81+ time64_t expiry , now ;
82+ unsigned long ttl = SMB_DNS_RESOLVE_INTERVAL_DEFAULT ;
8183
8284 if (!server -> hostname )
8385 return - EINVAL ;
@@ -91,13 +93,13 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
9193 }
9294 scnprintf (unc , len , "\\\\%s" , server -> hostname );
9395
94- rc = dns_resolve_server_name_to_ip (unc , & ipaddr );
96+ rc = dns_resolve_server_name_to_ip (unc , & ipaddr , & expiry );
9597 kfree (unc );
9698
9799 if (rc < 0 ) {
98100 cifs_dbg (FYI , "%s: failed to resolve server part of %s to IP: %d\n" ,
99101 __func__ , server -> hostname , rc );
100- return rc ;
102+ goto requeue_resolve ;
101103 }
102104
103105 spin_lock (& cifs_tcp_ses_lock );
@@ -106,7 +108,45 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
106108 spin_unlock (& cifs_tcp_ses_lock );
107109 kfree (ipaddr );
108110
109- return !rc ? -1 : 0 ;
111+ /* rc == 1 means success here */
112+ if (rc ) {
113+ now = ktime_get_real_seconds ();
114+ if (expiry && expiry > now )
115+ /*
116+ * To make sure we don't use the cached entry, retry 1s
117+ * after expiry.
118+ */
119+ ttl = (expiry - now + 1 );
120+ }
121+ rc = !rc ? -1 : 0 ;
122+
123+ requeue_resolve :
124+ cifs_dbg (FYI , "%s: next dns resolution scheduled for %lu seconds in the future\n" ,
125+ __func__ , ttl );
126+ mod_delayed_work (cifsiod_wq , & server -> resolve , (ttl * HZ ));
127+
128+ return rc ;
129+ }
130+
131+
132+ static void cifs_resolve_server (struct work_struct * work )
133+ {
134+ int rc ;
135+ struct TCP_Server_Info * server = container_of (work ,
136+ struct TCP_Server_Info , resolve .work );
137+
138+ mutex_lock (& server -> srv_mutex );
139+
140+ /*
141+ * Resolve the hostname again to make sure that IP address is up-to-date.
142+ */
143+ rc = reconn_set_ipaddr_from_hostname (server );
144+ if (rc ) {
145+ cifs_dbg (FYI , "%s: failed to resolve hostname: %d\n" ,
146+ __func__ , rc );
147+ }
148+
149+ mutex_unlock (& server -> srv_mutex );
110150}
111151
112152#ifdef CONFIG_CIFS_DFS_UPCALL
@@ -680,6 +720,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
680720 spin_unlock (& cifs_tcp_ses_lock );
681721
682722 cancel_delayed_work_sync (& server -> echo );
723+ cancel_delayed_work_sync (& server -> resolve );
683724
684725 spin_lock (& GlobalMid_Lock );
685726 server -> tcpStatus = CifsExiting ;
@@ -1260,6 +1301,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
12601301 spin_unlock (& cifs_tcp_ses_lock );
12611302
12621303 cancel_delayed_work_sync (& server -> echo );
1304+ cancel_delayed_work_sync (& server -> resolve );
12631305
12641306 if (from_reconnect )
12651307 /*
@@ -1342,6 +1384,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
13421384 INIT_LIST_HEAD (& tcp_ses -> tcp_ses_list );
13431385 INIT_LIST_HEAD (& tcp_ses -> smb_ses_list );
13441386 INIT_DELAYED_WORK (& tcp_ses -> echo , cifs_echo_request );
1387+ INIT_DELAYED_WORK (& tcp_ses -> resolve , cifs_resolve_server );
13451388 INIT_DELAYED_WORK (& tcp_ses -> reconnect , smb2_reconnect_server );
13461389 mutex_init (& tcp_ses -> reconnect_mutex );
13471390 memcpy (& tcp_ses -> srcaddr , & ctx -> srcaddr ,
@@ -1427,6 +1470,12 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
14271470 /* queue echo request delayed work */
14281471 queue_delayed_work (cifsiod_wq , & tcp_ses -> echo , tcp_ses -> echo_interval );
14291472
1473+ /* queue dns resolution delayed work */
1474+ cifs_dbg (FYI , "%s: next dns resolution scheduled for %d seconds in the future\n" ,
1475+ __func__ , SMB_DNS_RESOLVE_INTERVAL_DEFAULT );
1476+
1477+ queue_delayed_work (cifsiod_wq , & tcp_ses -> resolve , (SMB_DNS_RESOLVE_INTERVAL_DEFAULT * HZ ));
1478+
14301479 return tcp_ses ;
14311480
14321481out_err_crypto_release :
0 commit comments