Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998 - 2001
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DBGC_CLASS DBGC_LOCKING
#include "includes.h"
+#include "smbd/smbd.h"
#include "smbd/globals.h"
-#include "librpc/gen_ndr/messaging.h"
+#include "messages.h"
+#include "../librpc/gen_ndr/open_files.h"
/****************************************************************************
Get the number of current exclusive oplocks.
}
/****************************************************************************
- Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
- disabled (just sets flags). Returns True if oplock set.
+ Attempt to set an oplock on a file. Succeeds if kernel oplocks are
+ disabled (just sets flags) and no byte-range locks in the file. Returns True
+ if oplock set.
****************************************************************************/
bool set_file_oplock(files_struct *fsp, int oplock_type)
{
- if ((fsp->oplock_type == LEVEL_II_OPLOCK)
- && koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) {
- DEBUG(10, ("Refusing level2 oplock, kernel oplocks don't "
- "support them\n"));
- return false;
+ if (fsp->oplock_type == LEVEL_II_OPLOCK) {
+ if (koplocks &&
+ !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) {
+ DEBUG(10, ("Refusing level2 oplock, kernel oplocks "
+ "don't support them\n"));
+ return false;
+ }
}
+
if ((fsp->oplock_type != NO_OPLOCK) &&
(fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
koplocks &&
static char *new_break_message_smb1(TALLOC_CTX *mem_ctx,
files_struct *fsp, int cmd)
{
- char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0);
+ char *result = talloc_array(mem_ctx, char, smb_size + 8*2 + 0);
if (result == NULL) {
DEBUG(0, ("talloc failed\n"));
}
fsp->oplock_timeout =
- event_add_timed(smbd_event_context(), fsp,
- timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
- oplock_timeout_handler, fsp);
+ tevent_add_timer(fsp->conn->sconn->ev_ctx, fsp,
+ timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
+ oplock_timeout_handler, fsp);
if (fsp->oplock_timeout == NULL) {
DEBUG(0, ("Could not add oplock timeout handler\n"));
struct server_id src,
DATA_BLOB *data)
{
- struct smbd_server_connection *sconn;
struct share_mode_entry msg;
files_struct *fsp;
+ struct smbd_server_connection *sconn =
+ talloc_get_type(private_data,
+ struct smbd_server_connection);
- if (data->data == NULL) {
- DEBUG(0, ("Got NULL buffer\n"));
+ if (sconn == NULL) {
return;
}
- sconn = msg_ctx_to_sconn(msg_ctx);
- if (sconn == NULL) {
- DEBUG(1, ("could not find sconn\n"));
+ if (data->data == NULL) {
+ DEBUG(0, ("Got NULL buffer\n"));
return;
}
message_to_share_mode_entry(&msg, (char *)data->data);
DEBUG(10, ("Got oplock async level 2 break message from pid %s: "
- "%s/%lu\n", procid_str(talloc_tos(), &src),
- file_id_string_tos(&msg.id), msg.share_file_id));
+ "%s/%llu\n", 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);
struct server_id src,
DATA_BLOB *data)
{
- struct smbd_server_connection *sconn;
struct share_mode_entry msg;
files_struct *fsp;
bool break_to_level2 = False;
+ struct smbd_server_connection *sconn =
+ talloc_get_type(private_data,
+ struct smbd_server_connection);
- if (data->data == NULL) {
- DEBUG(0, ("Got NULL buffer\n"));
+ if (sconn == NULL) {
return;
}
- sconn = msg_ctx_to_sconn(msg_ctx);
- if (sconn == NULL) {
- DEBUG(1, ("could not find sconn\n"));
+ if (data->data == NULL) {
+ DEBUG(0, ("Got NULL buffer\n"));
return;
}
/* De-linearize incoming message. */
message_to_share_mode_entry(&msg, (char *)data->data);
- DEBUG(10, ("Got oplock break message from pid %s: %s/%lu\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
- msg.share_file_id));
+ DEBUG(10, ("Got oplock break message from pid %s: %s/%llu\n",
+ 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);
struct server_id src,
DATA_BLOB *data)
{
- struct smbd_server_connection *sconn;
struct file_id id;
unsigned long file_id;
files_struct *fsp;
+ struct smbd_server_connection *sconn =
+ talloc_get_type(private_data,
+ struct smbd_server_connection);
+
+ if (sconn == NULL) {
+ return;
+ }
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
return;
}
- sconn = msg_ctx_to_sconn(msg_ctx);
- if (sconn == NULL) {
- DEBUG(1, ("could not find sconn\n"));
- return;
- }
-
/* Pull the data from the message. */
pull_file_id_24((char *)data->data, &id);
file_id = (unsigned long)IVAL(data->data, 24);
DEBUG(10, ("Got kernel oplock break message from pid %s: %s/%u\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&id),
+ server_id_str(talloc_tos(), &src), file_id_string_tos(&id),
(unsigned int)file_id));
fsp = initial_break_processing(sconn, id, file_id);
DATA_BLOB *data)
{
struct share_mode_entry msg;
+ struct smbd_server_connection *sconn =
+ talloc_get_type(private_data,
+ struct smbd_server_connection);
+
+ if (sconn == NULL) {
+ return;
+ }
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
/* De-linearize incoming message. */
message_to_share_mode_entry(&msg, (char *)data->data);
- DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid %llu\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
- msg.share_file_id, (unsigned long long)msg.op_mid));
+ DEBUG(10, ("Got oplock break response from pid %s: %s/%llu mid %llu\n",
+ server_id_str(talloc_tos(), &src),
+ file_id_string_tos(&msg.id),
+ (unsigned long long)msg.share_file_id,
+ (unsigned long long)msg.op_mid));
- schedule_deferred_open_message_smb(msg.op_mid);
+ schedule_deferred_open_message_smb(sconn, msg.op_mid);
}
static void process_open_retry_message(struct messaging_context *msg_ctx,
DATA_BLOB *data)
{
struct share_mode_entry msg;
-
+ struct smbd_server_connection *sconn =
+ talloc_get_type(private_data,
+ struct smbd_server_connection);
+
+ if (sconn == NULL) {
+ return;
+ }
+
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
return;
message_to_share_mode_entry(&msg, (char *)data->data);
DEBUG(10, ("Got open retry msg from pid %s: %s mid %llu\n",
- procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
+ server_id_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
(unsigned long long)msg.op_mid));
- schedule_deferred_open_message_smb(msg.op_mid);
+ schedule_deferred_open_message_smb(sconn, msg.op_mid);
}
/****************************************************************************
*/
if (procid_is_me(&share_entry->pid)) {
+ struct files_struct *cur_fsp =
+ initial_break_processing(fsp->conn->sconn,
+ share_entry->id,
+ share_entry->share_file_id);
wait_before_sending_break();
- break_level2_to_none_async(fsp);
+ if (cur_fsp != NULL) {
+ break_level2_to_none_async(cur_fsp);
+ } else {
+ DEBUG(3, ("release_level_2_oplocks_on_change: "
+ "Did not find fsp, ignoring\n"));
+ }
} else {
messaging_send_buf(fsp->conn->sconn->msg_ctx,
share_entry->pid,
TALLOC_FREE(lck);
}
-void contend_level2_oplocks_begin(files_struct *fsp,
+void smbd_contend_level2_oplocks_begin(files_struct *fsp,
enum level2_contention_type type)
{
if (koplocks && koplocks->ops->contend_level2_oplocks_begin) {
contend_level2_oplocks_begin_default(fsp, type);
}
-void contend_level2_oplocks_end(files_struct *fsp,
+void smbd_contend_level2_oplocks_end(files_struct *fsp,
enum level2_contention_type type)
{
/* Only kernel oplocks implement this so far */
SIVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET,e->share_file_id);
SIVAL(msg,OP_BREAK_MSG_UID_OFFSET,e->uid);
SSVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET,e->flags);
-#ifdef CLUSTER_SUPPORT
+ SIVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET,e->name_hash);
SIVAL(msg,OP_BREAK_MSG_VNN_OFFSET,e->pid.vnn);
-#endif
}
/****************************************************************************
e->share_file_id = (unsigned long)IVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET);
e->uid = (uint32)IVAL(msg,OP_BREAK_MSG_UID_OFFSET);
e->flags = (uint16)SVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET);
-#ifdef CLUSTER_SUPPORT
+ e->name_hash = IVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET);
e->pid.vnn = IVAL(msg,OP_BREAK_MSG_VNN_OFFSET);
-#endif
}
/****************************************************************************
Setup oplocks for this process.
****************************************************************************/
-bool init_oplocks(struct messaging_context *msg_ctx)
+bool init_oplocks(struct smbd_server_connection *sconn)
{
DEBUG(3,("init_oplocks: initializing messages.\n"));
- messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_REQUEST,
+ messaging_register(sconn->msg_ctx, sconn, MSG_SMB_BREAK_REQUEST,
process_oplock_break_message);
- messaging_register(msg_ctx, NULL, MSG_SMB_ASYNC_LEVEL2_BREAK,
+ messaging_register(sconn->msg_ctx, sconn, MSG_SMB_ASYNC_LEVEL2_BREAK,
process_oplock_async_level2_break_message);
- messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_RESPONSE,
+ messaging_register(sconn->msg_ctx, sconn, MSG_SMB_BREAK_RESPONSE,
process_oplock_break_response);
- messaging_register(msg_ctx, NULL, MSG_SMB_KERNEL_BREAK,
+ messaging_register(sconn->msg_ctx, sconn, MSG_SMB_KERNEL_BREAK,
process_kernel_oplock_break);
- messaging_register(msg_ctx, NULL, MSG_SMB_OPEN_RETRY,
+ messaging_register(sconn->msg_ctx, sconn, MSG_SMB_OPEN_RETRY,
process_open_retry_message);
if (lp_kernel_oplocks()) {
#if HAVE_KERNEL_OPLOCKS_IRIX
- koplocks = irix_init_kernel_oplocks(talloc_autofree_context());
+ koplocks = irix_init_kernel_oplocks(NULL);
#elif HAVE_KERNEL_OPLOCKS_LINUX
koplocks = linux_init_kernel_oplocks(NULL);
#elif HAVE_ONEFS
- koplocks = onefs_init_kernel_oplocks(talloc_autofree_context());
+#error Isilon, please check if the NULL context is okay here. Thanks!
+ koplocks = onefs_init_kernel_oplocks(NULL);
#endif
}