void msg_close_file(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { files_struct *fsp = NULL; struct share_mode_entry e; struct smbd_server_connection *sconn = talloc_get_type_abort(private_data, struct smbd_server_connection); message_to_share_mode_entry(&e, (char *)data->data); if(DEBUGLVL(10)) { char *sm_str = share_mode_str(NULL, 0, &e); if (!sm_str) { smb_panic("talloc failed"); } DEBUG(10,("msg_close_file: got request to close share mode " "entry %s\n", sm_str)); TALLOC_FREE(sm_str); } fsp = file_find_dif(sconn, e.id, e.share_file_id); if (!fsp) { DEBUG(10,("msg_close_file: failed to find file.\n")); return; } close_file(NULL, fsp, NORMAL_CLOSE); }
static void process_oplock_break_message(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { struct share_mode_entry msg; files_struct *fsp; bool break_to_level2 = False; bool use_kernel; struct smbd_server_connection *sconn = talloc_get_type_abort(private_data, struct smbd_server_connection); struct server_id self = messaging_server_id(sconn->msg_ctx); struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops; uint16_t break_to; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); return; } if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) { DEBUG(0, ("Got invalid msg len %d\n", (int)data->length)); return; } /* De-linearize incoming message. */ message_to_share_mode_entry(&msg, (char *)data->data); break_to = msg.op_type; DEBUG(10, ("Got oplock break to %u message from pid %s: %s/%llu\n", (unsigned)break_to, server_id_str(talloc_tos(), &src), file_id_string_tos(&msg.id), (unsigned long long)msg.share_file_id)); fsp = initial_break_processing(sconn, msg.id, msg.share_file_id); if (fsp == NULL) { /* We hit a race here. Break messages are sent, and before we * get to process this message, we have closed the file. */ DEBUG(3, ("Did not find fsp\n")); return; } if (fsp->sent_oplock_break != NO_BREAK_SENT) { /* * Nothing to do anymore */ return; } if (break_to == fsp->oplock_type) { DEBUG(3, ("Already downgraded oplock on %s: %s\n", file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp))); return; } use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && koplocks; if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && (break_to != NO_OPLOCK) && !(use_kernel && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) && lp_level2_oplocks(SNUM(fsp->conn))) { break_to_level2 = True; } /* Need to wait before sending a break message if we sent ourselves this message. */ if (serverid_equal(&self, &src)) { wait_before_sending_break(); } if (sconn->using_smb2) { send_break_message_smb2(fsp, break_to_level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); } else { send_break_message_smb1(fsp, break_to_level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE); } if ((fsp->oplock_type == LEVEL_II_OPLOCK) && (break_to == NO_OPLOCK)) { /* * This is an async break without a reply and thus no timeout */ remove_oplock(fsp); return; } fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; add_oplock_timeout_handler(fsp); }