diff options
Diffstat (limited to 'fs/cifs/misc.c')
| -rw-r--r-- | fs/cifs/misc.c | 90 |
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 | |||
| 497 | is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | 488 | is_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 | } |
