Changeset 740 for vendor/current/source3/smbd/oplock.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/oplock.c
r587 r740 22 22 #define DBGC_CLASS DBGC_LOCKING 23 23 #include "includes.h" 24 #include "smbd/smbd.h" 24 25 #include "smbd/globals.h" 26 #include "messages.h" 25 27 26 28 /**************************************************************************** … … 47 49 sending to ourselves. */ 48 50 49 messaging_send_buf(msg_ctx, procid_self(),51 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx), 50 52 MSG_SMB_KERNEL_BREAK, 51 53 msg, MSG_SMB_KERNEL_BREAK_SIZE); … … 53 55 54 56 /**************************************************************************** 55 Attempt to set an oplock on a file. Always succeeds if kernel oplocks are 56 disabled (just sets flags). Returns True if oplock set. 57 Attempt to set an oplock on a file. Succeeds if kernel oplocks are 58 disabled (just sets flags) and no byte-range locks in the file. Returns True 59 if oplock set. 57 60 ****************************************************************************/ 58 61 59 62 bool set_file_oplock(files_struct *fsp, int oplock_type) 60 63 { 61 if ((fsp->oplock_type == LEVEL_II_OPLOCK) 62 && koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) { 63 DEBUG(10, ("Refusing level2 oplock, kernel oplocks don't " 64 "support them\n")); 65 return false; 66 } 64 if (fsp->oplock_type == LEVEL_II_OPLOCK) { 65 if (koplocks && 66 !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) { 67 DEBUG(10, ("Refusing level2 oplock, kernel oplocks " 68 "don't support them\n")); 69 return false; 70 } 71 } 72 67 73 if ((fsp->oplock_type != NO_OPLOCK) && 68 74 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && … … 216 222 ****************************************************************************/ 217 223 218 static char *new_break_ smb_message(TALLOC_CTX *mem_ctx,219 files_struct *fsp, uint8cmd)224 static char *new_break_message_smb1(TALLOC_CTX *mem_ctx, 225 files_struct *fsp, int cmd) 220 226 { 221 227 char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0); … … 257 263 ****************************************************************************/ 258 264 259 static files_struct *initial_break_processing(struct file_id id, unsigned long file_id) 265 static files_struct *initial_break_processing( 266 struct smbd_server_connection *sconn, struct file_id id, 267 unsigned long file_id) 260 268 { 261 269 files_struct *fsp = NULL; … … 274 282 */ 275 283 276 fsp = file_find_dif( id, file_id);284 fsp = file_find_dif(sconn, id, file_id); 277 285 278 286 if(fsp == NULL) { … … 321 329 DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", 322 330 fsp_str_dbg(fsp))); 323 global_client_failed_oplock_break = True;324 331 remove_oplock(fsp); 325 332 reply_to_oplock_break_requests(fsp); … … 347 354 348 355 fsp->oplock_timeout = 349 event_add_timed(smbd_event_context(), NULL,356 event_add_timed(smbd_event_context(), fsp, 350 357 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0), 351 358 oplock_timeout_handler, fsp); … … 356 363 } 357 364 365 static void send_break_message_smb1(files_struct *fsp, int level) 366 { 367 char *break_msg = new_break_message_smb1(talloc_tos(), 368 fsp, 369 level); 370 if (break_msg == NULL) { 371 exit_server("Could not talloc break_msg\n"); 372 } 373 374 show_msg(break_msg); 375 if (!srv_send_smb(fsp->conn->sconn, 376 break_msg, false, 0, 377 IS_CONN_ENCRYPTED(fsp->conn), 378 NULL)) { 379 exit_server_cleanly("send_break_message_smb1: " 380 "srv_send_smb failed."); 381 } 382 383 TALLOC_FREE(break_msg); 384 } 385 358 386 void break_level2_to_none_async(files_struct *fsp) 359 387 { 360 char *break_msg;388 struct smbd_server_connection *sconn = fsp->conn->sconn; 361 389 362 390 if (fsp->oplock_type == NO_OPLOCK) { … … 384 412 385 413 /* Now send a break to none message to our client. */ 386 break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); 387 if (break_msg == NULL) { 388 exit_server("Could not talloc break_msg\n"); 389 } 390 391 show_msg(break_msg); 392 if (!srv_send_smb(smbd_server_fd(), 393 break_msg, false, 0, 394 IS_CONN_ENCRYPTED(fsp->conn), 395 NULL)) { 396 exit_server_cleanly("oplock_break: srv_send_smb failed."); 397 } 398 399 TALLOC_FREE(break_msg); 414 if (sconn->using_smb2) { 415 send_break_message_smb2(fsp, OPLOCKLEVEL_NONE); 416 } else { 417 send_break_message_smb1(fsp, OPLOCKLEVEL_NONE); 418 } 400 419 401 420 /* Async level2 request, don't send a reply, just remove the oplock. */ 402 421 remove_oplock(fsp); 403 404 422 } 405 423 … … 418 436 DATA_BLOB *data) 419 437 { 438 struct smbd_server_connection *sconn; 420 439 struct share_mode_entry msg; 421 440 files_struct *fsp; … … 423 442 if (data->data == NULL) { 424 443 DEBUG(0, ("Got NULL buffer\n")); 444 return; 445 } 446 447 sconn = msg_ctx_to_sconn(msg_ctx); 448 if (sconn == NULL) { 449 DEBUG(1, ("could not find sconn\n")); 425 450 return; 426 451 } … … 438 463 file_id_string_tos(&msg.id), msg.share_file_id)); 439 464 440 fsp = initial_break_processing( msg.id, msg.share_file_id);465 fsp = initial_break_processing(sconn, msg.id, msg.share_file_id); 441 466 442 467 if (fsp == NULL) { … … 461 486 DATA_BLOB *data) 462 487 { 488 struct smbd_server_connection *sconn; 463 489 struct share_mode_entry msg; 464 490 files_struct *fsp; 465 char *break_msg;466 491 bool break_to_level2 = False; 467 492 468 493 if (data->data == NULL) { 469 494 DEBUG(0, ("Got NULL buffer\n")); 495 return; 496 } 497 498 sconn = msg_ctx_to_sconn(msg_ctx); 499 if (sconn == NULL) { 500 DEBUG(1, ("could not find sconn\n")); 470 501 return; 471 502 } … … 483 514 msg.share_file_id)); 484 515 485 fsp = initial_break_processing( msg.id, msg.share_file_id);516 fsp = initial_break_processing(sconn, msg.id, msg.share_file_id); 486 517 487 518 if (fsp == NULL) { 488 /* a We hitrace here. Break messages are sent, and before we519 /* We hit a race here. Break messages are sent, and before we 489 520 * get to process this message, we have closed the file. Reply 490 521 * with 'ok, oplock broken' */ … … 527 558 } 528 559 529 break_msg = new_break_smb_message(NULL, fsp, break_to_level2 ? 530 OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); 531 if (break_msg == NULL) { 532 exit_server("Could not talloc break_msg\n"); 533 } 534 535 /* Need to wait before sending a break message if we sent ourselves this message. */ 560 /* Need to wait before sending a break 561 message if we sent ourselves this message. */ 536 562 if (procid_is_me(&src)) { 537 563 wait_before_sending_break(); 538 564 } 539 565 540 show_msg(break_msg); 541 if (!srv_send_smb(smbd_server_fd(), 542 break_msg, false, 0, 543 IS_CONN_ENCRYPTED(fsp->conn), 544 NULL)) { 545 exit_server_cleanly("oplock_break: srv_send_smb failed."); 546 } 547 548 TALLOC_FREE(break_msg); 566 if (sconn->using_smb2) { 567 send_break_message_smb2(fsp, break_to_level2 ? 568 OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); 569 } else { 570 send_break_message_smb1(fsp, break_to_level2 ? 571 OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); 572 } 549 573 550 574 fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; … … 568 592 DATA_BLOB *data) 569 593 { 594 struct smbd_server_connection *sconn; 570 595 struct file_id id; 571 596 unsigned long file_id; 572 597 files_struct *fsp; 573 char *break_msg;574 598 575 599 if (data->data == NULL) { … … 580 604 if (data->length != MSG_SMB_KERNEL_BREAK_SIZE) { 581 605 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length)); 606 return; 607 } 608 609 sconn = msg_ctx_to_sconn(msg_ctx); 610 if (sconn == NULL) { 611 DEBUG(1, ("could not find sconn\n")); 582 612 return; 583 613 } … … 591 621 (unsigned int)file_id)); 592 622 593 fsp = initial_break_processing( id, file_id);623 fsp = initial_break_processing(sconn, id, file_id); 594 624 595 625 if (fsp == NULL) { … … 606 636 } 607 637 608 break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); 609 if (break_msg == NULL) { 610 exit_server("Could not talloc break_msg\n"); 611 } 612 613 show_msg(break_msg); 614 if (!srv_send_smb(smbd_server_fd(), 615 break_msg, false, 0, 616 IS_CONN_ENCRYPTED(fsp->conn), 617 NULL)) { 618 exit_server_cleanly("oplock_break: srv_send_smb failed."); 619 } 620 621 TALLOC_FREE(break_msg); 638 if (sconn->using_smb2) { 639 send_break_message_smb2(fsp, OPLOCKLEVEL_NONE); 640 } else { 641 send_break_message_smb1(fsp, OPLOCKLEVEL_NONE); 642 } 622 643 623 644 fsp->sent_oplock_break = BREAK_TO_NONE_SENT; … … 645 666 share_mode_entry_to_message(msg, e); 646 667 647 messaging_send_buf( smbd_messaging_context(), e->pid,668 messaging_send_buf(fsp->conn->sconn->msg_ctx, e->pid, 648 669 MSG_SMB_BREAK_RESPONSE, 649 670 (uint8 *)msg, … … 683 704 message_to_share_mode_entry(&msg, (char *)data->data); 684 705 685 DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid % u\n",706 DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid %llu\n", 686 707 procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id), 687 msg.share_file_id, (unsigned int)msg.op_mid)); 688 689 /* Here's the hack from open.c, store the mid in the 'port' field */ 690 schedule_deferred_open_smb_message(msg.op_mid); 708 msg.share_file_id, (unsigned long long)msg.op_mid)); 709 710 schedule_deferred_open_message_smb(msg.op_mid); 691 711 } 692 712 … … 712 732 message_to_share_mode_entry(&msg, (char *)data->data); 713 733 714 DEBUG(10, ("Got open retry msg from pid %s: %s mid % u\n",734 DEBUG(10, ("Got open retry msg from pid %s: %s mid %llu\n", 715 735 procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id), 716 (unsigned int)msg.op_mid));717 718 schedule_deferred_open_ smb_message(msg.op_mid);736 (unsigned long long)msg.op_mid)); 737 738 schedule_deferred_open_message_smb(msg.op_mid); 719 739 } 720 740 … … 804 824 805 825 if (procid_is_me(&share_entry->pid)) { 826 struct files_struct *cur_fsp = 827 initial_break_processing(fsp->conn->sconn, 828 share_entry->id, 829 share_entry->share_file_id); 806 830 wait_before_sending_break(); 807 break_level2_to_none_async(fsp); 831 if (cur_fsp != NULL) { 832 break_level2_to_none_async(cur_fsp); 833 } else { 834 DEBUG(3, ("release_level_2_oplocks_on_change: " 835 "Did not find fsp, ignoring\n")); 836 } 808 837 } else { 809 messaging_send_buf( smbd_messaging_context(),838 messaging_send_buf(fsp->conn->sconn->msg_ctx, 810 839 share_entry->pid, 811 840 MSG_SMB_ASYNC_LEVEL2_BREAK, … … 847 876 void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e) 848 877 { 849 SIVAL(msg,0,(uint32)e->pid.pid); 850 SSVAL(msg,4,e->op_mid); 851 SSVAL(msg,6,e->op_type); 852 SIVAL(msg,8,e->access_mask); 853 SIVAL(msg,12,e->share_access); 854 SIVAL(msg,16,e->private_options); 855 SIVAL(msg,20,(uint32)e->time.tv_sec); 856 SIVAL(msg,24,(uint32)e->time.tv_usec); 857 push_file_id_24(msg+28, &e->id); 858 SIVAL(msg,52,e->share_file_id); 859 SIVAL(msg,56,e->uid); 860 SSVAL(msg,60,e->flags); 861 #ifdef CLUSTER_SUPPORT 862 SIVAL(msg,62,e->pid.vnn); 863 #endif 878 SIVAL(msg,OP_BREAK_MSG_PID_OFFSET,(uint32)e->pid.pid); 879 SBVAL(msg,OP_BREAK_MSG_MID_OFFSET,e->op_mid); 880 SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET,e->op_type); 881 SIVAL(msg,OP_BREAK_MSG_ACCESS_MASK_OFFSET,e->access_mask); 882 SIVAL(msg,OP_BREAK_MSG_SHARE_ACCESS_OFFSET,e->share_access); 883 SIVAL(msg,OP_BREAK_MSG_PRIV_OFFSET,e->private_options); 884 SIVAL(msg,OP_BREAK_MSG_TIME_SEC_OFFSET,(uint32_t)e->time.tv_sec); 885 SIVAL(msg,OP_BREAK_MSG_TIME_USEC_OFFSET,(uint32_t)e->time.tv_usec); 886 push_file_id_24(msg+OP_BREAK_MSG_DEV_OFFSET, &e->id); 887 SIVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET,e->share_file_id); 888 SIVAL(msg,OP_BREAK_MSG_UID_OFFSET,e->uid); 889 SSVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET,e->flags); 890 SIVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET,e->name_hash); 891 SIVAL(msg,OP_BREAK_MSG_VNN_OFFSET,e->pid.vnn); 864 892 } 865 893 … … 870 898 void message_to_share_mode_entry(struct share_mode_entry *e, char *msg) 871 899 { 872 e->pid.pid = (pid_t)IVAL(msg,0); 873 e->op_mid = SVAL(msg,4); 874 e->op_type = SVAL(msg,6); 875 e->access_mask = IVAL(msg,8); 876 e->share_access = IVAL(msg,12); 877 e->private_options = IVAL(msg,16); 878 e->time.tv_sec = (time_t)IVAL(msg,20); 879 e->time.tv_usec = (int)IVAL(msg,24); 880 pull_file_id_24(msg+28, &e->id); 881 e->share_file_id = (unsigned long)IVAL(msg,52); 882 e->uid = (uint32)IVAL(msg,56); 883 e->flags = (uint16)SVAL(msg,60); 884 #ifdef CLUSTER_SUPPORT 885 e->pid.vnn = IVAL(msg,62); 886 #endif 900 e->pid.pid = (pid_t)IVAL(msg,OP_BREAK_MSG_PID_OFFSET); 901 e->op_mid = BVAL(msg,OP_BREAK_MSG_MID_OFFSET); 902 e->op_type = SVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET); 903 e->access_mask = IVAL(msg,OP_BREAK_MSG_ACCESS_MASK_OFFSET); 904 e->share_access = IVAL(msg,OP_BREAK_MSG_SHARE_ACCESS_OFFSET); 905 e->private_options = IVAL(msg,OP_BREAK_MSG_PRIV_OFFSET); 906 e->time.tv_sec = (time_t)IVAL(msg,OP_BREAK_MSG_TIME_SEC_OFFSET); 907 e->time.tv_usec = (int)IVAL(msg,OP_BREAK_MSG_TIME_USEC_OFFSET); 908 pull_file_id_24(msg+OP_BREAK_MSG_DEV_OFFSET, &e->id); 909 e->share_file_id = (unsigned long)IVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET); 910 e->uid = (uint32)IVAL(msg,OP_BREAK_MSG_UID_OFFSET); 911 e->flags = (uint16)SVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET); 912 e->name_hash = IVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET); 913 e->pid.vnn = IVAL(msg,OP_BREAK_MSG_VNN_OFFSET); 887 914 } 888 915 … … 908 935 if (lp_kernel_oplocks()) { 909 936 #if HAVE_KERNEL_OPLOCKS_IRIX 910 koplocks = irix_init_kernel_oplocks( talloc_autofree_context());937 koplocks = irix_init_kernel_oplocks(NULL); 911 938 #elif HAVE_KERNEL_OPLOCKS_LINUX 912 koplocks = linux_init_kernel_oplocks( talloc_autofree_context());939 koplocks = linux_init_kernel_oplocks(NULL); 913 940 #elif HAVE_ONEFS 914 koplocks = onefs_init_kernel_oplocks(talloc_autofree_context()); 941 #error Isilon, please check if the NULL context is okay here. Thanks! 942 koplocks = onefs_init_kernel_oplocks(NULL); 915 943 #endif 916 944 }
Note:
See TracChangeset
for help on using the changeset viewer.