1/* 2 Unix SMB/CIFS implementation. 3 oplock processing 4 Copyright (C) Andrew Tridgell 1992-1998 5 Copyright (C) Jeremy Allison 1998 - 2001 6 Copyright (C) Volker Lendecke 2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#define DBGC_CLASS DBGC_LOCKING 23#include "includes.h" 24#include "smbd/globals.h" 25 26/**************************************************************************** 27 Get the number of current exclusive oplocks. 28****************************************************************************/ 29 30int32 get_number_of_exclusive_open_oplocks(void) 31{ 32 return exclusive_oplocks_open; 33} 34 35/* 36 * helper function used by the kernel oplock backends to post the break message 37 */ 38void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp) 39{ 40 uint8_t msg[MSG_SMB_KERNEL_BREAK_SIZE]; 41 42 /* Put the kernel break info into the message. */ 43 push_file_id_24((char *)msg, &fsp->file_id); 44 SIVAL(msg,24,fsp->fh->gen_id); 45 46 /* Don't need to be root here as we're only ever 47 sending to ourselves. */ 48 49 messaging_send_buf(msg_ctx, procid_self(), 50 MSG_SMB_KERNEL_BREAK, 51 msg, MSG_SMB_KERNEL_BREAK_SIZE); 52} 53 54/**************************************************************************** 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****************************************************************************/ 58 59bool set_file_oplock(files_struct *fsp, int oplock_type) 60{ 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 } 67 if ((fsp->oplock_type != NO_OPLOCK) && 68 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && 69 koplocks && 70 !koplocks->ops->set_oplock(koplocks, fsp, oplock_type)) { 71 return False; 72 } 73 74 fsp->oplock_type = oplock_type; 75 fsp->sent_oplock_break = NO_BREAK_SENT; 76 if (oplock_type == LEVEL_II_OPLOCK) { 77 level_II_oplocks_open++; 78 } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 79 exclusive_oplocks_open++; 80 } 81 82 DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, " 83 "tv_sec = %x, tv_usec = %x\n", 84 fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id), 85 fsp->fh->gen_id, (int)fsp->open_time.tv_sec, 86 (int)fsp->open_time.tv_usec )); 87 88 return True; 89} 90 91/**************************************************************************** 92 Attempt to release an oplock on a file. Decrements oplock count. 93****************************************************************************/ 94 95void release_file_oplock(files_struct *fsp) 96{ 97 if ((fsp->oplock_type != NO_OPLOCK) && 98 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && 99 koplocks) { 100 koplocks->ops->release_oplock(koplocks, fsp, NO_OPLOCK); 101 } 102 103 if (fsp->oplock_type == LEVEL_II_OPLOCK) { 104 level_II_oplocks_open--; 105 } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 106 exclusive_oplocks_open--; 107 } 108 109 SMB_ASSERT(exclusive_oplocks_open>=0); 110 SMB_ASSERT(level_II_oplocks_open>=0); 111 112 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 113 /* This doesn't matter for close. */ 114 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK; 115 } else { 116 fsp->oplock_type = NO_OPLOCK; 117 } 118 fsp->sent_oplock_break = NO_BREAK_SENT; 119 120 flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH); 121 delete_write_cache(fsp); 122 123 TALLOC_FREE(fsp->oplock_timeout); 124} 125 126/**************************************************************************** 127 Attempt to downgrade an oplock on a file. Doesn't decrement oplock count. 128****************************************************************************/ 129 130static void downgrade_file_oplock(files_struct *fsp) 131{ 132 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 133 DEBUG(0, ("trying to downgrade an already-downgraded oplock!\n")); 134 return; 135 } 136 137 if (koplocks) { 138 koplocks->ops->release_oplock(koplocks, fsp, LEVEL_II_OPLOCK); 139 } 140 fsp->oplock_type = LEVEL_II_OPLOCK; 141 exclusive_oplocks_open--; 142 level_II_oplocks_open++; 143 fsp->sent_oplock_break = NO_BREAK_SENT; 144} 145 146/**************************************************************************** 147 Remove a file oplock. Copes with level II and exclusive. 148 Locks then unlocks the share mode lock. Client can decide to go directly 149 to none even if a "break-to-level II" was sent. 150****************************************************************************/ 151 152bool remove_oplock(files_struct *fsp) 153{ 154 bool ret; 155 struct share_mode_lock *lck; 156 157 /* Remove the oplock flag from the sharemode. */ 158 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, 159 NULL); 160 if (lck == NULL) { 161 DEBUG(0,("remove_oplock: failed to lock share entry for " 162 "file %s\n", fsp_str_dbg(fsp))); 163 return False; 164 } 165 ret = remove_share_oplock(lck, fsp); 166 if (!ret) { 167 DEBUG(0,("remove_oplock: failed to remove share oplock for " 168 "file %s fnum %d, %s\n", 169 fsp_str_dbg(fsp), fsp->fnum, 170 file_id_string_tos(&fsp->file_id))); 171 } 172 release_file_oplock(fsp); 173 TALLOC_FREE(lck); 174 return ret; 175} 176 177/* 178 * Deal with a reply when a break-to-level II was sent. 179 */ 180bool downgrade_oplock(files_struct *fsp) 181{ 182 bool ret; 183 struct share_mode_lock *lck; 184 185 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, 186 NULL); 187 if (lck == NULL) { 188 DEBUG(0,("downgrade_oplock: failed to lock share entry for " 189 "file %s\n", fsp_str_dbg(fsp))); 190 return False; 191 } 192 ret = downgrade_share_oplock(lck, fsp); 193 if (!ret) { 194 DEBUG(0,("downgrade_oplock: failed to downgrade share oplock " 195 "for file %s fnum %d, file_id %s\n", 196 fsp_str_dbg(fsp), fsp->fnum, 197 file_id_string_tos(&fsp->file_id))); 198 } 199 200 downgrade_file_oplock(fsp); 201 TALLOC_FREE(lck); 202 return ret; 203} 204 205/* 206 * Some kernel oplock implementations handle the notification themselves. 207 */ 208bool should_notify_deferred_opens() 209{ 210 return !(koplocks && 211 (koplocks->flags & KOPLOCKS_DEFERRED_OPEN_NOTIFICATION)); 212} 213 214/**************************************************************************** 215 Set up an oplock break message. 216****************************************************************************/ 217 218static char *new_break_smb_message(TALLOC_CTX *mem_ctx, 219 files_struct *fsp, uint8 cmd) 220{ 221 char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0); 222 223 if (result == NULL) { 224 DEBUG(0, ("talloc failed\n")); 225 return NULL; 226 } 227 228 memset(result,'\0',smb_size); 229 srv_set_message(result,8,0,true); 230 SCVAL(result,smb_com,SMBlockingX); 231 SSVAL(result,smb_tid,fsp->conn->cnum); 232 SSVAL(result,smb_pid,0xFFFF); 233 SSVAL(result,smb_uid,0); 234 SSVAL(result,smb_mid,0xFFFF); 235 SCVAL(result,smb_vwv0,0xFF); 236 SSVAL(result,smb_vwv2,fsp->fnum); 237 SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE); 238 SCVAL(result,smb_vwv3+1,cmd); 239 return result; 240} 241 242/**************************************************************************** 243 Function to do the waiting before sending a local break. 244****************************************************************************/ 245 246static void wait_before_sending_break(void) 247{ 248 long wait_time = (long)lp_oplock_break_wait_time(); 249 250 if (wait_time) { 251 smb_msleep(wait_time); 252 } 253} 254 255/**************************************************************************** 256 Ensure that we have a valid oplock. 257****************************************************************************/ 258 259static files_struct *initial_break_processing(struct file_id id, unsigned long file_id) 260{ 261 files_struct *fsp = NULL; 262 263 if( DEBUGLVL( 3 ) ) { 264 dbgtext( "initial_break_processing: called for %s/%u\n", 265 file_id_string_tos(&id), (int)file_id); 266 dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n", 267 exclusive_oplocks_open, level_II_oplocks_open ); 268 } 269 270 /* 271 * We need to search the file open table for the 272 * entry containing this dev and inode, and ensure 273 * we have an oplock on it. 274 */ 275 276 fsp = file_find_dif(id, file_id); 277 278 if(fsp == NULL) { 279 /* The file could have been closed in the meantime - return success. */ 280 if( DEBUGLVL( 3 ) ) { 281 dbgtext( "initial_break_processing: cannot find open file with " ); 282 dbgtext( "file_id %s gen_id = %lu", file_id_string_tos(&id), file_id); 283 dbgtext( "allowing break to succeed.\n" ); 284 } 285 return NULL; 286 } 287 288 /* Ensure we have an oplock on the file */ 289 290 /* 291 * There is a potential race condition in that an oplock could 292 * have been broken due to another udp request, and yet there are 293 * still oplock break messages being sent in the udp message 294 * queue for this file. So return true if we don't have an oplock, 295 * as we may have just freed it. 296 */ 297 298 if(fsp->oplock_type == NO_OPLOCK) { 299 if( DEBUGLVL( 3 ) ) { 300 dbgtext( "initial_break_processing: file %s ", 301 fsp_str_dbg(fsp)); 302 dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n", 303 file_id_string_tos(&id), fsp->fh->gen_id ); 304 dbgtext( "Allowing break to succeed regardless.\n" ); 305 } 306 return NULL; 307 } 308 309 return fsp; 310} 311 312static void oplock_timeout_handler(struct event_context *ctx, 313 struct timed_event *te, 314 struct timeval now, 315 void *private_data) 316{ 317 files_struct *fsp = (files_struct *)private_data; 318 319 /* Remove the timed event handler. */ 320 TALLOC_FREE(fsp->oplock_timeout); 321 DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", 322 fsp_str_dbg(fsp))); 323 global_client_failed_oplock_break = True; 324 remove_oplock(fsp); 325 reply_to_oplock_break_requests(fsp); 326} 327 328/******************************************************************* 329 Add a timeout handler waiting for the client reply. 330*******************************************************************/ 331 332static void add_oplock_timeout_handler(files_struct *fsp) 333{ 334 /* 335 * If kernel oplocks already notifies smbds when an oplock break times 336 * out, just return. 337 */ 338 if (koplocks && 339 (koplocks->flags & KOPLOCKS_TIMEOUT_NOTIFICATION)) { 340 return; 341 } 342 343 if (fsp->oplock_timeout != NULL) { 344 DEBUG(0, ("Logic problem -- have an oplock event hanging " 345 "around\n")); 346 } 347 348 fsp->oplock_timeout = 349 event_add_timed(smbd_event_context(), NULL, 350 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0), 351 oplock_timeout_handler, fsp); 352 353 if (fsp->oplock_timeout == NULL) { 354 DEBUG(0, ("Could not add oplock timeout handler\n")); 355 } 356} 357 358void break_level2_to_none_async(files_struct *fsp) 359{ 360 char *break_msg; 361 362 if (fsp->oplock_type == NO_OPLOCK) { 363 /* We already got a "break to none" message and we've handled 364 * it. just ignore. */ 365 DEBUG(3, ("process_oplock_async_level2_break_message: already " 366 "broken to none, ignoring.\n")); 367 return; 368 } 369 370 if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) { 371 /* Don't tell the client, just downgrade. */ 372 DEBUG(3, ("process_oplock_async_level2_break_message: " 373 "downgrading fake level 2 oplock.\n")); 374 remove_oplock(fsp); 375 return; 376 } 377 378 /* Ensure we're really at level2 state. */ 379 SMB_ASSERT(fsp->oplock_type == LEVEL_II_OPLOCK); 380 381 DEBUG(10,("process_oplock_async_level2_break_message: sending break " 382 "to none message for fid %d, file %s\n", fsp->fnum, 383 fsp_str_dbg(fsp))); 384 385 /* 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); 400 401 /* Async level2 request, don't send a reply, just remove the oplock. */ 402 remove_oplock(fsp); 403 404} 405 406/******************************************************************* 407 This handles the case of a write triggering a break to none 408 message on a level2 oplock. 409 When we get this message we may be in any of three states : 410 NO_OPLOCK, LEVEL_II, FAKE_LEVEL2. We only send a message to 411 the client for LEVEL2. 412*******************************************************************/ 413 414void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx, 415 void *private_data, 416 uint32_t msg_type, 417 struct server_id src, 418 DATA_BLOB *data) 419{ 420 struct share_mode_entry msg; 421 files_struct *fsp; 422 423 if (data->data == NULL) { 424 DEBUG(0, ("Got NULL buffer\n")); 425 return; 426 } 427 428 if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 429 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length)); 430 return; 431 } 432 433 /* De-linearize incoming message. */ 434 message_to_share_mode_entry(&msg, (char *)data->data); 435 436 DEBUG(10, ("Got oplock async level 2 break message from pid %s: " 437 "%s/%lu\n", procid_str(talloc_tos(), &src), 438 file_id_string_tos(&msg.id), msg.share_file_id)); 439 440 fsp = initial_break_processing(msg.id, msg.share_file_id); 441 442 if (fsp == NULL) { 443 /* We hit a race here. Break messages are sent, and before we 444 * get to process this message, we have closed the file. 445 * No need to reply as this is an async message. */ 446 DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n")); 447 return; 448 } 449 450 break_level2_to_none_async(fsp); 451} 452 453/******************************************************************* 454 This handles the generic oplock break message from another smbd. 455*******************************************************************/ 456 457static void process_oplock_break_message(struct messaging_context *msg_ctx, 458 void *private_data, 459 uint32_t msg_type, 460 struct server_id src, 461 DATA_BLOB *data) 462{ 463 struct share_mode_entry msg; 464 files_struct *fsp; 465 char *break_msg; 466 bool break_to_level2 = False; 467 468 if (data->data == NULL) { 469 DEBUG(0, ("Got NULL buffer\n")); 470 return; 471 } 472 473 if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 474 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length)); 475 return; 476 } 477 478 /* De-linearize incoming message. */ 479 message_to_share_mode_entry(&msg, (char *)data->data); 480 481 DEBUG(10, ("Got oplock break message from pid %s: %s/%lu\n", 482 procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id), 483 msg.share_file_id)); 484 485 fsp = initial_break_processing(msg.id, msg.share_file_id); 486 487 if (fsp == NULL) { 488 /* a We hit race here. Break messages are sent, and before we 489 * get to process this message, we have closed the file. Reply 490 * with 'ok, oplock broken' */ 491 DEBUG(3, ("Did not find fsp\n")); 492 493 /* We just send the same message back. */ 494 messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE, 495 (uint8 *)data->data, 496 MSG_SMB_SHARE_MODE_ENTRY_SIZE); 497 return; 498 } 499 500 if (fsp->sent_oplock_break != NO_BREAK_SENT) { 501 /* Remember we have to inform the requesting PID when the 502 * client replies */ 503 msg.pid = src; 504 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg, 505 &fsp->pending_break_messages, 506 &fsp->num_pending_break_messages); 507 return; 508 } 509 510 if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) && 511 !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 512 DEBUG(3, ("Already downgraded oplock on %s: %s\n", 513 file_id_string_tos(&fsp->file_id), 514 fsp_str_dbg(fsp))); 515 /* We just send the same message back. */ 516 messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE, 517 (uint8 *)data->data, 518 MSG_SMB_SHARE_MODE_ENTRY_SIZE); 519 return; 520 } 521 522 if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && 523 !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) && 524 !(koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) && 525 lp_level2_oplocks(SNUM(fsp->conn))) { 526 break_to_level2 = True; 527 } 528 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. */ 536 if (procid_is_me(&src)) { 537 wait_before_sending_break(); 538 } 539 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); 549 550 fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; 551 552 msg.pid = src; 553 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg, 554 &fsp->pending_break_messages, 555 &fsp->num_pending_break_messages); 556 557 add_oplock_timeout_handler(fsp); 558} 559 560/******************************************************************* 561 This handles the kernel oplock break message. 562*******************************************************************/ 563 564static void process_kernel_oplock_break(struct messaging_context *msg_ctx, 565 void *private_data, 566 uint32_t msg_type, 567 struct server_id src, 568 DATA_BLOB *data) 569{ 570 struct file_id id; 571 unsigned long file_id; 572 files_struct *fsp; 573 char *break_msg; 574 575 if (data->data == NULL) { 576 DEBUG(0, ("Got NULL buffer\n")); 577 return; 578 } 579 580 if (data->length != MSG_SMB_KERNEL_BREAK_SIZE) { 581 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length)); 582 return; 583 } 584 585 /* Pull the data from the message. */ 586 pull_file_id_24((char *)data->data, &id); 587 file_id = (unsigned long)IVAL(data->data, 24); 588 589 DEBUG(10, ("Got kernel oplock break message from pid %s: %s/%u\n", 590 procid_str(talloc_tos(), &src), file_id_string_tos(&id), 591 (unsigned int)file_id)); 592 593 fsp = initial_break_processing(id, file_id); 594 595 if (fsp == NULL) { 596 DEBUG(3, ("Got a kernel oplock break message for a file " 597 "I don't know about\n")); 598 return; 599 } 600 601 if (fsp->sent_oplock_break != NO_BREAK_SENT) { 602 /* This is ok, kernel oplocks come in completely async */ 603 DEBUG(3, ("Got a kernel oplock request while waiting for a " 604 "break reply\n")); 605 return; 606 } 607 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); 622 623 fsp->sent_oplock_break = BREAK_TO_NONE_SENT; 624 625 add_oplock_timeout_handler(fsp); 626} 627 628void reply_to_oplock_break_requests(files_struct *fsp) 629{ 630 int i; 631 632 /* 633 * If kernel oplocks already notifies smbds when oplocks are 634 * broken/removed, just return. 635 */ 636 if (koplocks && 637 (koplocks->flags & KOPLOCKS_OPLOCK_BROKEN_NOTIFICATION)) { 638 return; 639 } 640 641 for (i=0; i<fsp->num_pending_break_messages; i++) { 642 struct share_mode_entry *e = &fsp->pending_break_messages[i]; 643 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 644 645 share_mode_entry_to_message(msg, e); 646 647 messaging_send_buf(smbd_messaging_context(), e->pid, 648 MSG_SMB_BREAK_RESPONSE, 649 (uint8 *)msg, 650 MSG_SMB_SHARE_MODE_ENTRY_SIZE); 651 } 652 653 SAFE_FREE(fsp->pending_break_messages); 654 fsp->num_pending_break_messages = 0; 655 if (fsp->oplock_timeout != NULL) { 656 /* Remove the timed event handler. */ 657 TALLOC_FREE(fsp->oplock_timeout); 658 fsp->oplock_timeout = NULL; 659 } 660 return; 661} 662 663static void process_oplock_break_response(struct messaging_context *msg_ctx, 664 void *private_data, 665 uint32_t msg_type, 666 struct server_id src, 667 DATA_BLOB *data) 668{ 669 struct share_mode_entry msg; 670 671 if (data->data == NULL) { 672 DEBUG(0, ("Got NULL buffer\n")); 673 return; 674 } 675 676 if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 677 DEBUG(0, ("Got invalid msg len %u\n", 678 (unsigned int)data->length)); 679 return; 680 } 681 682 /* De-linearize incoming message. */ 683 message_to_share_mode_entry(&msg, (char *)data->data); 684 685 DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid %u\n", 686 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); 691} 692 693static void process_open_retry_message(struct messaging_context *msg_ctx, 694 void *private_data, 695 uint32_t msg_type, 696 struct server_id src, 697 DATA_BLOB *data) 698{ 699 struct share_mode_entry msg; 700 701 if (data->data == NULL) { 702 DEBUG(0, ("Got NULL buffer\n")); 703 return; 704 } 705 706 if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 707 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length)); 708 return; 709 } 710 711 /* De-linearize incoming message. */ 712 message_to_share_mode_entry(&msg, (char *)data->data); 713 714 DEBUG(10, ("Got open retry msg from pid %s: %s mid %u\n", 715 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); 719} 720 721/**************************************************************************** 722 This function is called on any file modification or lock request. If a file 723 is level 2 oplocked then it must tell all other level 2 holders to break to 724 none. 725****************************************************************************/ 726 727static void contend_level2_oplocks_begin_default(files_struct *fsp, 728 enum level2_contention_type type) 729{ 730 int i; 731 struct share_mode_lock *lck; 732 733 /* 734 * If this file is level II oplocked then we need 735 * to grab the shared memory lock and inform all 736 * other files with a level II lock that they need 737 * to flush their read caches. We keep the lock over 738 * the shared memory area whilst doing this. 739 */ 740 741 if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) 742 return; 743 744 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, 745 NULL); 746 if (lck == NULL) { 747 DEBUG(0,("release_level_2_oplocks_on_change: failed to lock " 748 "share mode entry for file %s.\n", fsp_str_dbg(fsp))); 749 return; 750 } 751 752 DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n", 753 lck->num_share_modes )); 754 755 for(i = 0; i < lck->num_share_modes; i++) { 756 struct share_mode_entry *share_entry = &lck->share_modes[i]; 757 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 758 759 if (!is_valid_share_mode_entry(share_entry)) { 760 continue; 761 } 762 763 /* 764 * As there could have been multiple writes waiting at the 765 * lock_share_entry gate we may not be the first to 766 * enter. Hence the state of the op_types in the share mode 767 * entries may be partly NO_OPLOCK and partly LEVEL_II or FAKE_LEVEL_II 768 * oplock. It will do no harm to re-send break messages to 769 * those smbd's that are still waiting their turn to remove 770 * their LEVEL_II state, and also no harm to ignore existing 771 * NO_OPLOCK states. JRA. 772 */ 773 774 DEBUG(10,("release_level_2_oplocks_on_change: " 775 "share_entry[%i]->op_type == %d\n", 776 i, share_entry->op_type )); 777 778 if (share_entry->op_type == NO_OPLOCK) { 779 continue; 780 } 781 782 /* Paranoia .... */ 783 if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) { 784 DEBUG(0,("release_level_2_oplocks_on_change: PANIC. " 785 "share mode entry %d is an exlusive " 786 "oplock !\n", i )); 787 TALLOC_FREE(lck); 788 abort(); 789 } 790 791 share_mode_entry_to_message(msg, share_entry); 792 793 /* 794 * Deal with a race condition when breaking level2 795 * oplocks. Don't send all the messages and release 796 * the lock, this allows someone else to come in and 797 * get a level2 lock before any of the messages are 798 * processed, and thus miss getting a break message. 799 * Ensure at least one entry (the one we're breaking) 800 * is processed immediately under the lock and becomes 801 * set as NO_OPLOCK to stop any waiter getting a level2. 802 * Bugid #5980. 803 */ 804 805 if (procid_is_me(&share_entry->pid)) { 806 wait_before_sending_break(); 807 break_level2_to_none_async(fsp); 808 } else { 809 messaging_send_buf(smbd_messaging_context(), 810 share_entry->pid, 811 MSG_SMB_ASYNC_LEVEL2_BREAK, 812 (uint8 *)msg, 813 MSG_SMB_SHARE_MODE_ENTRY_SIZE); 814 } 815 } 816 817 /* We let the message receivers handle removing the oplock state 818 in the share mode lock db. */ 819 820 TALLOC_FREE(lck); 821} 822 823void contend_level2_oplocks_begin(files_struct *fsp, 824 enum level2_contention_type type) 825{ 826 if (koplocks && koplocks->ops->contend_level2_oplocks_begin) { 827 koplocks->ops->contend_level2_oplocks_begin(fsp, type); 828 return; 829 } 830 831 contend_level2_oplocks_begin_default(fsp, type); 832} 833 834void contend_level2_oplocks_end(files_struct *fsp, 835 enum level2_contention_type type) 836{ 837 /* Only kernel oplocks implement this so far */ 838 if (koplocks && koplocks->ops->contend_level2_oplocks_end) { 839 koplocks->ops->contend_level2_oplocks_end(fsp, type); 840 } 841} 842 843/**************************************************************************** 844 Linearize a share mode entry struct to an internal oplock break message. 845****************************************************************************/ 846 847void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e) 848{ 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 864} 865 866/**************************************************************************** 867 De-linearize an internal oplock break message to a share mode entry struct. 868****************************************************************************/ 869 870void message_to_share_mode_entry(struct share_mode_entry *e, char *msg) 871{ 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 887} 888 889/**************************************************************************** 890 Setup oplocks for this process. 891****************************************************************************/ 892 893bool init_oplocks(struct messaging_context *msg_ctx) 894{ 895 DEBUG(3,("init_oplocks: initializing messages.\n")); 896 897 messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_REQUEST, 898 process_oplock_break_message); 899 messaging_register(msg_ctx, NULL, MSG_SMB_ASYNC_LEVEL2_BREAK, 900 process_oplock_async_level2_break_message); 901 messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_RESPONSE, 902 process_oplock_break_response); 903 messaging_register(msg_ctx, NULL, MSG_SMB_KERNEL_BREAK, 904 process_kernel_oplock_break); 905 messaging_register(msg_ctx, NULL, MSG_SMB_OPEN_RETRY, 906 process_open_retry_message); 907 908 if (lp_kernel_oplocks()) { 909#if HAVE_KERNEL_OPLOCKS_IRIX 910 koplocks = irix_init_kernel_oplocks(talloc_autofree_context()); 911#elif HAVE_KERNEL_OPLOCKS_LINUX 912 koplocks = linux_init_kernel_oplocks(talloc_autofree_context()); 913#elif HAVE_ONEFS 914 koplocks = onefs_init_kernel_oplocks(talloc_autofree_context()); 915#endif 916 } 917 918 return True; 919} 920