aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c90
1 files changed, 41 insertions, 49 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 88786ba02d27..addd1dcc2d79 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -75,12 +75,12 @@ sesInfoAlloc(void)
75 75
76 ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL); 76 ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
77 if (ret_buf) { 77 if (ret_buf) {
78 write_lock(&GlobalSMBSeslock);
79 atomic_inc(&sesInfoAllocCount); 78 atomic_inc(&sesInfoAllocCount);
80 ret_buf->status = CifsNew; 79 ret_buf->status = CifsNew;
81 list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList); 80 ++ret_buf->ses_count;
81 INIT_LIST_HEAD(&ret_buf->smb_ses_list);
82 INIT_LIST_HEAD(&ret_buf->tcon_list);
82 init_MUTEX(&ret_buf->sesSem); 83 init_MUTEX(&ret_buf->sesSem);
83 write_unlock(&GlobalSMBSeslock);
84 } 84 }
85 return ret_buf; 85 return ret_buf;
86} 86}
@@ -93,10 +93,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
93 return; 93 return;
94 } 94 }
95 95
96 write_lock(&GlobalSMBSeslock);
97 atomic_dec(&sesInfoAllocCount); 96 atomic_dec(&sesInfoAllocCount);
98 list_del(&buf_to_free->cifsSessionList);
99 write_unlock(&GlobalSMBSeslock);
100 kfree(buf_to_free->serverOS); 97 kfree(buf_to_free->serverOS);
101 kfree(buf_to_free->serverDomain); 98 kfree(buf_to_free->serverDomain);
102 kfree(buf_to_free->serverNOS); 99 kfree(buf_to_free->serverNOS);
@@ -111,17 +108,14 @@ tconInfoAlloc(void)
111 struct cifsTconInfo *ret_buf; 108 struct cifsTconInfo *ret_buf;
112 ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL); 109 ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
113 if (ret_buf) { 110 if (ret_buf) {
114 write_lock(&GlobalSMBSeslock);
115 atomic_inc(&tconInfoAllocCount); 111 atomic_inc(&tconInfoAllocCount);
116 list_add(&ret_buf->cifsConnectionList,
117 &GlobalTreeConnectionList);
118 ret_buf->tidStatus = CifsNew; 112 ret_buf->tidStatus = CifsNew;
113 ++ret_buf->tc_count;
119 INIT_LIST_HEAD(&ret_buf->openFileList); 114 INIT_LIST_HEAD(&ret_buf->openFileList);
120 init_MUTEX(&ret_buf->tconSem); 115 INIT_LIST_HEAD(&ret_buf->tcon_list);
121#ifdef CONFIG_CIFS_STATS 116#ifdef CONFIG_CIFS_STATS
122 spin_lock_init(&ret_buf->stat_lock); 117 spin_lock_init(&ret_buf->stat_lock);
123#endif 118#endif
124 write_unlock(&GlobalSMBSeslock);
125 } 119 }
126 return ret_buf; 120 return ret_buf;
127} 121}
@@ -133,10 +127,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
133 cFYI(1, ("Null buffer passed to tconInfoFree")); 127 cFYI(1, ("Null buffer passed to tconInfoFree"));
134 return; 128 return;
135 } 129 }
136 write_lock(&GlobalSMBSeslock);
137 atomic_dec(&tconInfoAllocCount); 130 atomic_dec(&tconInfoAllocCount);
138 list_del(&buf_to_free->cifsConnectionList);
139 write_unlock(&GlobalSMBSeslock);
140 kfree(buf_to_free->nativeFileSystem); 131 kfree(buf_to_free->nativeFileSystem);
141 kfree(buf_to_free); 132 kfree(buf_to_free);
142} 133}
@@ -350,9 +341,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
350 if (current->fsuid != treeCon->ses->linux_uid) { 341 if (current->fsuid != treeCon->ses->linux_uid) {
351 cFYI(1, ("Multiuser mode and UID " 342 cFYI(1, ("Multiuser mode and UID "
352 "did not match tcon uid")); 343 "did not match tcon uid"));
353 read_lock(&GlobalSMBSeslock); 344 read_lock(&cifs_tcp_ses_lock);
354 list_for_each(temp_item, &GlobalSMBSessionList) { 345 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
355 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); 346 ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
356 if (ses->linux_uid == current->fsuid) { 347 if (ses->linux_uid == current->fsuid) {
357 if (ses->server == treeCon->ses->server) { 348 if (ses->server == treeCon->ses->server) {
358 cFYI(1, ("found matching uid substitute right smb_uid")); 349 cFYI(1, ("found matching uid substitute right smb_uid"));
@@ -364,7 +355,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
364 } 355 }
365 } 356 }
366 } 357 }
367 read_unlock(&GlobalSMBSeslock); 358 read_unlock(&cifs_tcp_ses_lock);
368 } 359 }
369 } 360 }
370 } 361 }
@@ -497,9 +488,10 @@ bool
497is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) 488is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
498{ 489{
499 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf; 490 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
500 struct list_head *tmp; 491 struct list_head *tmp, *tmp1, *tmp2;
501 struct list_head *tmp1; 492 struct cifsSesInfo *ses;
502 struct cifsTconInfo *tcon; 493 struct cifsTconInfo *tcon;
494 struct cifsInodeInfo *pCifsInode;
503 struct cifsFileInfo *netfile; 495 struct cifsFileInfo *netfile;
504 496
505 cFYI(1, ("Checking for oplock break or dnotify response")); 497 cFYI(1, ("Checking for oplock break or dnotify response"));
@@ -554,42 +546,42 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
554 return false; 546 return false;
555 547
556 /* look up tcon based on tid & uid */ 548 /* look up tcon based on tid & uid */
557 read_lock(&GlobalSMBSeslock); 549 read_lock(&cifs_tcp_ses_lock);
558 list_for_each(tmp, &GlobalTreeConnectionList) { 550 list_for_each(tmp, &srv->smb_ses_list) {
559 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 551 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
560 if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) { 552 list_for_each(tmp1, &ses->tcon_list) {
553 tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
554 if (tcon->tid != buf->Tid)
555 continue;
556
561 cifs_stats_inc(&tcon->num_oplock_brks); 557 cifs_stats_inc(&tcon->num_oplock_brks);
562 list_for_each(tmp1, &tcon->openFileList) { 558 list_for_each(tmp2, &tcon->openFileList) {
563 netfile = list_entry(tmp1, struct cifsFileInfo, 559 netfile = list_entry(tmp2, struct cifsFileInfo,
564 tlist); 560 tlist);
565 if (pSMB->Fid == netfile->netfid) { 561 if (pSMB->Fid != netfile->netfid)
566 struct cifsInodeInfo *pCifsInode; 562 continue;
567 read_unlock(&GlobalSMBSeslock); 563
568 cFYI(1, 564 read_unlock(&cifs_tcp_ses_lock);
569 ("file id match, oplock break")); 565 cFYI(1, ("file id match, oplock break"));
570 pCifsInode = 566 pCifsInode = CIFS_I(netfile->pInode);
571 CIFS_I(netfile->pInode); 567 pCifsInode->clientCanCacheAll = false;
572 pCifsInode->clientCanCacheAll = false; 568 if (pSMB->OplockLevel == 0)
573 if (pSMB->OplockLevel == 0) 569 pCifsInode->clientCanCacheRead = false;
574 pCifsInode->clientCanCacheRead 570 pCifsInode->oplockPending = true;
575 = false; 571 AllocOplockQEntry(netfile->pInode,
576 pCifsInode->oplockPending = true; 572 netfile->netfid, tcon);
577 AllocOplockQEntry(netfile->pInode, 573 cFYI(1, ("about to wake up oplock thread"));
578 netfile->netfid, 574 if (oplockThread)
579 tcon); 575 wake_up_process(oplockThread);
580 cFYI(1, 576
581 ("about to wake up oplock thread")); 577 return true;
582 if (oplockThread)
583 wake_up_process(oplockThread);
584 return true;
585 }
586 } 578 }
587 read_unlock(&GlobalSMBSeslock); 579 read_unlock(&cifs_tcp_ses_lock);
588 cFYI(1, ("No matching file for oplock break")); 580 cFYI(1, ("No matching file for oplock break"));
589 return true; 581 return true;
590 } 582 }
591 } 583 }
592 read_unlock(&GlobalSMBSeslock); 584 read_unlock(&cifs_tcp_ses_lock);
593 cFYI(1, ("Can not process oplock break for non-existent connection")); 585 cFYI(1, ("Can not process oplock break for non-existent connection"));
594 return true; 586 return true;
595} 587}