forked from Minki/linux
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 <sprasad@microsoft.com> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
30a0b95b13
commit
8abcaeaed3
@ -400,6 +400,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
|
||||
{
|
||||
struct smb_hdr *buf = (struct smb_hdr *)buffer;
|
||||
struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
|
||||
struct TCP_Server_Info *pserver;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsInodeInfo *pCifsInode;
|
||||
@ -464,9 +465,12 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
|
||||
if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
|
||||
return false;
|
||||
|
||||
/* If server is a channel, select the primary channel */
|
||||
pserver = CIFS_SERVER_IS_CHAN(srv) ? srv->primary_server : srv;
|
||||
|
||||
/* look up tcon based on tid & uid */
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each_entry(ses, &srv->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
||||
if (tcon->tid != buf->Tid)
|
||||
continue;
|
||||
|
@ -135,6 +135,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
|
||||
int
|
||||
smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
|
||||
{
|
||||
struct TCP_Server_Info *pserver;
|
||||
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
|
||||
struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
|
||||
int hdr_size = sizeof(struct smb2_hdr);
|
||||
@ -143,6 +144,9 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
|
||||
__u32 calc_len; /* calculated length */
|
||||
__u64 mid;
|
||||
|
||||
/* If server is a channel, select the primary channel */
|
||||
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
|
||||
|
||||
/*
|
||||
* Add function to do table lookup of StructureSize by command
|
||||
* 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)
|
||||
|
||||
/* decrypt frame now that it is completely read in */
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(iter, &pserver->smb_ses_list, smb_ses_list) {
|
||||
if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
|
||||
ses = iter;
|
||||
break;
|
||||
@ -671,6 +675,7 @@ bool
|
||||
smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
|
||||
{
|
||||
struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
|
||||
struct TCP_Server_Info *pserver;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsInodeInfo *cinode;
|
||||
@ -691,9 +696,12 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
|
||||
|
||||
cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
|
||||
|
||||
/* If server is a channel, select the primary channel */
|
||||
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
|
||||
|
||||
/* look up tcon based on tid & uid */
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
||||
|
||||
spin_lock(&tcon->open_file_lock);
|
||||
|
@ -2302,14 +2302,18 @@ static void
|
||||
smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
|
||||
{
|
||||
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
|
||||
struct TCP_Server_Info *pserver;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
if (shdr->Status != STATUS_NETWORK_NAME_DELETED)
|
||||
return;
|
||||
|
||||
/* If server is a channel, select the primary channel */
|
||||
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
|
||||
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
|
||||
if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) {
|
||||
spin_lock(&tcon->tc_lock);
|
||||
|
@ -136,9 +136,13 @@ out:
|
||||
static struct cifs_ses *
|
||||
smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
|
||||
{
|
||||
struct TCP_Server_Info *pserver;
|
||||
struct cifs_ses *ses;
|
||||
|
||||
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
|
||||
/* If server is a channel, select the primary channel */
|
||||
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
|
||||
|
||||
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
|
||||
if (ses->Suid != ses_id)
|
||||
continue;
|
||||
++ses->ses_count;
|
||||
|
Loading…
Reference in New Issue
Block a user