Changeset 988 for vendor/current/source3/smbd/blocking.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/blocking.c
r746 r988 25 25 #undef DBGC_CLASS 26 26 #define DBGC_CLASS DBGC_LOCKING 27 28 /****************************************************************************29 Determine if this is a secondary element of a chained SMB.30 **************************************************************************/31 27 32 28 static void received_unlock_msg(struct messaging_context *msg, … … 36 32 DATA_BLOB *data); 37 33 38 void brl_timeout_fn(struct event_context *event_ctx,39 struct t imed_event*te,34 void brl_timeout_fn(struct tevent_context *event_ctx, 35 struct tevent_timer *te, 40 36 struct timeval now, 41 37 void *private_data) … … 112 108 } 113 109 114 /* 110 /* 115 111 to account for unclean shutdowns by clients we need a 116 112 maximum timeout that we use for checking pending locks. If … … 140 136 } 141 137 142 sconn->smb1.locks.brl_timeout = event_add_timed(smbd_event_context(),143 NULL, next_timeout,144 brl_timeout_fn, sconn);138 sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->ev_ctx, 139 NULL, next_timeout, 140 brl_timeout_fn, sconn); 145 141 if (sconn->smb1.locks.brl_timeout == NULL) { 146 142 return False; … … 209 205 blr->expire_time.tv_usec = 0; /* Never expire. */ 210 206 } else { 211 blr->expire_time = timeval_current_ofs(lock_timeout/1000, 212 (lock_timeout % 1000) * 1000); 207 blr->expire_time = timeval_current_ofs_msec(lock_timeout); 213 208 } 214 209 blr->lock_num = lock_num; … … 219 214 blr->offset = offset; 220 215 blr->count = count; 221 216 222 217 /* Specific brl_lock() implementations can fill this in. */ 223 218 blr->blr_private = NULL; … … 227 222 br_lck, 228 223 smblctx, 229 sconn_server_id(req->sconn),224 messaging_server_id(req->sconn->msg_ctx), 230 225 offset, 231 226 count, … … 233 228 blr->lock_flav, 234 229 True, 235 NULL, 236 blr); 230 NULL); 237 231 238 232 if (!NT_STATUS_IS_OK(status)) { … … 245 239 blr->req = talloc_move(blr, &req); 246 240 247 DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr , struct blocking_lock_record *);241 DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr); 248 242 recalc_brl_timeout(sconn); 249 243 250 244 /* Ensure we'll receive messages when this is unlocked. */ 251 245 if (!sconn->smb1.locks.blocking_lock_unlock_state) { 252 messaging_register(sconn->msg_ctx, NULL,246 messaging_register(sconn->msg_ctx, sconn, 253 247 MSG_SMB_UNLOCK, received_unlock_msg); 254 248 sconn->smb1.locks.blocking_lock_unlock_state = true; … … 256 250 257 251 DEBUG(3,("push_blocking_lock_request: lock request blocked with " 258 "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",252 "expiry time (%u sec. %u usec) (+%d msec) for %s, name = %s\n", 259 253 (unsigned int)blr->expire_time.tv_sec, 260 254 (unsigned int)blr->expire_time.tv_usec, lock_timeout, 261 blr->fsp->fnum, fsp_str_dbg(blr->fsp)));255 fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp))); 262 256 263 257 return True; … … 270 264 static void reply_lockingX_success(struct blocking_lock_record *blr) 271 265 { 272 reply_outbuf(blr->req, 2, 0); 266 struct smb_request *req = blr->req; 267 268 reply_outbuf(req, 2, 0); 269 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */ 270 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */ 273 271 274 272 /* … … 280 278 */ 281 279 282 chain_reply(blr->req); 283 TALLOC_FREE(blr->req->outbuf); 280 if (!srv_send_smb(req->xconn, 281 (char *)req->outbuf, 282 true, req->seqnum+1, 283 IS_CONN_ENCRYPTED(req->conn)||req->encrypted, 284 &req->pcd)) { 285 exit_server_cleanly("construct_reply: srv_send_smb failed."); 286 } 287 288 TALLOC_FREE(req->outbuf); 284 289 } 285 290 … … 304 309 fsp->last_lock_failure.context.tid = fsp->conn->cnum; 305 310 fsp->last_lock_failure.context.pid = 306 sconn_server_id(fsp->conn->sconn);311 messaging_server_id(fsp->conn->sconn->msg_ctx); 307 312 fsp->last_lock_failure.start = blr->offset; 308 313 fsp->last_lock_failure.size = blr->count; … … 314 319 315 320 reply_nterror(blr->req, status); 316 if (!srv_send_smb(blr->req-> sconn, (char *)blr->req->outbuf,321 if (!srv_send_smb(blr->req->xconn, (char *)blr->req->outbuf, 317 322 true, blr->req->seqnum+1, 318 323 blr->req->encrypted, NULL)) { … … 323 328 324 329 /**************************************************************************** 325 Return a lock fail error for a lockingX call. Undo all the locks we have 330 Return a lock fail error for a lockingX call. Undo all the locks we have 326 331 obtained first. 327 332 *****************************************************************************/ … … 330 335 { 331 336 files_struct *fsp = blr->fsp; 332 uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);337 uint16_t num_ulocks = SVAL(blr->req->vwv+6, 0); 333 338 uint64_t count = (uint64_t)0, offset = (uint64_t) 0; 334 339 uint64_t smblctx; … … 338 343 int i; 339 344 340 data = (uint8_t *)blr->req->buf345 data = discard_const_p(uint8_t, blr->req->buf) 341 346 + ((large_file_format ? 20 : 10)*num_ulocks); 342 347 343 /* 348 /* 344 349 * Data now points at the beginning of the list 345 350 * of smb_lkrng structs. … … 353 358 354 359 for(i = blr->lock_num - 1; i >= 0; i--) { 355 bool err;356 360 357 361 smblctx = get_lock_pid( data, i, large_file_format); 358 362 count = get_lock_count( data, i, large_file_format); 359 offset = get_lock_offset( data, i, large_file_format , &err);363 offset = get_lock_offset( data, i, large_file_format); 360 364 361 365 /* … … 393 397 } 394 398 generic_blocking_lock_error(blr, status); 395 399 break; 396 400 case SMBtrans2: 397 401 case SMBtranss2: … … 404 408 SCVAL(blr->req->outbuf,smb_com,SMBtrans2); 405 409 406 if (!srv_send_smb(blr->req-> sconn,410 if (!srv_send_smb(blr->req->xconn, 407 411 (char *)blr->req->outbuf, 408 412 true, blr->req->seqnum+1, … … 421 425 422 426 /**************************************************************************** 427 Utility function that returns true if a lock timed out. 428 *****************************************************************************/ 429 430 static bool lock_timed_out(const struct blocking_lock_record *blr) 431 { 432 struct timeval tv_curr; 433 434 if (timeval_is_zero(&blr->expire_time)) { 435 return false; /* Never times out. */ 436 } 437 438 tv_curr = timeval_current(); 439 if (timeval_compare(&blr->expire_time, &tv_curr) <= 0) { 440 return true; 441 } 442 return false; 443 } 444 445 /**************************************************************************** 423 446 Attempt to finish off getting all pending blocking locks for a lockingX call. 424 447 Returns True if we want to be removed from the list. … … 429 452 unsigned char locktype = CVAL(blr->req->vwv+3, 0); 430 453 files_struct *fsp = blr->fsp; 431 uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); 432 uint16 num_locks = SVAL(blr->req->vwv+7, 0); 433 uint64_t count = (uint64_t)0, offset = (uint64_t)0; 434 uint64_t smblctx; 454 uint16_t num_ulocks = SVAL(blr->req->vwv+6, 0); 455 uint16_t num_locks = SVAL(blr->req->vwv+7, 0); 435 456 bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); 436 457 uint8_t *data; 437 458 NTSTATUS status = NT_STATUS_OK; 438 439 data = (uint8_t *)blr->req->buf 459 bool lock_timeout = lock_timed_out(blr); 460 461 data = discard_const_p(uint8_t, blr->req->buf) 440 462 + ((large_file_format ? 20 : 10)*num_ulocks); 441 463 442 /* 464 /* 443 465 * Data now points at the beginning of the list 444 466 * of smb_lkrng structs. … … 447 469 for(; blr->lock_num < num_locks; blr->lock_num++) { 448 470 struct byte_range_lock *br_lck = NULL; 449 bool err; 450 451 smblctx = get_lock_pid( data, blr->lock_num, large_file_format); 452 count = get_lock_count( data, blr->lock_num, large_file_format); 453 offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); 471 472 /* 473 * Ensure the blr record gets updated with 474 * any lock we might end up blocked on. 475 */ 476 477 blr->smblctx = get_lock_pid( data, blr->lock_num, large_file_format); 478 blr->count = get_lock_count( data, blr->lock_num, large_file_format); 479 blr->offset = get_lock_offset( data, blr->lock_num, large_file_format); 454 480 455 481 /* … … 460 486 br_lck = do_lock(fsp->conn->sconn->msg_ctx, 461 487 fsp, 462 smblctx,463 count,464 offset,488 blr->smblctx, 489 blr->count, 490 blr->offset, 465 491 ((locktype & LOCKING_ANDX_SHARED_LOCK) ? 466 492 READ_LOCK : WRITE_LOCK), … … 468 494 True, 469 495 &status, 470 &blr->blocking_smblctx, 471 blr); 496 &blr->blocking_smblctx); 497 498 if (ERROR_WAS_LOCK_DENIED(status) && !lock_timeout) { 499 /* 500 * If we didn't timeout, but still need to wait, 501 * re-add the pending lock entry whilst holding 502 * the brlock db lock. 503 */ 504 NTSTATUS status1 = 505 brl_lock(blr->fsp->conn->sconn->msg_ctx, 506 br_lck, 507 blr->smblctx, 508 messaging_server_id( 509 blr->fsp->conn->sconn->msg_ctx), 510 blr->offset, 511 blr->count, 512 blr->lock_type == READ_LOCK ? 513 PENDING_READ_LOCK : 514 PENDING_WRITE_LOCK, 515 blr->lock_flav, 516 true, /* Blocking lock. */ 517 NULL); 518 519 if (!NT_STATUS_IS_OK(status1)) { 520 DEBUG(0,("failed to add PENDING_LOCK " 521 "record.\n")); 522 } 523 } 472 524 473 525 TALLOC_FREE(br_lck); … … 483 535 */ 484 536 485 DEBUG(3,("process_lockingX file = %s, fnum=%dtype=%d "486 "num_locks=%d\n", fsp_str_dbg(fsp), fsp ->fnum,537 DEBUG(3,("process_lockingX file = %s, %s, type=%d " 538 "num_locks=%d\n", fsp_str_dbg(fsp), fsp_fnum_dbg(fsp), 487 539 (unsigned int)locktype, num_locks)); 488 540 … … 491 543 } 492 544 493 if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && 494 !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { 545 if (!ERROR_WAS_LOCK_DENIED(status)) { 495 546 /* 496 547 * We have other than a "can't get lock" … … 503 554 504 555 /* 556 * Return an error to the client if we timed out. 557 */ 558 if (lock_timeout) { 559 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); 560 return true; 561 } 562 563 /* 505 564 * Still can't get all the locks - keep waiting. 506 565 */ 507 566 508 DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ 509 Waiting....\n", 510 blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum)); 567 DEBUG(10, ("process_lockingX: only got %d locks of %d needed for " 568 "file %s, %s. Waiting....\n", 569 blr->lock_num, num_locks, fsp_str_dbg(fsp), 570 fsp_fnum_dbg(fsp))); 511 571 512 572 return False; … … 522 582 char params[2]; 523 583 NTSTATUS status; 584 bool lock_timeout = lock_timed_out(blr); 585 524 586 struct byte_range_lock *br_lck = do_lock( 525 587 blr->fsp->conn->sconn->msg_ctx, … … 532 594 True, 533 595 &status, 534 &blr->blocking_smblctx, 535 blr); 596 &blr->blocking_smblctx); 597 if (ERROR_WAS_LOCK_DENIED(status) && !lock_timeout) { 598 /* 599 * If we didn't timeout, but still need to wait, 600 * re-add the pending lock entry whilst holding 601 * the brlock db lock. 602 */ 603 NTSTATUS status1 = 604 brl_lock(blr->fsp->conn->sconn->msg_ctx, 605 br_lck, 606 blr->smblctx, 607 messaging_server_id( 608 blr->fsp->conn->sconn->msg_ctx), 609 blr->offset, 610 blr->count, 611 blr->lock_type == READ_LOCK ? 612 PENDING_READ_LOCK : 613 PENDING_WRITE_LOCK, 614 blr->lock_flav, 615 true, /* Blocking lock. */ 616 NULL); 617 618 if (!NT_STATUS_IS_OK(status1)) { 619 DEBUG(0,("failed to add PENDING_LOCK record.\n")); 620 } 621 } 622 536 623 TALLOC_FREE(br_lck); 537 624 538 625 if (!NT_STATUS_IS_OK(status)) { 539 626 if (ERROR_WAS_LOCK_DENIED(status)) { 627 if (lock_timeout) { 628 /* 629 * Return an error if we timed out 630 * and return true to get dequeued. 631 */ 632 blocking_lock_reply_error(blr, 633 NT_STATUS_FILE_LOCK_CONFLICT); 634 return true; 635 } 540 636 /* Still can't get the lock, just keep waiting. */ 541 637 return False; 542 } 638 } 543 639 /* 544 640 * We have other than a "can't get lock" … … 553 649 SSVAL(params,0,0); 554 650 /* Fake up max_data_bytes here - we know it fits. */ 555 send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);651 send_trans2_replies(blr->fsp->conn, blr->req, NT_STATUS_OK, params, 2, NULL, 0, 0xffff); 556 652 return True; 557 653 } … … 583 679 *****************************************************************************/ 584 680 585 void cancel_pending_lock_requests_by_fid(files_struct *fsp,586 struct byte_range_lock *br_lck,587 enum file_close_type close_type)681 void smbd_cancel_pending_lock_requests_by_fid(files_struct *fsp, 682 struct byte_range_lock *br_lck, 683 enum file_close_type close_type) 588 684 { 589 685 struct smbd_server_connection *sconn = fsp->conn->sconn; … … 610 706 611 707 DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " 612 "request type %d for file %s fnum = %d\n",613 blr->req->cmd, fsp_str_dbg(fsp), fsp ->fnum));708 "request type %d for file %s, %s\n", 709 blr->req->cmd, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp))); 614 710 615 711 blr_cancelled = blocking_lock_cancel_smb1(fsp, … … 625 721 brl_lock_cancel(br_lck, 626 722 blr->smblctx, 627 sconn_server_id(sconn),723 messaging_server_id(sconn->msg_ctx), 628 724 blr->offset, 629 725 blr->count, 630 blr->lock_flav, 631 blr); 726 blr->lock_flav); 632 727 633 728 /* We're closing the file fsp here, so ensure … … 662 757 if (br_lck) { 663 758 DEBUG(10, ("remove_pending_lock_requests_by_mid_smb1 - " 664 "removing request type %d for file %s fnum "665 "= %d\n",blr->req->cmd, fsp_str_dbg(fsp),666 fsp ->fnum));759 "removing request type %d for file %s, %s\n", 760 blr->req->cmd, fsp_str_dbg(fsp), 761 fsp_fnum_dbg(fsp))); 667 762 668 763 brl_lock_cancel(br_lck, 669 764 blr->smblctx, 670 sconn_server_id(sconn),765 messaging_server_id(sconn->msg_ctx), 671 766 blr->offset, 672 767 blr->count, 673 blr->lock_flav, 674 blr); 768 blr->lock_flav); 675 769 TALLOC_FREE(br_lck); 676 770 } … … 711 805 DATA_BLOB *data) 712 806 { 713 struct smbd_server_connection *sconn; 714 715 sconn = msg_ctx_to_sconn(msg); 716 if (sconn == NULL) { 717 DEBUG(1, ("could not find sconn\n")); 718 return; 719 } 807 struct smbd_server_connection *sconn = 808 talloc_get_type_abort(private_data, 809 struct smbd_server_connection); 720 810 721 811 DEBUG(10,("received_unlock_msg\n")); … … 729 819 void process_blocking_lock_queue(struct smbd_server_connection *sconn) 730 820 { 731 struct timeval tv_curr = timeval_current();732 821 struct blocking_lock_record *blr, *next = NULL; 733 822 734 823 if (sconn->using_smb2) { 735 process_blocking_lock_queue_smb2(sconn, t v_curr);824 process_blocking_lock_queue_smb2(sconn, timeval_current()); 736 825 return; 737 826 } … … 742 831 743 832 for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { 833 struct byte_range_lock *br_lck = NULL; 744 834 745 835 next = blr->next; … … 761 851 false); 762 852 763 if(blocking_lock_record_process(blr)) { 764 struct byte_range_lock *br_lck = brl_get_locks( 765 talloc_tos(), blr->fsp); 766 767 DEBUG(10, ("BLR_process returned true: cancelling and " 768 "removing lock. BLR = %p\n", blr)); 769 770 if (br_lck) { 771 brl_lock_cancel(br_lck, 772 blr->smblctx, 773 sconn_server_id(sconn), 774 blr->offset, 775 blr->count, 776 blr->lock_flav, 777 blr); 778 TALLOC_FREE(br_lck); 779 } 780 781 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 782 TALLOC_FREE(blr); 853 /* 854 * Remove the pending lock we're waiting on. 855 * If we need to keep waiting blocking_lock_record_process() 856 * will re-add it. 857 */ 858 859 br_lck = brl_get_locks(talloc_tos(), blr->fsp); 860 if (br_lck) { 861 brl_lock_cancel(br_lck, 862 blr->smblctx, 863 messaging_server_id(sconn->msg_ctx), 864 blr->offset, 865 blr->count, 866 blr->lock_flav); 867 } 868 TALLOC_FREE(br_lck); 869 870 if(!blocking_lock_record_process(blr)) { 871 DEBUG(10, ("still waiting for lock. BLR = %p\n", blr)); 783 872 continue; 784 873 } 785 874 786 /* 787 * We couldn't get the locks for this record on the list. 788 * If the time has expired, return a lock error. 789 */ 790 791 if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { 792 struct byte_range_lock *br_lck = brl_get_locks( 793 talloc_tos(), blr->fsp); 794 795 DEBUG(10, ("Lock timed out! BLR = %p\n", blr)); 796 797 /* 798 * Lock expired - throw away all previously 799 * obtained locks and return lock error. 800 */ 801 802 if (br_lck) { 803 DEBUG(5,("process_blocking_lock_queue: " 804 "pending lock fnum = %d for file %s " 805 "timed out.\n", blr->fsp->fnum, 806 fsp_str_dbg(blr->fsp))); 807 808 brl_lock_cancel(br_lck, 809 blr->smblctx, 810 sconn_server_id(sconn), 811 blr->offset, 812 blr->count, 813 blr->lock_flav, 814 blr); 815 TALLOC_FREE(br_lck); 816 } 817 818 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); 819 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 820 TALLOC_FREE(blr); 821 } 875 DEBUG(10, ("BLR_process returned true: removing BLR = %p\n", 876 blr)); 877 878 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); 879 TALLOC_FREE(blr); 822 880 } 823 881 … … 837 895 DATA_BLOB *data) 838 896 { 839 struct smbd_server_connection *sconn;840 897 NTSTATUS err; 841 898 const char *msg = (const char *)data->data; 842 899 struct blocking_lock_record *blr; 900 struct smbd_server_connection *sconn = 901 talloc_get_type_abort(private_data, 902 struct smbd_server_connection); 843 903 844 904 if (data->data == NULL) { … … 851 911 smb_panic("process_blocking_lock_cancel_message: bad msg"); 852 912 } 853 854 sconn = msg_ctx_to_sconn(ctx);855 if (sconn == NULL) {856 DEBUG(1, ("could not find sconn\n"));857 return;858 }859 913 860 914 memcpy(&blr, msg, sizeof(blr)); … … 889 943 if (!sconn->smb1.locks.blocking_lock_cancel_state) { 890 944 /* Register our message. */ 891 messaging_register(sconn->msg_ctx, NULL,945 messaging_register(sconn->msg_ctx, sconn, 892 946 MSG_SMB_BLOCKING_LOCK_CANCEL, 893 947 process_blocking_lock_cancel_message); … … 925 979 memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS)); 926 980 927 messaging_send_buf(sconn->msg_ctx, sconn_server_id(sconn),981 messaging_send_buf(sconn->msg_ctx, messaging_server_id(sconn->msg_ctx), 928 982 MSG_SMB_BLOCKING_LOCK_CANCEL, 929 (uint8 *)&msg, sizeof(msg));983 (uint8_t *)&msg, sizeof(msg)); 930 984 931 985 return blr;
Note:
See TracChangeset
for help on using the changeset viewer.