diff options
Diffstat (limited to 'fs/smb/client/cifsglob.h')
-rw-r--r-- | fs/smb/client/cifsglob.h | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index caeac04da97c..ee863b569734 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -106,6 +106,8 @@ #define CIFS_DFS_ROOT_SES(ses) ((ses)->dfs_root_ses ?: (ses)) +#define CIFS_MAX_CHANNELS 16 + /* * CIFS vfs client Status information (based on what we know.) */ @@ -621,6 +623,8 @@ struct TCP_Server_Info { struct socket *ssocket; struct sockaddr_storage dstaddr; struct sockaddr_storage srcaddr; /* locally bind to this IP */ + char *iface_names[CIFS_MAX_CHANNELS]; + int __iface_idx; /* do not use directly */ #ifdef CONFIG_NET_NS struct net *net; #endif @@ -757,6 +761,38 @@ struct TCP_Server_Info { char *origin_fullpath, *leaf_fullpath; }; +static inline char *smb_get_next_iface_name_rr(struct TCP_Server_Info *server) +{ + struct TCP_Server_Info *pserver = server->primary_server ?: server; + int idx = pserver->__iface_idx; + bool wrap = true; + char *iface; + + /* no interface names set */ + if (idx == -1) + return NULL; + + if (!pserver->iface_names[0]) { + pserver->__iface_idx = -1; + return NULL; + } + +next_iface: + if ((iface = pserver->iface_names[++idx])) { + pserver->__iface_idx = idx; + return iface; + } else if (wrap || idx >= CIFS_MAX_CHANNELS - 1) { + wrap = false; + idx = 0; + goto next_iface; + } + + /* no more interfaces to check -- unlikely to reach */ + pserver->__iface_idx = -1; + + return NULL; +} + static inline bool is_smb1(struct TCP_Server_Info *server) { return HEADER_PREAMBLE_SIZE(server) != 0; @@ -1072,7 +1108,6 @@ struct cifs_ses { spinlock_t chan_lock; /* ========= begin: protected by chan_lock ======== */ -#define CIFS_MAX_CHANNELS 16 #define CIFS_ALL_CHANNELS_SET(ses) \ ((1UL << (ses)->chan_count) - 1) #define CIFS_ALL_CHANS_GOOD(ses) \ |