Skip to content

Commit 0f2b305

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: connect individual channel servers to primary channel server
Today, we don't have any way to get the smb session for any of the secondary channels. Introducing a pointer to the primary server from server struct of any secondary channel. The value will be NULL for the server of the primary channel. This will enable us to get the smb session for any channel. This will be needed for some of the changes that I'm planning to make soon. Signed-off-by: Shyam Prasad N <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 724244c commit 0f2b305

File tree

6 files changed

+36
-14
lines changed

6 files changed

+36
-14
lines changed

fs/cifs/cifs_debug.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
271271
c = 0;
272272
spin_lock(&cifs_tcp_ses_lock);
273273
list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
274-
if (server->is_channel)
274+
/* channel info will be printed as a part of sessions below */
275+
if (CIFS_SERVER_IS_CHAN(server))
275276
continue;
276277

277278
c++;

fs/cifs/cifsglob.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,15 @@ struct TCP_Server_Info {
690690
*/
691691
int nr_targets;
692692
bool noblockcnt; /* use non-blocking connect() */
693-
bool is_channel; /* if a session channel */
693+
694+
/*
695+
* If this is a session channel,
696+
* primary_server holds the ref-counted
697+
* pointer to primary channel connection for the session.
698+
*/
699+
#define CIFS_SERVER_IS_CHAN(server) (!!(server)->primary_server)
700+
struct TCP_Server_Info *primary_server;
701+
694702
#ifdef CONFIG_CIFS_SWN_UPCALL
695703
bool use_swn_dstaddr;
696704
struct sockaddr_storage swn_dstaddr;

fs/cifs/cifsproto.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,9 @@ extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
269269

270270
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
271271
const char *path);
272-
273-
extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx);
272+
extern struct TCP_Server_Info *
273+
cifs_get_tcp_session(struct smb3_fs_context *ctx,
274+
struct TCP_Server_Info *primary_server);
274275
extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
275276
int from_reconnect);
276277
extern void cifs_put_tcon(struct cifs_tcon *tcon);

fs/cifs/connect.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
173173
struct cifs_tcon *tcon;
174174
struct mid_q_entry *mid, *nmid;
175175
struct list_head retry_list;
176+
struct TCP_Server_Info *pserver;
176177

177178
server->maxBuf = 0;
178179
server->max_read = 0;
@@ -184,8 +185,12 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
184185
* are not used until reconnected.
185186
*/
186187
cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n", __func__);
188+
189+
/* If server is a channel, select the primary channel */
190+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
191+
187192
spin_lock(&cifs_tcp_ses_lock);
188-
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
193+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
189194
ses->need_reconnect = true;
190195
list_for_each_entry(tcon, &ses->tcon_list, tcon_list)
191196
tcon->need_reconnect = true;
@@ -1338,7 +1343,7 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx)
13381343
* Skip ses channels since they're only handled in lower layers
13391344
* (e.g. cifs_send_recv).
13401345
*/
1341-
if (server->is_channel || !match_server(server, ctx))
1346+
if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx))
13421347
continue;
13431348

13441349
++server->srv_count;
@@ -1369,6 +1374,10 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
13691374
list_del_init(&server->tcp_ses_list);
13701375
spin_unlock(&cifs_tcp_ses_lock);
13711376

1377+
/* For secondary channels, we pick up ref-count on the primary server */
1378+
if (CIFS_SERVER_IS_CHAN(server))
1379+
cifs_put_tcp_session(server->primary_server, from_reconnect);
1380+
13721381
cancel_delayed_work_sync(&server->echo);
13731382
cancel_delayed_work_sync(&server->resolve);
13741383

@@ -1401,7 +1410,8 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
14011410
}
14021411

14031412
struct TCP_Server_Info *
1404-
cifs_get_tcp_session(struct smb3_fs_context *ctx)
1413+
cifs_get_tcp_session(struct smb3_fs_context *ctx,
1414+
struct TCP_Server_Info *primary_server)
14051415
{
14061416
struct TCP_Server_Info *tcp_ses = NULL;
14071417
int rc;
@@ -1438,6 +1448,10 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
14381448
tcp_ses->in_flight = 0;
14391449
tcp_ses->max_in_flight = 0;
14401450
tcp_ses->credits = 1;
1451+
if (primary_server) {
1452+
++primary_server->srv_count;
1453+
tcp_ses->primary_server = primary_server;
1454+
}
14411455
init_waitqueue_head(&tcp_ses->response_q);
14421456
init_waitqueue_head(&tcp_ses->request_q);
14431457
INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
@@ -1559,6 +1573,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
15591573

15601574
out_err:
15611575
if (tcp_ses) {
1576+
if (CIFS_SERVER_IS_CHAN(tcp_ses))
1577+
cifs_put_tcp_session(tcp_ses->primary_server, false);
15621578
kfree(tcp_ses->hostname);
15631579
if (tcp_ses->ssocket)
15641580
sock_release(tcp_ses->ssocket);
@@ -2960,7 +2976,7 @@ static int mount_get_conns(struct mount_ctx *mnt_ctx)
29602976
xid = get_xid();
29612977

29622978
/* get a reference to a tcp session */
2963-
server = cifs_get_tcp_session(ctx);
2979+
server = cifs_get_tcp_session(ctx, NULL);
29642980
if (IS_ERR(server)) {
29652981
rc = PTR_ERR(server);
29662982
server = NULL;

fs/cifs/sess.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
258258
SMB2_CLIENT_GUID_SIZE);
259259
ctx.use_client_guid = true;
260260

261-
chan_server = cifs_get_tcp_session(&ctx);
261+
chan_server = cifs_get_tcp_session(&ctx, ses->server);
262262

263263
mutex_lock(&ses->session_mutex);
264264
spin_lock(&ses->chan_lock);
@@ -272,10 +272,6 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
272272
}
273273
spin_unlock(&ses->chan_lock);
274274

275-
spin_lock(&cifs_tcp_ses_lock);
276-
chan->server->is_channel = true;
277-
spin_unlock(&cifs_tcp_ses_lock);
278-
279275
/*
280276
* We need to allocate the server crypto now as we will need
281277
* to sign packets before we generate the channel signing key

fs/cifs/smb2pdu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
257257
/*
258258
* If we are reconnecting an extra channel, bind
259259
*/
260-
if (server->is_channel) {
260+
if (CIFS_SERVER_IS_CHAN(server)) {
261261
ses->binding = true;
262262
ses->binding_chan = cifs_ses_find_chan(ses, server);
263263
}

0 commit comments

Comments
 (0)