int32 get_number_of_exclusive_open_oplocks | ( | void | ) |
BOOL oplock_message_waiting | ( | fd_set * | fds | ) |
参照先 koplocks・kernel_oplocks::msg_waiting.
00050 { 00051 if (koplocks && koplocks->msg_waiting(fds)) { 00052 return True; 00053 } 00054 00055 return False; 00056 }
void process_kernel_oplocks | ( | fd_set * | pfds | ) |
参照先 koplocks・message_send_pid()・kernel_oplocks::msg_waiting・pid_to_procid()・kernel_oplocks::receive_message・sys_getpid().
参照元 async_processing()・respond_to_all_remaining_local_messages().
00066 { 00067 /* 00068 * We need to check for kernel oplocks before going into the select 00069 * here, as the EINTR generated by the linux kernel oplock may have 00070 * already been eaten. JRA. 00071 */ 00072 00073 if (!koplocks) { 00074 return; 00075 } 00076 00077 while (koplocks->msg_waiting(pfds)) { 00078 files_struct *fsp; 00079 char msg[MSG_SMB_KERNEL_BREAK_SIZE]; 00080 00081 fsp = koplocks->receive_message(pfds); 00082 00083 if (fsp == NULL) { 00084 DEBUG(3, ("Kernel oplock message announced, but none " 00085 "received\n")); 00086 return; 00087 } 00088 00089 /* Put the kernel break info into the message. */ 00090 SDEV_T_VAL(msg,0,fsp->dev); 00091 SINO_T_VAL(msg,8,fsp->inode); 00092 SIVAL(msg,16,fsp->fh->file_id); 00093 00094 /* Don't need to be root here as we're only ever 00095 sending to ourselves. */ 00096 00097 message_send_pid(pid_to_procid(sys_getpid()), 00098 MSG_SMB_KERNEL_BREAK, 00099 &msg, MSG_SMB_KERNEL_BREAK_SIZE, True); 00100 } 00101 }
BOOL set_file_oplock | ( | files_struct * | fsp, | |
int | oplock_type | |||
) |
参照先 files_struct::dev・exclusive_oplocks_open・files_struct::fh・fd_handle::file_id・files_struct::fsp_name・files_struct::inode・koplocks・level_II_oplocks_open・files_struct::open_time・files_struct::oplock_type・files_struct::sent_oplock_break・kernel_oplocks::set_oplock.
参照元 open_file_ntcreate().
00109 { 00110 if (koplocks && !koplocks->set_oplock(fsp, oplock_type)) { 00111 return False; 00112 } 00113 00114 fsp->oplock_type = oplock_type; 00115 fsp->sent_oplock_break = NO_BREAK_SENT; 00116 if (oplock_type == LEVEL_II_OPLOCK) { 00117 level_II_oplocks_open++; 00118 } else { 00119 exclusive_oplocks_open++; 00120 } 00121 00122 DEBUG(5,("set_file_oplock: granted oplock on file %s, 0x%x/%.0f/%lu, " 00123 "tv_sec = %x, tv_usec = %x\n", 00124 fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, 00125 fsp->fh->file_id, (int)fsp->open_time.tv_sec, 00126 (int)fsp->open_time.tv_usec )); 00127 00128 return True; 00129 }
void release_file_oplock | ( | files_struct * | fsp | ) |
参照先 exclusive_oplocks_open・flush_write_cache()・koplocks・level_II_oplocks_open・files_struct::oplock_timeout・files_struct::oplock_type・kernel_oplocks::release_oplock・files_struct::sent_oplock_break.
参照元 close_normal_file()・remove_oplock().
00136 { 00137 if ((fsp->oplock_type != NO_OPLOCK) && 00138 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && 00139 koplocks) { 00140 koplocks->release_oplock(fsp); 00141 } 00142 00143 if (fsp->oplock_type == LEVEL_II_OPLOCK) { 00144 level_II_oplocks_open--; 00145 } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 00146 exclusive_oplocks_open--; 00147 } 00148 00149 SMB_ASSERT(exclusive_oplocks_open>=0); 00150 SMB_ASSERT(level_II_oplocks_open>=0); 00151 00152 fsp->oplock_type = NO_OPLOCK; 00153 fsp->sent_oplock_break = NO_BREAK_SENT; 00154 00155 flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH); 00156 00157 TALLOC_FREE(fsp->oplock_timeout); 00158 }
static void downgrade_file_oplock | ( | files_struct * | fsp | ) | [static] |
参照先 exclusive_oplocks_open・koplocks・level_II_oplocks_open・files_struct::oplock_type・kernel_oplocks::release_oplock・files_struct::sent_oplock_break.
参照元 downgrade_oplock().
00165 { 00166 if (koplocks) { 00167 koplocks->release_oplock(fsp); 00168 } 00169 fsp->oplock_type = LEVEL_II_OPLOCK; 00170 exclusive_oplocks_open--; 00171 level_II_oplocks_open++; 00172 fsp->sent_oplock_break = NO_BREAK_SENT; 00173 }
BOOL remove_oplock | ( | files_struct * | fsp | ) |
参照先 files_struct::dev・dev・files_struct::fnum・files_struct::fsp_name・get_share_mode_lock()・files_struct::inode・inode・release_file_oplock()・remove_share_oplock().
参照元 oplock_timeout_handler()・process_oplock_async_level2_break_message()・reply_lockingX().
00182 { 00183 SMB_DEV_T dev = fsp->dev; 00184 SMB_INO_T inode = fsp->inode; 00185 BOOL ret; 00186 struct share_mode_lock *lck; 00187 00188 /* Remove the oplock flag from the sharemode. */ 00189 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 00190 if (lck == NULL) { 00191 DEBUG(0,("remove_oplock: failed to lock share entry for " 00192 "file %s\n", fsp->fsp_name )); 00193 return False; 00194 } 00195 ret = remove_share_oplock(lck, fsp); 00196 if (!ret) { 00197 DEBUG(0,("remove_oplock: failed to remove share oplock for " 00198 "file %s fnum %d, 0x%x/%.0f\n", 00199 fsp->fsp_name, fsp->fnum, (unsigned int)dev, 00200 (double)inode)); 00201 } 00202 release_file_oplock(fsp); 00203 TALLOC_FREE(lck); 00204 return ret; 00205 }
BOOL downgrade_oplock | ( | files_struct * | fsp | ) |
参照先 files_struct::dev・dev・downgrade_file_oplock()・downgrade_share_oplock()・files_struct::fnum・files_struct::fsp_name・get_share_mode_lock()・files_struct::inode・inode.
参照元 reply_lockingX().
00211 { 00212 SMB_DEV_T dev = fsp->dev; 00213 SMB_INO_T inode = fsp->inode; 00214 BOOL ret; 00215 struct share_mode_lock *lck; 00216 00217 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 00218 if (lck == NULL) { 00219 DEBUG(0,("downgrade_oplock: failed to lock share entry for " 00220 "file %s\n", fsp->fsp_name )); 00221 return False; 00222 } 00223 ret = downgrade_share_oplock(lck, fsp); 00224 if (!ret) { 00225 DEBUG(0,("downgrade_oplock: failed to downgrade share oplock " 00226 "for file %s fnum %d, dev = %x, inode = %.0f\n", 00227 fsp->fsp_name, fsp->fnum, (unsigned int)dev, 00228 (double)inode)); 00229 } 00230 00231 downgrade_file_oplock(fsp); 00232 TALLOC_FREE(lck); 00233 return ret; 00234 }
int oplock_notify_fd | ( | void | ) |
参照先 koplocks・kernel_oplocks::notification_fd.
00241 { 00242 if (koplocks) { 00243 return koplocks->notification_fd; 00244 } 00245 00246 return -1; 00247 }
static char* new_break_smb_message | ( | TALLOC_CTX * | mem_ctx, | |
files_struct * | fsp, | |||
uint8 | cmd | |||
) | [static] |
参照先 connection_struct::cnum・files_struct::conn・files_struct::fnum・result・set_message().
参照元 process_kernel_oplock_break()・process_oplock_async_level2_break_message()・process_oplock_break_message().
00255 { 00256 char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0); 00257 00258 if (result == NULL) { 00259 DEBUG(0, ("talloc failed\n")); 00260 return NULL; 00261 } 00262 00263 memset(result,'\0',smb_size); 00264 set_message(result,8,0,True); 00265 SCVAL(result,smb_com,SMBlockingX); 00266 SSVAL(result,smb_tid,fsp->conn->cnum); 00267 SSVAL(result,smb_pid,0xFFFF); 00268 SSVAL(result,smb_uid,0); 00269 SSVAL(result,smb_mid,0xFFFF); 00270 SCVAL(result,smb_vwv0,0xFF); 00271 SSVAL(result,smb_vwv2,fsp->fnum); 00272 SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE); 00273 SCVAL(result,smb_vwv3+1,cmd); 00274 return result; 00275 }
static void wait_before_sending_break | ( | void | ) | [static] |
参照先 smb_msleep().
参照元 process_oplock_async_level2_break_message()・process_oplock_break_message().
00282 { 00283 long wait_time = (long)lp_oplock_break_wait_time(); 00284 00285 if (wait_time) { 00286 smb_msleep(wait_time); 00287 } 00288 }
static files_struct* initial_break_processing | ( | SMB_DEV_T | dev, | |
SMB_INO_T | inode, | |||
unsigned long | file_id | |||
) | [static] |
参照先 dbgtext()・exclusive_oplocks_open・files_struct::fh・file_find_dif()・fd_handle::file_id・files_struct::fsp_name・level_II_oplocks_open・files_struct::oplock_type.
参照元 process_kernel_oplock_break()・process_oplock_async_level2_break_message()・process_oplock_break_message().
00295 { 00296 files_struct *fsp = NULL; 00297 00298 if( DEBUGLVL( 3 ) ) { 00299 dbgtext( "initial_break_processing: called for 0x%x/%.0f/%u\n", 00300 (unsigned int)dev, (double)inode, (int)file_id); 00301 dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n", 00302 exclusive_oplocks_open, level_II_oplocks_open ); 00303 } 00304 00305 /* 00306 * We need to search the file open table for the 00307 * entry containing this dev and inode, and ensure 00308 * we have an oplock on it. 00309 */ 00310 00311 fsp = file_find_dif(dev, inode, file_id); 00312 00313 if(fsp == NULL) { 00314 /* The file could have been closed in the meantime - return success. */ 00315 if( DEBUGLVL( 3 ) ) { 00316 dbgtext( "initial_break_processing: cannot find open file with " ); 00317 dbgtext( "dev = 0x%x, inode = %.0f file_id = %lu", (unsigned int)dev, 00318 (double)inode, file_id); 00319 dbgtext( "allowing break to succeed.\n" ); 00320 } 00321 return NULL; 00322 } 00323 00324 /* Ensure we have an oplock on the file */ 00325 00326 /* 00327 * There is a potential race condition in that an oplock could 00328 * have been broken due to another udp request, and yet there are 00329 * still oplock break messages being sent in the udp message 00330 * queue for this file. So return true if we don't have an oplock, 00331 * as we may have just freed it. 00332 */ 00333 00334 if(fsp->oplock_type == NO_OPLOCK) { 00335 if( DEBUGLVL( 3 ) ) { 00336 dbgtext( "initial_break_processing: file %s ", fsp->fsp_name ); 00337 dbgtext( "(dev = %x, inode = %.0f, file_id = %lu) has no oplock.\n", 00338 (unsigned int)dev, (double)inode, fsp->fh->file_id ); 00339 dbgtext( "Allowing break to succeed regardless.\n" ); 00340 } 00341 return NULL; 00342 } 00343 00344 return fsp; 00345 }
static void oplock_timeout_handler | ( | struct event_context * | ctx, | |
struct timed_event * | te, | |||
const struct timeval * | now, | |||
void * | private_data | |||
) | [static] |
参照先 files_struct::fsp_name・global_client_failed_oplock_break・files_struct::oplock_timeout・remove_oplock()・reply_to_oplock_break_requests().
参照元 add_oplock_timeout_handler().
00351 { 00352 files_struct *fsp = (files_struct *)private_data; 00353 00354 /* Remove the timed event handler. */ 00355 TALLOC_FREE(fsp->oplock_timeout); 00356 DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name)); 00357 global_client_failed_oplock_break = True; 00358 remove_oplock(fsp); 00359 reply_to_oplock_break_requests(fsp); 00360 }
static void add_oplock_timeout_handler | ( | files_struct * | fsp | ) | [static] |
参照先 event_add_timed()・files_struct::oplock_timeout・oplock_timeout_handler()・smbd_event_context()・timeval_current_ofs().
参照元 process_kernel_oplock_break()・process_oplock_break_message().
00367 { 00368 if (fsp->oplock_timeout != NULL) { 00369 DEBUG(0, ("Logic problem -- have an oplock event hanging " 00370 "around\n")); 00371 } 00372 00373 fsp->oplock_timeout = 00374 event_add_timed(smbd_event_context(), NULL, 00375 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0), 00376 "oplock_timeout_handler", 00377 oplock_timeout_handler, fsp); 00378 00379 if (fsp->oplock_timeout == NULL) { 00380 DEBUG(0, ("Could not add oplock timeout handler\n")); 00381 } 00382 }
static void process_oplock_async_level2_break_message | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
参照先 share_mode_entry::dev・exit_server()・exit_server_cleanly()・initial_break_processing()・share_mode_entry::inode・message_to_share_mode_entry()・new_break_smb_message()・procid_to_pid()・remove_oplock()・send_smb()・share_mode_entry::share_file_id・show_msg()・smbd_server_fd()・srv_oplock_set_signing()・sys_getpid()・wait_before_sending_break().
参照元 init_oplocks().
00395 { 00396 struct share_mode_entry msg; 00397 files_struct *fsp; 00398 char *break_msg; 00399 BOOL sign_state; 00400 00401 if (buf == NULL) { 00402 DEBUG(0, ("Got NULL buffer\n")); 00403 return; 00404 } 00405 00406 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 00407 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 00408 return; 00409 } 00410 00411 /* De-linearize incoming message. */ 00412 message_to_share_mode_entry(&msg, (char *)buf); 00413 00414 DEBUG(10, ("Got oplock async level 2 break message from pid %d: 0x%x/%.0f/%lu\n", 00415 (int)procid_to_pid(&src), (unsigned int)msg.dev, 00416 (double)msg.inode, msg.share_file_id)); 00417 00418 fsp = initial_break_processing(msg.dev, msg.inode, 00419 msg.share_file_id); 00420 00421 if (fsp == NULL) { 00422 /* We hit a race here. Break messages are sent, and before we 00423 * get to process this message, we have closed the file. 00424 * No need to reply as this is an async message. */ 00425 DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n")); 00426 return; 00427 } 00428 00429 if (fsp->oplock_type == NO_OPLOCK) { 00430 /* We already got a "break to none" message and we've handled it. 00431 * just ignore. */ 00432 DEBUG(3, ("process_oplock_async_level2_break_message: already broken to none, ignoring.\n")); 00433 return; 00434 } 00435 00436 if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) { 00437 /* Don't tell the client, just downgrade. */ 00438 DEBUG(3, ("process_oplock_async_level2_break_message: downgrading fake level 2 oplock.\n")); 00439 remove_oplock(fsp); 00440 return; 00441 } 00442 00443 /* Ensure we're really at level2 state. */ 00444 SMB_ASSERT(fsp->oplock_type == LEVEL_II_OPLOCK); 00445 00446 /* Now send a break to none message to our client. */ 00447 00448 break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); 00449 if (break_msg == NULL) { 00450 exit_server("Could not talloc break_msg\n"); 00451 } 00452 00453 /* Need to wait before sending a break message if we sent ourselves this message. */ 00454 if (procid_to_pid(&src) == sys_getpid()) { 00455 wait_before_sending_break(); 00456 } 00457 00458 /* Save the server smb signing state. */ 00459 sign_state = srv_oplock_set_signing(False); 00460 00461 show_msg(break_msg); 00462 if (!send_smb(smbd_server_fd(), break_msg)) { 00463 exit_server_cleanly("oplock_break: send_smb failed."); 00464 } 00465 00466 /* Restore the sign state to what it was. */ 00467 srv_oplock_set_signing(sign_state); 00468 00469 TALLOC_FREE(break_msg); 00470 00471 /* Async level2 request, don't send a reply, just remove the oplock. */ 00472 remove_oplock(fsp); 00473 }
static void process_oplock_break_message | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
参照先 add_oplock_timeout_handler()・share_mode_entry::dev・exit_server()・exit_server_cleanly()・global_client_caps・initial_break_processing()・share_mode_entry::inode・koplocks・message_send_pid()・message_to_share_mode_entry()・new_break_smb_message()・share_mode_entry::op_type・share_mode_entry::pid・procid_to_pid()・send_smb()・share_mode_entry::share_file_id・show_msg()・smbd_server_fd()・srv_oplock_set_signing()・sys_getpid()・wait_before_sending_break().
参照元 init_oplocks().
00482 { 00483 struct share_mode_entry msg; 00484 files_struct *fsp; 00485 char *break_msg; 00486 BOOL break_to_level2 = False; 00487 BOOL sign_state; 00488 00489 if (buf == NULL) { 00490 DEBUG(0, ("Got NULL buffer\n")); 00491 return; 00492 } 00493 00494 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 00495 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 00496 return; 00497 } 00498 00499 /* De-linearize incoming message. */ 00500 message_to_share_mode_entry(&msg, (char *)buf); 00501 00502 DEBUG(10, ("Got oplock break message from pid %d: 0x%x/%.0f/%lu\n", 00503 (int)procid_to_pid(&src), (unsigned int)msg.dev, 00504 (double)msg.inode, msg.share_file_id)); 00505 00506 fsp = initial_break_processing(msg.dev, msg.inode, 00507 msg.share_file_id); 00508 00509 if (fsp == NULL) { 00510 /* a We hit race here. Break messages are sent, and before we 00511 * get to process this message, we have closed the file. Reply 00512 * with 'ok, oplock broken' */ 00513 DEBUG(3, ("Did not find fsp\n")); 00514 00515 /* We just send the same message back. */ 00516 message_send_pid(src, MSG_SMB_BREAK_RESPONSE, 00517 buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 00518 return; 00519 } 00520 00521 if (fsp->sent_oplock_break != NO_BREAK_SENT) { 00522 /* Remember we have to inform the requesting PID when the 00523 * client replies */ 00524 msg.pid = src; 00525 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg, 00526 &fsp->pending_break_messages, 00527 &fsp->num_pending_break_messages); 00528 return; 00529 } 00530 00531 if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) && 00532 !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 00533 DEBUG(3, ("Already downgraded oplock on 0x%x/%.0f: %s\n", 00534 (unsigned int)fsp->dev, (double)fsp->inode, 00535 fsp->fsp_name)); 00536 /* We just send the same message back. */ 00537 message_send_pid(src, MSG_SMB_BREAK_RESPONSE, 00538 buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 00539 return; 00540 } 00541 00542 if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && 00543 !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) && 00544 !koplocks && /* NOTE: we force levelII off for kernel oplocks - 00545 * this will change when it is supported */ 00546 lp_level2_oplocks(SNUM(fsp->conn))) { 00547 break_to_level2 = True; 00548 } 00549 00550 break_msg = new_break_smb_message(NULL, fsp, break_to_level2 ? 00551 OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); 00552 if (break_msg == NULL) { 00553 exit_server("Could not talloc break_msg\n"); 00554 } 00555 00556 /* Need to wait before sending a break message if we sent ourselves this message. */ 00557 if (procid_to_pid(&src) == sys_getpid()) { 00558 wait_before_sending_break(); 00559 } 00560 00561 /* Save the server smb signing state. */ 00562 sign_state = srv_oplock_set_signing(False); 00563 00564 show_msg(break_msg); 00565 if (!send_smb(smbd_server_fd(), break_msg)) { 00566 exit_server_cleanly("oplock_break: send_smb failed."); 00567 } 00568 00569 /* Restore the sign state to what it was. */ 00570 srv_oplock_set_signing(sign_state); 00571 00572 TALLOC_FREE(break_msg); 00573 00574 fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; 00575 00576 msg.pid = src; 00577 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg, 00578 &fsp->pending_break_messages, 00579 &fsp->num_pending_break_messages); 00580 00581 add_oplock_timeout_handler(fsp); 00582 }
static void process_kernel_oplock_break | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
参照先 add_oplock_timeout_handler()・dev・exit_server()・exit_server_cleanly()・initial_break_processing()・inode・new_break_smb_message()・procid_to_pid()・send_smb()・files_struct::sent_oplock_break・show_msg()・smbd_server_fd()・srv_oplock_set_signing().
参照元 init_oplocks().
00591 { 00592 SMB_DEV_T dev; 00593 SMB_INO_T inode; 00594 unsigned long file_id; 00595 files_struct *fsp; 00596 char *break_msg; 00597 BOOL sign_state; 00598 00599 if (buf == NULL) { 00600 DEBUG(0, ("Got NULL buffer\n")); 00601 return; 00602 } 00603 00604 if (len != MSG_SMB_KERNEL_BREAK_SIZE) { 00605 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 00606 return; 00607 } 00608 00609 /* Pull the data from the message. */ 00610 dev = DEV_T_VAL(buf, 0); 00611 inode = INO_T_VAL(buf, 8); 00612 file_id = (unsigned long)IVAL(buf, 16); 00613 00614 DEBUG(10, ("Got kernel oplock break message from pid %d: 0x%x/%.0f/%u\n", 00615 (int)procid_to_pid(&src), (unsigned int)dev, (double)inode, 00616 (unsigned int)file_id)); 00617 00618 fsp = initial_break_processing(dev, inode, file_id); 00619 00620 if (fsp == NULL) { 00621 DEBUG(3, ("Got a kernel oplock break message for a file " 00622 "I don't know about\n")); 00623 return; 00624 } 00625 00626 if (fsp->sent_oplock_break != NO_BREAK_SENT) { 00627 /* This is ok, kernel oplocks come in completely async */ 00628 DEBUG(3, ("Got a kernel oplock request while waiting for a " 00629 "break reply\n")); 00630 return; 00631 } 00632 00633 break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE); 00634 if (break_msg == NULL) { 00635 exit_server("Could not talloc break_msg\n"); 00636 } 00637 00638 /* Save the server smb signing state. */ 00639 sign_state = srv_oplock_set_signing(False); 00640 00641 show_msg(break_msg); 00642 if (!send_smb(smbd_server_fd(), break_msg)) { 00643 exit_server_cleanly("oplock_break: send_smb failed."); 00644 } 00645 00646 /* Restore the sign state to what it was. */ 00647 srv_oplock_set_signing(sign_state); 00648 00649 TALLOC_FREE(break_msg); 00650 00651 fsp->sent_oplock_break = BREAK_TO_NONE_SENT; 00652 00653 add_oplock_timeout_handler(fsp); 00654 }
void reply_to_oplock_break_requests | ( | files_struct * | fsp | ) |
参照先 message_send_pid()・files_struct::num_pending_break_messages・files_struct::oplock_timeout・files_struct::pending_break_messages・share_mode_entry_to_message().
参照元 oplock_timeout_handler()・reply_lockingX().
00657 { 00658 int i; 00659 00660 for (i=0; i<fsp->num_pending_break_messages; i++) { 00661 struct share_mode_entry *e = &fsp->pending_break_messages[i]; 00662 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 00663 00664 share_mode_entry_to_message(msg, e); 00665 00666 message_send_pid(e->pid, MSG_SMB_BREAK_RESPONSE, 00667 msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 00668 } 00669 00670 SAFE_FREE(fsp->pending_break_messages); 00671 fsp->num_pending_break_messages = 0; 00672 if (fsp->oplock_timeout != NULL) { 00673 /* Remove the timed event handler. */ 00674 TALLOC_FREE(fsp->oplock_timeout); 00675 fsp->oplock_timeout = NULL; 00676 } 00677 return; 00678 }
static void process_oplock_break_response | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
参照先 share_mode_entry::dev・share_mode_entry::inode・message_to_share_mode_entry()・share_mode_entry::op_mid・procid_to_pid()・schedule_deferred_open_smb_message()・share_mode_entry::share_file_id.
参照元 init_oplocks().
00683 { 00684 struct share_mode_entry msg; 00685 00686 if (buf == NULL) { 00687 DEBUG(0, ("Got NULL buffer\n")); 00688 return; 00689 } 00690 00691 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 00692 DEBUG(0, ("Got invalid msg len %u\n", (unsigned int)len)); 00693 return; 00694 } 00695 00696 /* De-linearize incoming message. */ 00697 message_to_share_mode_entry(&msg, (char *)buf); 00698 00699 DEBUG(10, ("Got oplock break response from pid %d: 0x%x/%.0f/%lu mid %u\n", 00700 (int)procid_to_pid(&src), (unsigned int)msg.dev, 00701 (double)msg.inode, msg.share_file_id, 00702 (unsigned int)msg.op_mid)); 00703 00704 /* Here's the hack from open.c, store the mid in the 'port' field */ 00705 schedule_deferred_open_smb_message(msg.op_mid); 00706 }
static void process_open_retry_message | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
参照先 share_mode_entry::dev・share_mode_entry::inode・message_to_share_mode_entry()・share_mode_entry::op_mid・procid_to_pid()・schedule_deferred_open_smb_message()・share_mode_entry::share_file_id.
参照元 init_oplocks().
00711 { 00712 struct share_mode_entry msg; 00713 00714 if (buf == NULL) { 00715 DEBUG(0, ("Got NULL buffer\n")); 00716 return; 00717 } 00718 00719 if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { 00720 DEBUG(0, ("Got invalid msg len %d\n", (int)len)); 00721 return; 00722 } 00723 00724 /* De-linearize incoming message. */ 00725 message_to_share_mode_entry(&msg, (char *)buf); 00726 00727 DEBUG(10, ("Got open retry msg from pid %d: 0x%x/%.0f/%lu mid %u\n", 00728 (int)procid_to_pid(&src), (unsigned int)msg.dev, 00729 (double)msg.inode, msg.share_file_id, 00730 (unsigned int)msg.op_mid)); 00731 00732 schedule_deferred_open_smb_message(msg.op_mid); 00733 }
void release_level_2_oplocks_on_change | ( | files_struct * | fsp | ) |
参照先 files_struct::dev・files_struct::fsp_name・get_share_mode_lock()・files_struct::inode・is_valid_share_mode_entry()・message_send_pid()・share_mode_lock::num_share_modes・files_struct::oplock_type・share_mode_entry_to_message()・share_mode_lock::share_modes.
参照元 reply_lock()・reply_lockingX()・reply_lockread()・vfs_allocate_file_space()・vfs_fill_sparse()・vfs_set_filelen()・write_file().
00742 { 00743 int i; 00744 struct share_mode_lock *lck; 00745 00746 /* 00747 * If this file is level II oplocked then we need 00748 * to grab the shared memory lock and inform all 00749 * other files with a level II lock that they need 00750 * to flush their read caches. We keep the lock over 00751 * the shared memory area whilst doing this. 00752 */ 00753 00754 if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) 00755 return; 00756 00757 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 00758 if (lck == NULL) { 00759 DEBUG(0,("release_level_2_oplocks_on_change: failed to lock " 00760 "share mode entry for file %s.\n", fsp->fsp_name )); 00761 return; 00762 } 00763 00764 DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n", 00765 lck->num_share_modes )); 00766 00767 for(i = 0; i < lck->num_share_modes; i++) { 00768 struct share_mode_entry *share_entry = &lck->share_modes[i]; 00769 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; 00770 00771 if (!is_valid_share_mode_entry(share_entry)) { 00772 continue; 00773 } 00774 00775 /* 00776 * As there could have been multiple writes waiting at the 00777 * lock_share_entry gate we may not be the first to 00778 * enter. Hence the state of the op_types in the share mode 00779 * entries may be partly NO_OPLOCK and partly LEVEL_II or FAKE_LEVEL_II 00780 * oplock. It will do no harm to re-send break messages to 00781 * those smbd's that are still waiting their turn to remove 00782 * their LEVEL_II state, and also no harm to ignore existing 00783 * NO_OPLOCK states. JRA. 00784 */ 00785 00786 DEBUG(10,("release_level_2_oplocks_on_change: " 00787 "share_entry[%i]->op_type == %d\n", 00788 i, share_entry->op_type )); 00789 00790 if (share_entry->op_type == NO_OPLOCK) { 00791 continue; 00792 } 00793 00794 /* Paranoia .... */ 00795 if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) { 00796 DEBUG(0,("release_level_2_oplocks_on_change: PANIC. " 00797 "share mode entry %d is an exlusive " 00798 "oplock !\n", i )); 00799 TALLOC_FREE(lck); 00800 abort(); 00801 } 00802 00803 share_mode_entry_to_message(msg, share_entry); 00804 00805 message_send_pid(share_entry->pid, MSG_SMB_ASYNC_LEVEL2_BREAK, 00806 msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); 00807 } 00808 00809 /* We let the message receivers handle removing the oplock state 00810 in the share mode lock db. */ 00811 00812 TALLOC_FREE(lck); 00813 }
void share_mode_entry_to_message | ( | char * | msg, | |
struct share_mode_entry * | e | |||
) |
参照先 share_mode_entry::access_mask・share_mode_entry::dev・share_mode_entry::flags・share_mode_entry::inode・share_mode_entry::op_mid・share_mode_entry::op_type・process_id::pid・share_mode_entry::pid・share_mode_entry::private_options・share_mode_entry::share_access・share_mode_entry::share_file_id・share_mode_entry::time・share_mode_entry::uid.
参照元 notify_deferred_opens()・release_level_2_oplocks_on_change()・reply_to_oplock_break_requests().
00820 { 00821 SIVAL(msg,0,(uint32)e->pid.pid); 00822 SSVAL(msg,4,e->op_mid); 00823 SSVAL(msg,6,e->op_type); 00824 SIVAL(msg,8,e->access_mask); 00825 SIVAL(msg,12,e->share_access); 00826 SIVAL(msg,16,e->private_options); 00827 SIVAL(msg,20,(uint32)e->time.tv_sec); 00828 SIVAL(msg,24,(uint32)e->time.tv_usec); 00829 SDEV_T_VAL(msg,28,e->dev); 00830 SINO_T_VAL(msg,36,e->inode); 00831 SIVAL(msg,44,e->share_file_id); 00832 SIVAL(msg,48,e->uid); 00833 SSVAL(msg,52,e->flags); 00834 }
void message_to_share_mode_entry | ( | struct share_mode_entry * | e, | |
char * | msg | |||
) |
参照先 share_mode_entry::access_mask・share_mode_entry::dev・share_mode_entry::flags・share_mode_entry::inode・share_mode_entry::op_mid・share_mode_entry::op_type・process_id::pid・share_mode_entry::pid・share_mode_entry::private_options・share_mode_entry::share_access・share_mode_entry::share_file_id・share_mode_entry::time・share_mode_entry::uid.
参照元 process_open_retry_message()・process_oplock_async_level2_break_message()・process_oplock_break_message()・process_oplock_break_response().
00841 { 00842 e->pid.pid = (pid_t)IVAL(msg,0); 00843 e->op_mid = SVAL(msg,4); 00844 e->op_type = SVAL(msg,6); 00845 e->access_mask = IVAL(msg,8); 00846 e->share_access = IVAL(msg,12); 00847 e->private_options = IVAL(msg,16); 00848 e->time.tv_sec = (time_t)IVAL(msg,20); 00849 e->time.tv_usec = (int)IVAL(msg,24); 00850 e->dev = DEV_T_VAL(msg,28); 00851 e->inode = INO_T_VAL(msg,36); 00852 e->share_file_id = (unsigned long)IVAL(msg,44); 00853 e->uid = (uint32)IVAL(msg,48); 00854 e->flags = (uint16)SVAL(msg,52); 00855 }
BOOL init_oplocks | ( | void | ) |
参照先 irix_init_kernel_oplocks()・koplocks・linux_init_kernel_oplocks()・message_register()・process_kernel_oplock_break()・process_open_retry_message()・process_oplock_async_level2_break_message()・process_oplock_break_message()・process_oplock_break_response().
参照元 main().
00862 { 00863 DEBUG(3,("init_oplocks: initializing messages.\n")); 00864 00865 message_register(MSG_SMB_BREAK_REQUEST, 00866 process_oplock_break_message, 00867 NULL); 00868 message_register(MSG_SMB_ASYNC_LEVEL2_BREAK, 00869 process_oplock_async_level2_break_message, 00870 NULL); 00871 message_register(MSG_SMB_BREAK_RESPONSE, 00872 process_oplock_break_response, 00873 NULL); 00874 message_register(MSG_SMB_KERNEL_BREAK, 00875 process_kernel_oplock_break, 00876 NULL); 00877 message_register(MSG_SMB_OPEN_RETRY, 00878 process_open_retry_message, 00879 NULL); 00880 00881 if (lp_kernel_oplocks()) { 00882 #if HAVE_KERNEL_OPLOCKS_IRIX 00883 koplocks = irix_init_kernel_oplocks(); 00884 #elif HAVE_KERNEL_OPLOCKS_LINUX 00885 koplocks = linux_init_kernel_oplocks(); 00886 #endif 00887 } 00888 00889 return True; 00890 }
int32 exclusive_oplocks_open = 0 [static] |
int32 level_II_oplocks_open = 0 [static] |
uint32 global_client_caps |
sesssetup.c の 32 行で定義されています。
int smb_read_error |
util_sock.c の 117 行で定義されています。
struct kernel_oplocks* koplocks [static] |