Changeset 740 for vendor/current/source3/smbd/blocking.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/blocking.c
r427 r740 19 19 20 20 #include "includes.h" 21 #include "smbd/smbd.h" 21 22 #include "smbd/globals.h" 23 #include "messages.h" 22 24 23 25 #undef DBGC_CLASS … … 34 36 DATA_BLOB *data); 35 37 36 staticvoid brl_timeout_fn(struct event_context *event_ctx,38 void brl_timeout_fn(struct event_context *event_ctx, 37 39 struct timed_event *te, 38 40 struct timeval now, 39 41 void *private_data) 40 42 { 41 SMB_ASSERT(brl_timeout == te); 42 TALLOC_FREE(brl_timeout); 43 struct smbd_server_connection *sconn = talloc_get_type_abort( 44 private_data, struct smbd_server_connection); 45 46 if (sconn->using_smb2) { 47 SMB_ASSERT(sconn->smb2.locks.brl_timeout == te); 48 TALLOC_FREE(sconn->smb2.locks.brl_timeout); 49 } else { 50 SMB_ASSERT(sconn->smb1.locks.brl_timeout == te); 51 TALLOC_FREE(sconn->smb1.locks.brl_timeout); 52 } 43 53 44 54 change_to_root_user(); /* TODO: Possibly run all timed events as 45 55 * root */ 46 56 47 process_blocking_lock_queue( );57 process_blocking_lock_queue(sconn); 48 58 } 49 59 … … 52 62 ****************************************************************************/ 53 63 54 st atic struct timeval timeval_brl_min(const struct timeval *tv1,64 struct timeval timeval_brl_min(const struct timeval *tv1, 55 65 const struct timeval *tv2) 56 66 { … … 69 79 ****************************************************************************/ 70 80 71 static bool recalc_brl_timeout( void)81 static bool recalc_brl_timeout(struct smbd_server_connection *sconn) 72 82 { 73 83 struct blocking_lock_record *blr; … … 75 85 int max_brl_timeout = lp_parm_int(-1, "brl", "recalctime", 5); 76 86 77 TALLOC_FREE( brl_timeout);78 79 next_timeout = timeval_zero(); 80 81 for (blr = blocking_lock_queue; blr; blr = blr->next) {87 TALLOC_FREE(sconn->smb1.locks.brl_timeout); 88 89 next_timeout = timeval_zero(); 90 91 for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) { 82 92 if (timeval_is_zero(&blr->expire_time)) { 83 93 /* 84 * If we're blocked on pid 0xFFFFFFFF this is94 * If we're blocked on pid 0xFFFFFFFFFFFFFFFFLL this is 85 95 * a POSIX lock, so calculate a timeout of 86 96 * 10 seconds into the future. 87 97 */ 88 if (blr->blocking_ pid == 0xFFFFFFFF) {98 if (blr->blocking_smblctx == 0xFFFFFFFFFFFFFFFFLL) { 89 99 struct timeval psx_to = timeval_current_ofs(10, 0); 90 100 next_timeout = timeval_brl_min(&next_timeout, &psx_to); … … 118 128 if (max_brl_timeout > 0) { 119 129 struct timeval min_to = timeval_current_ofs(max_brl_timeout, 0); 120 next_timeout = timeval_min(&next_timeout, &min_to); 130 next_timeout = timeval_min(&next_timeout, &min_to); 121 131 } 122 132 … … 130 140 } 131 141 132 if (!(brl_timeout = event_add_timed(smbd_event_context(), NULL, 133 next_timeout, 134 brl_timeout_fn, NULL))) { 142 sconn->smb1.locks.brl_timeout = event_add_timed(smbd_event_context(), 143 NULL, next_timeout, 144 brl_timeout_fn, sconn); 145 if (sconn->smb1.locks.brl_timeout == NULL) { 135 146 return False; 136 147 } … … 149 160 int lock_timeout, 150 161 int lock_num, 151 uint 32_t lock_pid,162 uint64_t smblctx, 152 163 enum brl_type lock_type, 153 164 enum brl_flavour lock_flav, 154 165 uint64_t offset, 155 166 uint64_t count, 156 uint32_t blocking_pid) 157 { 167 uint64_t blocking_smblctx) 168 { 169 struct smbd_server_connection *sconn = req->sconn; 158 170 struct blocking_lock_record *blr; 159 171 NTSTATUS status; 172 173 if (req->smb2req) { 174 return push_blocking_lock_request_smb2(br_lck, 175 req, 176 fsp, 177 lock_timeout, 178 lock_num, 179 smblctx, 180 lock_type, 181 lock_flav, 182 offset, 183 count, 184 blocking_smblctx); 185 } 160 186 161 187 if(req_is_in_chain(req)) { … … 187 213 } 188 214 blr->lock_num = lock_num; 189 blr-> lock_pid = lock_pid;190 blr->blocking_ pid = blocking_pid;215 blr->smblctx = smblctx; 216 blr->blocking_smblctx = blocking_smblctx; 191 217 blr->lock_flav = lock_flav; 192 218 blr->lock_type = lock_type; … … 198 224 199 225 /* Add a pending lock record for this. */ 200 status = brl_lock( smbd_messaging_context(),226 status = brl_lock(req->sconn->msg_ctx, 201 227 br_lck, 202 lock_pid,203 procid_self(),228 smblctx, 229 sconn_server_id(req->sconn), 204 230 offset, 205 231 count, … … 219 245 blr->req = talloc_move(blr, &req); 220 246 221 DLIST_ADD_END( blocking_lock_queue, blr, struct blocking_lock_record *);222 recalc_brl_timeout( );247 DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr, struct blocking_lock_record *); 248 recalc_brl_timeout(sconn); 223 249 224 250 /* Ensure we'll receive messages when this is unlocked. */ 225 if (! blocking_lock_unlock_state) {226 messaging_register(s mbd_messaging_context(), NULL,251 if (!sconn->smb1.locks.blocking_lock_unlock_state) { 252 messaging_register(sconn->msg_ctx, NULL, 227 253 MSG_SMB_UNLOCK, received_unlock_msg); 228 blocking_lock_unlock_state = true;254 sconn->smb1.locks.blocking_lock_unlock_state = true; 229 255 } 230 256 … … 275 301 276 302 if (fsp) { 277 fsp->last_lock_failure.context.smb pid = blr->lock_pid;303 fsp->last_lock_failure.context.smblctx = blr->smblctx; 278 304 fsp->last_lock_failure.context.tid = fsp->conn->cnum; 279 fsp->last_lock_failure.context.pid = procid_self(); 305 fsp->last_lock_failure.context.pid = 306 sconn_server_id(fsp->conn->sconn); 280 307 fsp->last_lock_failure.start = blr->offset; 281 308 fsp->last_lock_failure.size = blr->count; … … 287 314 288 315 reply_nterror(blr->req, status); 289 if (!srv_send_smb( smbd_server_fd(), (char *)blr->req->outbuf,316 if (!srv_send_smb(blr->req->sconn, (char *)blr->req->outbuf, 290 317 true, blr->req->seqnum+1, 291 318 blr->req->encrypted, NULL)) { … … 305 332 uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); 306 333 uint64_t count = (uint64_t)0, offset = (uint64_t) 0; 307 uint 32 lock_pid;334 uint64_t smblctx; 308 335 unsigned char locktype = CVAL(blr->req->vwv+3, 0); 309 336 bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); … … 328 355 bool err; 329 356 330 lock_pid= get_lock_pid( data, i, large_file_format);357 smblctx = get_lock_pid( data, i, large_file_format); 331 358 count = get_lock_count( data, i, large_file_format); 332 359 offset = get_lock_offset( data, i, large_file_format, &err); … … 337 364 */ 338 365 339 do_unlock( smbd_messaging_context(),366 do_unlock(fsp->conn->sconn->msg_ctx, 340 367 fsp, 341 lock_pid,368 smblctx, 342 369 count, 343 370 offset, … … 370 397 SCVAL(blr->req->outbuf,smb_com,SMBtrans2); 371 398 372 if (!srv_send_smb( smbd_server_fd(),399 if (!srv_send_smb(blr->req->sconn, 373 400 (char *)blr->req->outbuf, 374 401 true, blr->req->seqnum+1, … … 398 425 uint16 num_locks = SVAL(blr->req->vwv+7, 0); 399 426 uint64_t count = (uint64_t)0, offset = (uint64_t)0; 400 uint 32 lock_pid;427 uint64_t smblctx; 401 428 bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); 402 429 uint8_t *data; … … 415 442 bool err; 416 443 417 lock_pid= get_lock_pid( data, blr->lock_num, large_file_format);444 smblctx = get_lock_pid( data, blr->lock_num, large_file_format); 418 445 count = get_lock_count( data, blr->lock_num, large_file_format); 419 446 offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); … … 424 451 */ 425 452 errno = 0; 426 br_lck = do_lock( smbd_messaging_context(),453 br_lck = do_lock(fsp->conn->sconn->msg_ctx, 427 454 fsp, 428 lock_pid,455 smblctx, 429 456 count, 430 offset, 457 offset, 431 458 ((locktype & LOCKING_ANDX_SHARED_LOCK) ? 432 459 READ_LOCK : WRITE_LOCK), … … 434 461 True, 435 462 &status, 436 &blr->blocking_ pid,463 &blr->blocking_smblctx, 437 464 blr); 438 465 … … 488 515 char params[2]; 489 516 NTSTATUS status; 490 struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(), 517 struct byte_range_lock *br_lck = do_lock( 518 blr->fsp->conn->sconn->msg_ctx, 491 519 blr->fsp, 492 blr-> lock_pid,520 blr->smblctx, 493 521 blr->count, 494 522 blr->offset, … … 497 525 True, 498 526 &status, 499 &blr->blocking_ pid,527 &blr->blocking_smblctx, 500 528 blr); 501 529 TALLOC_FREE(br_lck); … … 545 573 /**************************************************************************** 546 574 Cancel entries by fnum from the blocking lock pending queue. 547 *****************************************************************************/ 548 549 void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) 550 { 575 Called when a file is closed. 576 *****************************************************************************/ 577 578 void cancel_pending_lock_requests_by_fid(files_struct *fsp, 579 struct byte_range_lock *br_lck, 580 enum file_close_type close_type) 581 { 582 struct smbd_server_connection *sconn = fsp->conn->sconn; 551 583 struct blocking_lock_record *blr, *blr_cancelled, *next = NULL; 552 584 553 for(blr = blocking_lock_queue; blr; blr = next) { 585 if (sconn->using_smb2) { 586 cancel_pending_lock_requests_by_fid_smb2(fsp, 587 br_lck, 588 close_type); 589 return; 590 } 591 592 for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { 554 593 unsigned char locktype = 0; 555 594 … … 567 606 blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum)); 568 607 569 blr_cancelled = blocking_lock_cancel (fsp,570 blr-> lock_pid,608 blr_cancelled = blocking_lock_cancel_smb1(fsp, 609 blr->smblctx, 571 610 blr->offset, 572 611 blr->count, … … 578 617 579 618 brl_lock_cancel(br_lck, 580 blr-> lock_pid,581 procid_self(),619 blr->smblctx, 620 sconn_server_id(sconn), 582 621 blr->offset, 583 622 blr->count, … … 593 632 /**************************************************************************** 594 633 Delete entries by mid from the blocking lock pending queue. Always send reply. 595 *****************************************************************************/ 596 597 void remove_pending_lock_requests_by_mid(int mid) 634 Only called from the SMB1 cancel code. 635 *****************************************************************************/ 636 637 void remove_pending_lock_requests_by_mid_smb1( 638 struct smbd_server_connection *sconn, uint64_t mid) 598 639 { 599 640 struct blocking_lock_record *blr, *next = NULL; 600 641 601 for(blr = blocking_lock_queue; blr; blr = next) {642 for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { 602 643 files_struct *fsp; 603 644 struct byte_range_lock *br_lck; … … 613 654 614 655 if (br_lck) { 615 DEBUG(10, ("remove_pending_lock_requests_by_mid - "656 DEBUG(10, ("remove_pending_lock_requests_by_mid_smb1 - " 616 657 "removing request type %d for file %s fnum " 617 658 "= %d\n", blr->req->cmd, fsp_str_dbg(fsp), … … 619 660 620 661 brl_lock_cancel(br_lck, 621 blr-> lock_pid,622 procid_self(),662 blr->smblctx, 663 sconn_server_id(sconn), 623 664 blr->offset, 624 665 blr->count, … … 629 670 630 671 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); 631 DLIST_REMOVE( blocking_lock_queue, blr);672 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 632 673 TALLOC_FREE(blr); 633 674 } … … 636 677 /**************************************************************************** 637 678 Is this mid a blocking lock request on the queue ? 638 *****************************************************************************/ 639 640 bool blocking_lock_was_deferred(int mid) 679 Currently only called from the SMB1 unix extensions POSIX lock code. 680 *****************************************************************************/ 681 682 bool blocking_lock_was_deferred_smb1( 683 struct smbd_server_connection *sconn, uint64_t mid) 641 684 { 642 685 struct blocking_lock_record *blr, *next = NULL; 643 686 644 for(blr = blocking_lock_queue; blr; blr = next) {687 for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { 645 688 next = blr->next; 646 689 if(blr->req->mid == mid) { … … 661 704 DATA_BLOB *data) 662 705 { 706 struct smbd_server_connection *sconn; 707 708 sconn = msg_ctx_to_sconn(msg); 709 if (sconn == NULL) { 710 DEBUG(1, ("could not find sconn\n")); 711 return; 712 } 713 663 714 DEBUG(10,("received_unlock_msg\n")); 664 process_blocking_lock_queue( );715 process_blocking_lock_queue(sconn); 665 716 } 666 717 … … 669 720 *****************************************************************************/ 670 721 671 void process_blocking_lock_queue( void)722 void process_blocking_lock_queue(struct smbd_server_connection *sconn) 672 723 { 673 724 struct timeval tv_curr = timeval_current(); 674 725 struct blocking_lock_record *blr, *next = NULL; 726 727 if (sconn->using_smb2) { 728 process_blocking_lock_queue_smb2(sconn, tv_curr); 729 return; 730 } 675 731 676 732 /* … … 678 734 */ 679 735 680 for (blr = blocking_lock_queue; blr; blr = next) {736 for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { 681 737 682 738 next = blr->next; … … 707 763 if (br_lck) { 708 764 brl_lock_cancel(br_lck, 709 blr-> lock_pid,710 procid_self(),765 blr->smblctx, 766 sconn_server_id(sconn), 711 767 blr->offset, 712 768 blr->count, … … 716 772 } 717 773 718 DLIST_REMOVE( blocking_lock_queue, blr);774 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 719 775 TALLOC_FREE(blr); 720 776 continue; … … 744 800 745 801 brl_lock_cancel(br_lck, 746 blr-> lock_pid,747 procid_self(),802 blr->smblctx, 803 sconn_server_id(sconn), 748 804 blr->offset, 749 805 blr->count, … … 754 810 755 811 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); 756 DLIST_REMOVE( blocking_lock_queue, blr);812 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 757 813 TALLOC_FREE(blr); 758 814 } 759 815 } 760 816 761 recalc_brl_timeout( );817 recalc_brl_timeout(sconn); 762 818 } 763 819 … … 774 830 DATA_BLOB *data) 775 831 { 832 struct smbd_server_connection *sconn; 776 833 NTSTATUS err; 777 834 const char *msg = (const char *)data->data; … … 788 845 } 789 846 847 sconn = msg_ctx_to_sconn(ctx); 848 if (sconn == NULL) { 849 DEBUG(1, ("could not find sconn\n")); 850 return; 851 } 852 790 853 memcpy(&blr, msg, sizeof(blr)); 791 854 memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS)); … … 795 858 796 859 blocking_lock_reply_error(blr, err); 797 DLIST_REMOVE( blocking_lock_cancelled_queue, blr);860 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_cancelled_queue, blr); 798 861 TALLOC_FREE(blr); 799 862 } … … 802 865 Send ourselves a blocking lock cancelled message. Handled asynchronously above. 803 866 Returns the blocking_lock_record that is being cancelled. 804 *****************************************************************************/ 805 806 struct blocking_lock_record *blocking_lock_cancel(files_struct *fsp, 807 uint32 lock_pid, 867 Only called from the SMB1 code. 868 *****************************************************************************/ 869 870 struct blocking_lock_record *blocking_lock_cancel_smb1(files_struct *fsp, 871 uint64_t smblctx, 808 872 uint64_t offset, 809 873 uint64_t count, … … 812 876 NTSTATUS err) 813 877 { 878 struct smbd_server_connection *sconn = fsp->conn->sconn; 814 879 char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE]; 815 880 struct blocking_lock_record *blr; 816 881 817 if (! blocking_lock_cancel_state) {882 if (!sconn->smb1.locks.blocking_lock_cancel_state) { 818 883 /* Register our message. */ 819 messaging_register(s mbd_messaging_context(), NULL,884 messaging_register(sconn->msg_ctx, NULL, 820 885 MSG_SMB_BLOCKING_LOCK_CANCEL, 821 886 process_blocking_lock_cancel_message); 822 887 823 blocking_lock_cancel_state = True;824 } 825 826 for (blr = blocking_lock_queue; blr; blr = blr->next) {888 sconn->smb1.locks.blocking_lock_cancel_state = True; 889 } 890 891 for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) { 827 892 if (fsp == blr->fsp && 828 lock_pid == blr->lock_pid&&893 smblctx == blr->smblctx && 829 894 offset == blr->offset && 830 895 count == blr->count && … … 846 911 847 912 /* Move to cancelled queue. */ 848 DLIST_REMOVE( blocking_lock_queue, blr);849 DLIST_ADD( blocking_lock_cancelled_queue, blr);913 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 914 DLIST_ADD(sconn->smb1.locks.blocking_lock_cancelled_queue, blr); 850 915 851 916 /* Create the message. */ … … 853 918 memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS)); 854 919 855 messaging_send_buf(s mbd_messaging_context(), procid_self(),920 messaging_send_buf(sconn->msg_ctx, sconn_server_id(sconn), 856 921 MSG_SMB_BLOCKING_LOCK_CANCEL, 857 922 (uint8 *)&msg, sizeof(msg));
Note:
See TracChangeset
for help on using the changeset viewer.