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 2 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, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21*/ 22 23#define DBGC_CLASS DBGC_LOCKING 24#include "includes.h" 25 26/* Current number of oplocks we have outstanding. */ 27static int32 exclusive_oplocks_open = 0; 28static int32 level_II_oplocks_open = 0; 29BOOL global_client_failed_oplock_break = False; 30 31extern uint32 global_client_caps; 32extern int smb_read_error; 33 34static struct kernel_oplocks *koplocks; 35 36/**************************************************************************** 37 Get the number of current exclusive oplocks. 38****************************************************************************/ 39 40int32 get_number_of_exclusive_open_oplocks(void) 41{ 42 return exclusive_oplocks_open; 43} 44 45/**************************************************************************** 46 Return True if an oplock message is pending. 47****************************************************************************/ 48 49BOOL oplock_message_waiting(fd_set *fds) 50{ 51 if (koplocks && koplocks->msg_waiting(fds)) { 52 return True; 53 } 54 55 return False; 56} 57 58/**************************************************************************** 59 Find out if there are any kernel oplock messages waiting and process them 60 if so. pfds is the fd_set from the main select loop (which contains any 61 kernel oplock fd if that's what the system uses (IRIX). If may be NULL if 62 we're calling this in a shutting down state. 63****************************************************************************/ 64 65void process_kernel_oplocks(fd_set *pfds) 66{ 67 /* 68 * We need to check for kernel oplocks before going into the select 69 * here, as the EINTR generated by the linux kernel oplock may have 70 * already been eaten. JRA. 71 */ 72 73 if (!koplocks) { 74 return; 75 } 76 77 while (koplocks->msg_waiting(pfds)) { 78 files_struct *fsp; 79 char msg[MSG_SMB_KERNEL_BREAK_SIZE]; 80 81 fsp = koplocks->receive_message(pfds); 82 83 if (fsp == NULL) { 84 DEBUG(3, ("Kernel oplock message announced, but none " 85 "received\n")); 86 return; 87 } 88 89 /* Put the kernel break info into the message. */ 90 SDEV_T_VAL(msg,0,fsp->dev); 91 SINO_T_VAL(msg,8,fsp->inode); 92 SIVAL(msg,16,fsp->fh->file_id); 93 94 /* Don't need to be root here as we're only ever 95 sending to ourselves. */ 96 97 message_send_pid(pid_to_procid(sys_getpid()), 98 MSG_SMB_KERNEL_BREAK, 99 &msg, MSG_SMB_KERNEL_BREAK_SIZE, True); 100 } 101} 102 103/**************************************************************************** 104 Attempt to set an oplock on a file. Always succeeds if kernel oplocks are 105 disabled (just sets flags). Returns True if oplock set. 106****************************************************************************/ 107 108BOOL set_file_oplock(files_struct *fsp, int oplock_type) 109{ 110 if (koplocks && !koplocks->set_oplock(fsp, oplock_type)) { 111 return False; 112 } 113 114 fsp->oplock_type = oplock_type; 115 fsp->sent_oplock_break = NO_BREAK_SENT; 116 if (oplock_type == LEVEL_II_OPLOCK) { 117 level_II_oplocks_open++; 118 } else { 119 exclusive_oplocks_open++; 120 } 121 122 DEBUG(5,("set_file_oplock: granted oplock on file %s, 0x%x/%.0f/%lu, " 123 "tv_sec = %x, tv_usec = %x\n", 124 fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, 125 fsp->fh->file_id, (int)fsp->open_time.tv_sec, 126 (int)fsp->open_time.tv_usec )); 127 128 return True; 129} 130 131/**************************************************************************** 132 Attempt to release an oplock on a file. Decrements oplock count. 133****************************************************************************/ 134 135void release_file_oplock(files_struct *fsp) 136{ 137 if ((fsp->oplock_type != NO_OPLOCK) && 138 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && 139 koplocks) { 140 koplocks->release_oplock(fsp); 141 } 142 143 if (fsp->oplock_type == LEVEL_II_OPLOCK) { 144 level_II_oplocks_open--; 145 } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 146 exclusive_oplocks_open--; 147 } 148 149 SMB_ASSERT(exclusive_oplocks_open>=0); 150 SMB_ASSERT(level_II_oplocks_open>=0); 151 152 fsp->oplock_type = NO_OPLOCK; 153 fsp->sent_oplock_break = NO_BREAK_SENT; 154 155 flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH); 156 157 TALLOC_FREE(fsp->oplock_timeout); 158} 159 160/**************************************************************************** 161 Attempt to downgrade an oplock on a file. Doesn't decrement oplock count. 162****************************************************************************/ 163 164static void downgrade_file_oplock(files_struct *fsp) 165{ 166 if (koplocks) { 167 koplocks->release_oplock(fsp); 168 } 169 fsp->oplock_type = LEVEL_II_OPLOCK; 170 exclusive_oplocks_open--; 171 level_II_oplocks_open++; 172 fsp->sent_oplock_break = NO_BREAK_SENT; 173} 174 175/**************************************************************************** 176 Remove a file oplock. Copes with level II and exclusive. 177 Locks then unlocks the share mode lock. Client can decide to go directly 178 to none even if a "break-to-level II" was sent. 179****************************************************************************/ 180 181BOOL remove_oplock(files_struct *fsp) 182{ 183 SMB_DEV_T dev = fsp->dev; 184 SMB_INO_T inode = fsp->inode; 185 BOOL ret; 186 struct share_mode_lock *lck; 187 188 /* Remove the oplock flag from the sharemode. */ 189 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 190 if (lck == NULL) { 191 DEBUG(0,("remove_oplock: failed to lock share entry for " 192 "file %s\n", fsp->fsp_name )); 193 return False; 194 } 195 ret = remove_share_oplock(lck, fsp); 196 if (!ret) { 197 DEBUG(0,("remove_oplock: failed to remove share oplock for " 198 "file %s fnum %d, 0x%x/%.0f\n", 199 fsp->fsp_name, fsp->fnum, (unsigned int)dev, 200 (double)inode)); 201 } 202 release_file_oplock(fsp); 203 TALLOC_FREE(lck); 204 return ret; 205} 206 207/* 208 * Deal with a reply when a break-to-level II was sent. 209 */ 210BOOL downgrade_oplock(files_struct *fsp) 211{ 212 SMB_DEV_T dev = fsp->dev; 213 SMB_INO_T inode = fsp->inode; 214 BOOL ret; 215 struct share_mode_lock *lck; 216 217 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 218 if (lck == NULL) { 219 DEBUG(0,("downgrade_oplock: failed to lock share entry for " 220 "file %s\n", fsp->fsp_name )); 221 return False; 222 } 223 ret = downgrade_share_oplock(lck, fsp); 224 if (!ret) { 225 DEBUG(0,("downgrade_oplock: failed to downgrade share oplock " 226 "for file %s fnum %d, dev = %x, inode = %.0f\n", 227 fsp->fsp_name, fsp->fnum, (unsigned int)dev, 228 (double)inode)); 229 } 230 231 downgrade_file_oplock(fsp); 232 TALLOC_FREE(lck); 233 return ret; 234} 235 236/**************************************************************************** 237 Return the fd (if any) used for receiving oplock notifications. 238****************************************************************************/ 239 240int oplock_notify_fd(void) 241{ 242 if (koplocks) { 243 return koplocks->notification_fd; 244 } 245 246 return -1; 247} 248 249/**************************************************************************** 250 Set up an oplock break message. 251****************************************************************************/ 252 253static char *new_break_smb_message(TALLOC_CTX *mem_ctx, 254 files_struct *fsp, uint8 cmd) 255{ 256 char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0); 257 258 if (result == NULL) { 259 DEBUG(0, ("talloc failed\n")); 260 return NULL; 261 } 262 263 memset(result,'\0',smb_size); 264 set_message(result,8,0,True); 265 SCVAL(result,smb_com,SMBlockingX); 266 SSVAL(result,smb_tid,fsp->conn->cnum); 267 SSVAL(result,smb_pid,0xFFFF); 268 SSVAL(result,smb_uid,0); 269 SSVAL(result,smb_mid,0xFFFF); 270 SCVAL(result,smb_vwv0,0xFF); 271 SSVAL(result,smb_vwv2,fsp->fnum); 272 SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE); 273 SCVAL(result,smb_vwv3+1,cmd); 274 return result; 275} 276 277/**************************************************************************** 278 Function to do the waiting before sending a local break. 279****************************************************************************/ 280 281static void wait_before_sending_break(void) 282{ 283 long wait_time = (long)lp_oplock_break_wait_time(); 284 285 if (wait_time) { 286 smb_msleep(wait_time); 287 } 288} 289 290/**************************************************************************** 291 Ensure that we have a valid oplock. 292****************************************************************************/ 293 294static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id) 295{ 296 files_struct *fsp = NULL; 297 298 if( DEBUGLVL( 3 ) ) { 299 dbgtext( "initial_break_processing: called for 0x%x/%.0f/%u\n", 300 (unsigned int)dev, (double)inode, (int)file_id); 301 dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n", 302 exclusive_oplocks_open, level_II_oplocks_open ); 303 } 304 305 /* 306 * We need to search the file open table for the 307 * entry containing this dev and inode, and ensure 308 * we have an oplock on it. 309 */ 310 311 fsp = file_find_dif(dev, inode, file_id); 312 313 if(fsp == NULL) { 314 /* The file could have been closed in the meantime - return success. */ 315 if( DEBUGLVL( 3 ) ) { 316 dbgtext( "initial_break_processing: cannot find open file with " ); 317 dbgtext( "dev = 0x%x, inode = %.0f file_id = %lu", (unsigned int)dev, 318 (double)inode, file_id); 319 dbgtext( "allowing break to succeed.\n" ); 320 } 321 return NULL; 322 } 323 324 /* Ensure we have an oplock on the file */ 325 326 /* 327 * There is a potential race condition in that an oplock could 328 * have been broken due to another udp request, and yet there are 329 * still oplock break messages being sent in the udp message 330 * queue for this file. So return true if we don't have an oplock, 331 * as we may have just freed it. 332 */ 333 334 if(fsp->oplock_type == NO_OPLOCK) { 335 if( DEBUGLVL( 3 ) ) { 336 dbgtext( "initial_break_processing: file %s ", fsp->fsp_name ); 337 dbgtext( "(dev = %x, inode = %.0f, file_id = %lu) has no oplock.\n", 338 (unsigned int)dev, (double)inode, fsp->fh->file_id ); 339 dbgtext( "Allowing break to succeed regardless.\n" ); 340 } 341 return NULL; 342 } 343 344 return fsp; 345} 346 347static void oplock_timeout_handler(struct event_context *ctx, 348 struct timed_event *te, 349 const struct timeval *now, 350 void *private_data) 351{ 352 files_struct *fsp = (files_struct *)private_data; 353 354 /* Remove the timed event handler. */ 355 TALLOC_FREE(fsp->oplock_timeout); 356 DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name)); 357 global_client_failed_oplock_break = True; 358 remove_oplock(fsp); 359 reply_to_oplock_break_requests(fsp); 360} 361 362/******************************************************************* 363 Add a timeout handler waiting for the client reply. 364*******************************************************************/ 365 366static void add_oplock_timeout_handler(files_struct *fsp) 367{ 368 if (fsp->oplock_timeout != NULL) { 369 DEBUG(0, ("Logic problem -- have an oplock event hanging " 370 "around\n")); 371 } 372 373 fsp->oplock_timeout = 374 event_add_timed(smbd_event_context(), NULL, 375 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0), 376 "oplock_timeout_handler", 377 oplock_timeout_handler, fsp); 378 379 if (fsp->oplock_timeout == NULL) { 380 DEBUG(0, ("Could not add oplock timeout handler\n")); 381 } 382} 383 384/******************************************************************* 385 This handles the case of a write triggering a break to none 386 message on a level2 oplock. 387 When we get this message we may be in any of three states : 388 NO_OPLOCK, LEVEL_II, FAKE_LEVEL2. We only send a message to 389 the client for LEVEL2. 390*******************************************************************/ 391 392static void process_oplock_async_level2_break_message(int msg_type, struct process_id src, 393 void *buf, size_t len, 394 void *private_data) 395{ 396 struct share_mode_entry msg; 397 files_struct *fsp; 398 char *break_msg; 399 BOOL sign_state; 400 401 if (buf == NULL) { 402 DEBUG(0, ("Got NULL buffer\n")); 403 return; 404 } 405 406 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 407 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 408 return; 409 } 410 411 /* De-linearize incoming message. */ 412 message_to_share_mode_entry(&msg, (char *)buf); 413 414 DEBUG(10, ("Got oplock async level 2 break message from pid %d: 0x%x/%.0f/%lu\n", 415 (int)procid_to_pid(&src), (unsigned int)msg.dev, 416 (double)msg.inode, msg.share_file_id)); 417 418 fsp = initial_break_processing(msg.dev, msg.inode, 419 msg.share_file_id); 420 421 if (fsp == NULL) { 422 /* We hit a race here. Break messages are sent, and before we 423 * get to process this message, we have closed the file. 424 * No need to reply as this is an async message. */ 425 DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n")); 426 return; 427 } 428 429 if (fsp->oplock_type == NO_OPLOCK) { 430 /* We already got a "break to none" message and we've handled it. 431 * just ignore. */ 432 DEBUG(3, ("process_oplock_async_level2_break_message: already broken to none, ignoring.\n")); 433 return; 434 } 435 436 if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) { 437 /* Don't tell the client, just downgrade. */ 438 DEBUG(3, ("process_oplock_async_level2_break_message: downgrading fake level 2 oplock.\n")); 439 remove_oplock(fsp); 440 return; 441 } 442 443 /* Ensure we're really at level2 state. */ 444 SMB_ASSERT(fsp->oplock_type == LEVEL_II_OPLOCK); 445 446 /* Now send a break to none message to our client. */ 447 448 break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); 449 if (break_msg == NULL) { 450 exit_server("Could not talloc break_msg\n"); 451 } 452 453 /* Need to wait before sending a break message if we sent ourselves this message. */ 454 if (procid_to_pid(&src) == sys_getpid()) { 455 wait_before_sending_break(); 456 } 457 458 /* Save the server smb signing state. */ 459 sign_state = srv_oplock_set_signing(False); 460 461 show_msg(break_msg); 462 if (!send_smb(smbd_server_fd(), break_msg)) { 463 exit_server_cleanly("oplock_break: send_smb failed."); 464 } 465 466 /* Restore the sign state to what it was. */ 467 srv_oplock_set_signing(sign_state); 468 469 TALLOC_FREE(break_msg); 470 471 /* Async level2 request, don't send a reply, just remove the oplock. */ 472 remove_oplock(fsp); 473} 474 475/******************************************************************* 476 This handles the generic oplock break message from another smbd. 477*******************************************************************/ 478 479static void process_oplock_break_message(int msg_type, struct process_id src, 480 void *buf, size_t len, 481 void *private_data) 482{ 483 struct share_mode_entry msg; 484 files_struct *fsp; 485 char *break_msg; 486 BOOL break_to_level2 = False; 487 BOOL sign_state; 488 489 if (buf == NULL) { 490 DEBUG(0, ("Got NULL buffer\n")); 491 return; 492 } 493 494 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 495 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 496 return; 497 } 498 499 /* De-linearize incoming message. */ 500 message_to_share_mode_entry(&msg, (char *)buf); 501 502 DEBUG(10, ("Got oplock break message from pid %d: 0x%x/%.0f/%lu\n", 503 (int)procid_to_pid(&src), (unsigned int)msg.dev, 504 (double)msg.inode, msg.share_file_id)); 505 506 fsp = initial_break_processing(msg.dev, msg.inode, 507 msg.share_file_id); 508 509 if (fsp == NULL) { 510 /* a We hit race here. Break messages are sent, and before we 511 * get to process this message, we have closed the file. Reply 512 * with 'ok, oplock broken' */ 513 DEBUG(3, ("Did not find fsp\n")); 514 515 /* We just send the same message back. */ 516 message_send_pid(src, MSG_SMB_BREAK_RESPONSE, 517 buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 518 return; 519 } 520 521 if (fsp->sent_oplock_break != NO_BREAK_SENT) { 522 /* Remember we have to inform the requesting PID when the 523 * client replies */ 524 msg.pid = src; 525 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg, 526 &fsp->pending_break_messages, 527 &fsp->num_pending_break_messages); 528 return; 529 } 530 531 if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) && 532 !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 533 DEBUG(3, ("Already downgraded oplock on 0x%x/%.0f: %s\n", 534 (unsigned int)fsp->dev, (double)fsp->inode, 535 fsp->fsp_name)); 536 /* We just send the same message back. */ 537 message_send_pid(src, MSG_SMB_BREAK_RESPONSE, 538 buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 539 return; 540 } 541 542 if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && 543 !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) && 544 !koplocks && /* NOTE: we force levelII off for kernel oplocks - 545 * this will change when it is supported */ 546 lp_level2_oplocks(SNUM(fsp->conn))) { 547 break_to_level2 = True; 548 } 549 550 break_msg = new_break_smb_message(NULL, fsp, break_to_level2 ? 551 OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); 552 if (break_msg == NULL) { 553 exit_server("Could not talloc break_msg\n"); 554 } 555 556 /* Need to wait before sending a break message if we sent ourselves this message. */ 557 if (procid_to_pid(&src) == sys_getpid()) { 558 wait_before_sending_break(); 559 } 560 561 /* Save the server smb signing state. */ 562 sign_state = srv_oplock_set_signing(False); 563 564 show_msg(break_msg); 565 if (!send_smb(smbd_server_fd(), break_msg)) { 566 exit_server_cleanly("oplock_break: send_smb failed."); 567 } 568 569 /* Restore the sign state to what it was. */ 570 srv_oplock_set_signing(sign_state); 571 572 TALLOC_FREE(break_msg); 573 574 fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; 575 576 msg.pid = src; 577 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg, 578 &fsp->pending_break_messages, 579 &fsp->num_pending_break_messages); 580 581 add_oplock_timeout_handler(fsp); 582} 583 584/******************************************************************* 585 This handles the kernel oplock break message. 586*******************************************************************/ 587 588static void process_kernel_oplock_break(int msg_type, struct process_id src, 589 void *buf, size_t len, 590 void *private_data) 591{ 592 SMB_DEV_T dev; 593 SMB_INO_T inode; 594 unsigned long file_id; 595 files_struct *fsp; 596 char *break_msg; 597 BOOL sign_state; 598 599 if (buf == NULL) { 600 DEBUG(0, ("Got NULL buffer\n")); 601 return; 602 } 603 604 if (len != MSG_SMB_KERNEL_BREAK_SIZE) { 605 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 606 return; 607 } 608 609 /* Pull the data from the message. */ 610 dev = DEV_T_VAL(buf, 0); 611 inode = INO_T_VAL(buf, 8); 612 file_id = (unsigned long)IVAL(buf, 16); 613 614 DEBUG(10, ("Got kernel oplock break message from pid %d: 0x%x/%.0f/%u\n", 615 (int)procid_to_pid(&src), (unsigned int)dev, (double)inode, 616 (unsigned int)file_id)); 617 618 fsp = initial_break_processing(dev, inode, file_id); 619 620 if (fsp == NULL) { 621 DEBUG(3, ("Got a kernel oplock break message for a file " 622 "I don't know about\n")); 623 return; 624 } 625 626 if (fsp->sent_oplock_break != NO_BREAK_SENT) { 627 /* This is ok, kernel oplocks come in completely async */ 628 DEBUG(3, ("Got a kernel oplock request while waiting for a " 629 "break reply\n")); 630 return; 631 } 632 633 break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); 634 if (break_msg == NULL) { 635 exit_server("Could not talloc break_msg\n"); 636 } 637 638 /* Save the server smb signing state. */ 639 sign_state = srv_oplock_set_signing(False); 640 641 show_msg(break_msg); 642 if (!send_smb(smbd_server_fd(), break_msg)) { 643 exit_server_cleanly("oplock_break: send_smb failed."); 644 } 645 646 /* Restore the sign state to what it was. */ 647 srv_oplock_set_signing(sign_state); 648 649 TALLOC_FREE(break_msg); 650 651 fsp->sent_oplock_break = BREAK_TO_NONE_SENT; 652 653 add_oplock_timeout_handler(fsp); 654} 655 656void reply_to_oplock_break_requests(files_struct *fsp) 657{ 658 int i; 659 660 for (i=0; i<fsp->num_pending_break_messages; i++) { 661 struct share_mode_entry *e = &fsp->pending_break_messages[i]; 662 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 663 664 share_mode_entry_to_message(msg, e); 665 666 message_send_pid(e->pid, MSG_SMB_BREAK_RESPONSE, 667 msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 668 } 669 670 SAFE_FREE(fsp->pending_break_messages); 671 fsp->num_pending_break_messages = 0; 672 if (fsp->oplock_timeout != NULL) { 673 /* Remove the timed event handler. */ 674 TALLOC_FREE(fsp->oplock_timeout); 675 fsp->oplock_timeout = NULL; 676 } 677 return; 678} 679 680static void process_oplock_break_response(int msg_type, struct process_id src, 681 void *buf, size_t len, 682 void *private_data) 683{ 684 struct share_mode_entry msg; 685 686 if (buf == NULL) { 687 DEBUG(0, ("Got NULL buffer\n")); 688 return; 689 } 690 691 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 692 DEBUG(0, ("Got invalid msg len %u\n", (unsigned int)len)); 693 return; 694 } 695 696 /* De-linearize incoming message. */ 697 message_to_share_mode_entry(&msg, (char *)buf); 698 699 DEBUG(10, ("Got oplock break response from pid %d: 0x%x/%.0f/%lu mid %u\n", 700 (int)procid_to_pid(&src), (unsigned int)msg.dev, 701 (double)msg.inode, msg.share_file_id, 702 (unsigned int)msg.op_mid)); 703 704 /* Here's the hack from open.c, store the mid in the 'port' field */ 705 schedule_deferred_open_smb_message(msg.op_mid); 706} 707 708static void process_open_retry_message(int msg_type, struct process_id src, 709 void *buf, size_t len, 710 void *private_data) 711{ 712 struct share_mode_entry msg; 713 714 if (buf == NULL) { 715 DEBUG(0, ("Got NULL buffer\n")); 716 return; 717 } 718 719 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 720 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 721 return; 722 } 723 724 /* De-linearize incoming message. */ 725 message_to_share_mode_entry(&msg, (char *)buf); 726 727 DEBUG(10, ("Got open retry msg from pid %d: 0x%x/%.0f/%lu mid %u\n", 728 (int)procid_to_pid(&src), (unsigned int)msg.dev, 729 (double)msg.inode, msg.share_file_id, 730 (unsigned int)msg.op_mid)); 731 732 schedule_deferred_open_smb_message(msg.op_mid); 733} 734 735/**************************************************************************** 736 This function is called on any file modification or lock request. If a file 737 is level 2 oplocked then it must tell all other level 2 holders to break to 738 none. 739****************************************************************************/ 740 741void release_level_2_oplocks_on_change(files_struct *fsp) 742{ 743 int i; 744 struct share_mode_lock *lck; 745 746 /* 747 * If this file is level II oplocked then we need 748 * to grab the shared memory lock and inform all 749 * other files with a level II lock that they need 750 * to flush their read caches. We keep the lock over 751 * the shared memory area whilst doing this. 752 */ 753 754 if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) 755 return; 756 757 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 758 if (lck == NULL) { 759 DEBUG(0,("release_level_2_oplocks_on_change: failed to lock " 760 "share mode entry for file %s.\n", fsp->fsp_name )); 761 return; 762 } 763 764 DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n", 765 lck->num_share_modes )); 766 767 for(i = 0; i < lck->num_share_modes; i++) { 768 struct share_mode_entry *share_entry = &lck->share_modes[i]; 769 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 770 771 if (!is_valid_share_mode_entry(share_entry)) { 772 continue; 773 } 774 775 /* 776 * As there could have been multiple writes waiting at the 777 * lock_share_entry gate we may not be the first to 778 * enter. Hence the state of the op_types in the share mode 779 * entries may be partly NO_OPLOCK and partly LEVEL_II or FAKE_LEVEL_II 780 * oplock. It will do no harm to re-send break messages to 781 * those smbd's that are still waiting their turn to remove 782 * their LEVEL_II state, and also no harm to ignore existing 783 * NO_OPLOCK states. JRA. 784 */ 785 786 DEBUG(10,("release_level_2_oplocks_on_change: " 787 "share_entry[%i]->op_type == %d\n", 788 i, share_entry->op_type )); 789 790 if (share_entry->op_type == NO_OPLOCK) { 791 continue; 792 } 793 794 /* Paranoia .... */ 795 if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) { 796 DEBUG(0,("release_level_2_oplocks_on_change: PANIC. " 797 "share mode entry %d is an exlusive " 798 "oplock !\n", i )); 799 TALLOC_FREE(lck); 800 abort(); 801 } 802 803 share_mode_entry_to_message(msg, share_entry); 804 805 message_send_pid(share_entry->pid, MSG_SMB_ASYNC_LEVEL2_BREAK, 806 msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 807 } 808 809 /* We let the message receivers handle removing the oplock state 810 in the share mode lock db. */ 811 812 TALLOC_FREE(lck); 813} 814 815/**************************************************************************** 816 Linearize a share mode entry struct to an internal oplock break message. 817****************************************************************************/ 818 819void share_mode_entry_to_message(char *msg, struct share_mode_entry *e) 820{ 821 SIVAL(msg,0,(uint32)e->pid.pid); 822 SSVAL(msg,4,e->op_mid); 823 SSVAL(msg,6,e->op_type); 824 SIVAL(msg,8,e->access_mask); 825 SIVAL(msg,12,e->share_access); 826 SIVAL(msg,16,e->private_options); 827 SIVAL(msg,20,(uint32)e->time.tv_sec); 828 SIVAL(msg,24,(uint32)e->time.tv_usec); 829 SDEV_T_VAL(msg,28,e->dev); 830 SINO_T_VAL(msg,36,e->inode); 831 SIVAL(msg,44,e->share_file_id); 832 SIVAL(msg,48,e->uid); 833 SSVAL(msg,52,e->flags); 834} 835 836/**************************************************************************** 837 De-linearize an internal oplock break message to a share mode entry struct. 838****************************************************************************/ 839 840void message_to_share_mode_entry(struct share_mode_entry *e, char *msg) 841{ 842 e->pid.pid = (pid_t)IVAL(msg,0); 843 e->op_mid = SVAL(msg,4); 844 e->op_type = SVAL(msg,6); 845 e->access_mask = IVAL(msg,8); 846 e->share_access = IVAL(msg,12); 847 e->private_options = IVAL(msg,16); 848 e->time.tv_sec = (time_t)IVAL(msg,20); 849 e->time.tv_usec = (int)IVAL(msg,24); 850 e->dev = DEV_T_VAL(msg,28); 851 e->inode = INO_T_VAL(msg,36); 852 e->share_file_id = (unsigned long)IVAL(msg,44); 853 e->uid = (uint32)IVAL(msg,48); 854 e->flags = (uint16)SVAL(msg,52); 855} 856 857/**************************************************************************** 858 Setup oplocks for this process. 859****************************************************************************/ 860 861BOOL init_oplocks(void) 862{ 863 DEBUG(3,("init_oplocks: initializing messages.\n")); 864 865 message_register(MSG_SMB_BREAK_REQUEST, 866 process_oplock_break_message, 867 NULL); 868 message_register(MSG_SMB_ASYNC_LEVEL2_BREAK, 869 process_oplock_async_level2_break_message, 870 NULL); 871 message_register(MSG_SMB_BREAK_RESPONSE, 872 process_oplock_break_response, 873 NULL); 874 message_register(MSG_SMB_KERNEL_BREAK, 875 process_kernel_oplock_break, 876 NULL); 877 message_register(MSG_SMB_OPEN_RETRY, 878 process_open_retry_message, 879 NULL); 880 881 if (lp_kernel_oplocks()) { 882#if HAVE_KERNEL_OPLOCKS_IRIX 883 koplocks = irix_init_kernel_oplocks(); 884#elif HAVE_KERNEL_OPLOCKS_LINUX 885 koplocks = linux_init_kernel_oplocks(); 886#endif 887 } 888 889 return True; 890} 891