diff options
| author | Paulo Alcantara <pc@manguebit.org> | 2025-12-04 15:06:23 -0300 |
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2025-12-05 17:40:33 -0600 |
| commit | 855982a52ff7d188188f0ecf86c2ce95957202c6 (patch) | |
| tree | 62e0171cb5c5892abee05edfcb42eff211df3408 /fs/smb/client/cifsglob.h | |
| parent | 4ae4dde6f34a4124c65468ae4fa1f915fb40f900 (diff) | |
smb: client: relax session and tcon reconnect attempts
When the client re-establishes connection to the server, it will queue
a worker thread that will attempt to reconnect sessions and tcons on
every two seconds, which is kinda overkill as it is a very common
scenario when having expired passwords or KRB5 TGT tickets, or deleted
shares.
Use an exponential backoff strategy to handle session/tcon reconnect
attempts in the worker thread to prevent the client from overloading
the system when it is very unlikely to re-establish any session/tcon
soon while client is idle.
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Reviewed-by: David Howells <dhowells@redhat.com>
Cc: Pierguido Lambri <plambri@redhat.com>
Cc: linux-cifs@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb/client/cifsglob.h')
| -rw-r--r-- | fs/smb/client/cifsglob.h | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index f9c1f553ffd0..3eca5bfb7030 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -745,6 +745,7 @@ struct TCP_Server_Info { struct session_key session_key; unsigned long lstrp; /* when we got last response from this server */ unsigned long neg_start; /* when negotiate started (jiffies) */ + unsigned long reconn_delay; /* when resched session and tcon reconnect */ struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ #define CIFS_NEGFLAVOR_UNENCAP 1 /* wct == 17, but no ext_sec */ #define CIFS_NEGFLAVOR_EXTENDED 2 /* wct == 17, ext_sec bit set */ @@ -2292,4 +2293,24 @@ struct cifs_calc_sig_ctx { struct shash_desc *shash; }; +#define CIFS_RECONN_DELAY_SECS 30 +#define CIFS_MAX_RECONN_DELAY (4 * CIFS_RECONN_DELAY_SECS) + +static inline void cifs_queue_server_reconn(struct TCP_Server_Info *server) +{ + if (!delayed_work_pending(&server->reconnect)) { + WRITE_ONCE(server->reconn_delay, 0); + mod_delayed_work(cifsiod_wq, &server->reconnect, 0); + } +} + +static inline void cifs_requeue_server_reconn(struct TCP_Server_Info *server) +{ + unsigned long delay = READ_ONCE(server->reconn_delay); + + delay = umin(delay + CIFS_RECONN_DELAY_SECS, CIFS_MAX_RECONN_DELAY); + WRITE_ONCE(server->reconn_delay, delay); + queue_delayed_work(cifsiod_wq, &server->reconnect, delay * HZ); +} + #endif /* _CIFS_GLOB_H */ |
