smb: client: get rid of TCP_Server_Info::refpath_lock

TCP_Server_Info::leaf_fullpath is allocated in cifs_get_tcp_session()
and never changed afterwards, so there is no need to serialize its
access.

Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Paulo Alcantara
2025-01-17 17:38:56 -03:00
committed by Steve French
parent 2948f0d4db
commit 0a9b00e5e5
3 changed files with 7 additions and 30 deletions

View File

@@ -811,18 +811,9 @@ struct TCP_Server_Info {
bool use_swn_dstaddr;
struct sockaddr_storage swn_dstaddr;
#endif
struct mutex refpath_lock; /* protects leaf_fullpath */
/*
* leaf_fullpath: Canonical DFS referral path related to this
* connection.
* It is used in DFS cache refresher, reconnect and may
* change due to nested DFS links.
*
* Protected by @refpath_lock and @srv_lock. The @refpath_lock is
* mostly used for not requiring a copy of @leaf_fullpath when getting
* cached or new DFS referrals (which might also sleep during I/O).
* While @srv_lock is held for making string and NULL comparisons against
* both fields as in mount(2) and cache refresh.
* Canonical DFS referral path used in cifs_reconnect() for failover as
* well as in DFS cache refresher.
*
* format: \\HOST\SHARE[\OPTIONAL PATH]
*/

View File

@@ -492,7 +492,7 @@ static int reconnect_target_locked(struct TCP_Server_Info *server,
static int reconnect_dfs_server(struct TCP_Server_Info *server)
{
struct dfs_cache_tgt_iterator *target_hint = NULL;
const char *ref_path = server->leaf_fullpath + 1;
DFS_CACHE_TGT_LIST(tl);
int num_targets = 0;
int rc = 0;
@@ -505,10 +505,8 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
* through /proc/fs/cifs/dfscache or the target list is empty due to server settings after
* refreshing the referral, so, in this case, default it to 1.
*/
mutex_lock(&server->refpath_lock);
if (!dfs_cache_noreq_find(server->leaf_fullpath + 1, NULL, &tl))
if (!dfs_cache_noreq_find(ref_path, NULL, &tl))
num_targets = dfs_cache_get_nr_tgts(&tl);
mutex_unlock(&server->refpath_lock);
if (!num_targets)
num_targets = 1;
@@ -552,9 +550,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
} while (server->tcpStatus == CifsNeedReconnect);
mutex_lock(&server->refpath_lock);
dfs_cache_noreq_update_tgthint(server->leaf_fullpath + 1, target_hint);
mutex_unlock(&server->refpath_lock);
dfs_cache_noreq_update_tgthint(ref_path, target_hint);
dfs_cache_free_tgts(&tl);
/* Need to set up echo worker again once connection has been established */
@@ -569,13 +565,8 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)
{
mutex_lock(&server->refpath_lock);
if (!server->leaf_fullpath) {
mutex_unlock(&server->refpath_lock);
if (!server->leaf_fullpath)
return __cifs_reconnect(server, mark_smb_session);
}
mutex_unlock(&server->refpath_lock);
return reconnect_dfs_server(server);
}
#else
@@ -1754,9 +1745,6 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
mutex_init(&tcp_ses->reconnect_mutex);
#ifdef CONFIG_CIFS_DFS_UPCALL
mutex_init(&tcp_ses->refpath_lock);
#endif
memcpy(&tcp_ses->srcaddr, &ctx->srcaddr,
sizeof(tcp_ses->srcaddr));
memcpy(&tcp_ses->dstaddr, &ctx->dstaddr,

View File

@@ -1141,13 +1141,11 @@ static char *get_ses_refpath(struct cifs_ses *ses)
struct TCP_Server_Info *server = ses->server;
char *path = ERR_PTR(-ENOENT);
mutex_lock(&server->refpath_lock);
if (server->leaf_fullpath) {
path = kstrdup(server->leaf_fullpath + 1, GFP_ATOMIC);
path = kstrdup(server->leaf_fullpath + 1, GFP_KERNEL);
if (!path)
path = ERR_PTR(-ENOMEM);
}
mutex_unlock(&server->refpath_lock);
return path;
}