Skip to content

Commit 8abcaea

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: always iterate smb sessions using primary channel
smb sessions and tcons currently hang off primary channel only. Secondary channels have the lists as empty. Whenever there's a need to iterate sessions or tcons, we should use the list in the corresponding primary channel. Signed-off-by: Shyam Prasad N <[email protected]> Reviewed-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 30a0b95 commit 8abcaea

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

fs/cifs/misc.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
400400
{
401401
struct smb_hdr *buf = (struct smb_hdr *)buffer;
402402
struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
403+
struct TCP_Server_Info *pserver;
403404
struct cifs_ses *ses;
404405
struct cifs_tcon *tcon;
405406
struct cifsInodeInfo *pCifsInode;
@@ -464,9 +465,12 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
464465
if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
465466
return false;
466467

468+
/* If server is a channel, select the primary channel */
469+
pserver = CIFS_SERVER_IS_CHAN(srv) ? srv->primary_server : srv;
470+
467471
/* look up tcon based on tid & uid */
468472
spin_lock(&cifs_tcp_ses_lock);
469-
list_for_each_entry(ses, &srv->smb_ses_list, smb_ses_list) {
473+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
470474
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
471475
if (tcon->tid != buf->Tid)
472476
continue;

fs/cifs/smb2misc.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
135135
int
136136
smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
137137
{
138+
struct TCP_Server_Info *pserver;
138139
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
139140
struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
140141
int hdr_size = sizeof(struct smb2_hdr);
@@ -143,6 +144,9 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
143144
__u32 calc_len; /* calculated length */
144145
__u64 mid;
145146

147+
/* If server is a channel, select the primary channel */
148+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
149+
146150
/*
147151
* Add function to do table lookup of StructureSize by command
148152
* ie Validate the wct via smb2_struct_sizes table above
@@ -155,7 +159,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
155159

156160
/* decrypt frame now that it is completely read in */
157161
spin_lock(&cifs_tcp_ses_lock);
158-
list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
162+
list_for_each_entry(iter, &pserver->smb_ses_list, smb_ses_list) {
159163
if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
160164
ses = iter;
161165
break;
@@ -671,6 +675,7 @@ bool
671675
smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
672676
{
673677
struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
678+
struct TCP_Server_Info *pserver;
674679
struct cifs_ses *ses;
675680
struct cifs_tcon *tcon;
676681
struct cifsInodeInfo *cinode;
@@ -691,9 +696,12 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
691696

692697
cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
693698

699+
/* If server is a channel, select the primary channel */
700+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
701+
694702
/* look up tcon based on tid & uid */
695703
spin_lock(&cifs_tcp_ses_lock);
696-
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
704+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
697705
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
698706

699707
spin_lock(&tcon->open_file_lock);

fs/cifs/smb2ops.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2302,14 +2302,18 @@ static void
23022302
smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
23032303
{
23042304
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
2305+
struct TCP_Server_Info *pserver;
23052306
struct cifs_ses *ses;
23062307
struct cifs_tcon *tcon;
23072308

23082309
if (shdr->Status != STATUS_NETWORK_NAME_DELETED)
23092310
return;
23102311

2312+
/* If server is a channel, select the primary channel */
2313+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
2314+
23112315
spin_lock(&cifs_tcp_ses_lock);
2312-
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
2316+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
23132317
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
23142318
if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) {
23152319
spin_lock(&tcon->tc_lock);

fs/cifs/smb2transport.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,13 @@ int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
136136
static struct cifs_ses *
137137
smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
138138
{
139+
struct TCP_Server_Info *pserver;
139140
struct cifs_ses *ses;
140141

141-
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
142+
/* If server is a channel, select the primary channel */
143+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
144+
145+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
142146
if (ses->Suid != ses_id)
143147
continue;
144148
++ses->ses_count;

0 commit comments

Comments
 (0)