summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-06-20 14:12:14 +0000
committerVolker Lendecke <vl@samba.org>2014-06-21 20:38:11 +0200
commit0ead434b84a7c3226ac223acc79ad0e794da3877 (patch)
tree12387237bea0a1e1a9228cc74ed4907d84e0bfb5
parent01c197dc159297d9abdc62f0d2f69d4724b9fc5c (diff)
downloadsamba-0ead434b84a7c3226ac223acc79ad0e794da3877.tar.gz
samba-0ead434b84a7c3226ac223acc79ad0e794da3877.tar.xz
samba-0ead434b84a7c3226ac223acc79ad0e794da3877.zip
smbd: Store "struct deferred_open_record" instead of anonymous data on pml
The main point is to get a talloc parent that will go away when the request is cancelled Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/smbd/globals.h13
-rw-r--r--source3/smbd/open.c24
-rw-r--r--source3/smbd/process.c30
-rw-r--r--source3/smbd/proto.h14
-rw-r--r--source3/smbd/smb2_create.c19
5 files changed, 48 insertions, 52 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index cd99fe72ca..28e4f94430 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -287,6 +287,8 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
struct tevent_immediate *im,
void *private_data);
+struct deferred_open_record;
+
/* SMB1 -> SMB2 glue. */
void send_break_message_smb2(files_struct *fsp, int level);
struct blocking_lock_record *get_pending_smb2req_blr(struct smbd_smb2_request *smb2req);
@@ -310,7 +312,7 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp,
int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level);
bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
struct timeval *p_request_time,
- void **pp_state);
+ struct deferred_open_record **open_rec);
bool open_was_deferred_smb2(struct smbd_server_connection *sconn,
uint64_t mid);
void remove_deferred_open_message_smb2(
@@ -318,11 +320,10 @@ void remove_deferred_open_message_smb2(
bool schedule_deferred_open_message_smb2(
struct smbd_server_connection *sconn, uint64_t mid);
bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
- struct timeval request_time,
- struct timeval timeout,
- struct file_id id,
- char *private_data,
- size_t priv_len);
+ struct timeval request_time,
+ struct timeval timeout,
+ struct file_id id,
+ struct deferred_open_record *open_rec);
struct smbXsrv_connection {
struct smbd_server_connection *sconn;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 237e90cfd3..c0f4dea3ac 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1564,14 +1564,24 @@ static void defer_open(struct share_mode_lock *lck,
struct smb_request *req,
struct deferred_open_record *state)
{
+ struct deferred_open_record *open_rec;
+
DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
"open entry for mid %llu\n",
(unsigned int)request_time.tv_sec,
(unsigned int)request_time.tv_usec,
(unsigned long long)req->mid));
+ open_rec = talloc(NULL, struct deferred_open_record);
+ if (open_rec == NULL) {
+ TALLOC_FREE(lck);
+ exit_server("talloc failed");
+ }
+
+ *open_rec = *state;
+
if (!push_deferred_open_message_smb(req, request_time, timeout,
- state->id, (char *)state, sizeof(*state))) {
+ state->id, open_rec)) {
TALLOC_FREE(lck);
exit_server("push_deferred_open_message_smb failed");
}
@@ -1930,11 +1940,9 @@ NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
Return true if this is a state pointer to an asynchronous create.
****************************************************************************/
-bool is_deferred_open_async(const void *ptr)
+bool is_deferred_open_async(const struct deferred_open_record *rec)
{
- const struct deferred_open_record *state = (const struct deferred_open_record *)ptr;
-
- return state->async_open;
+ return rec->async_open;
}
static bool clear_ads(uint32_t create_disposition)
@@ -2143,10 +2151,10 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
*/
if (req) {
- void *ptr;
+ struct deferred_open_record *open_rec;
if (get_deferred_open_message_state(req,
&request_time,
- &ptr)) {
+ &open_rec)) {
/* Remember the absolute time of the original
request with this mid. We'll use it later to
see if this has timed out. */
@@ -2154,7 +2162,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
/* If it was an async create retry, the file
didn't exist. */
- if (is_deferred_open_async(ptr)) {
+ if (is_deferred_open_async(open_rec)) {
SET_STAT_INVALID(smb_fname->st);
file_existed = false;
}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 8a1d1d6770..b1d522dbc3 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -52,7 +52,7 @@ struct pending_message_list {
bool encrypted;
bool processed;
DATA_BLOB buf;
- DATA_BLOB private_data;
+ struct deferred_open_record *open_rec;
};
static void construct_reply_common(struct smb_request *req, const char *inbuf,
@@ -635,7 +635,7 @@ static void smbd_deferred_open_timer(struct tevent_context *ev,
static bool push_queued_message(struct smb_request *req,
struct timeval request_time,
struct timeval end_time,
- char *private_data, size_t private_len)
+ struct deferred_open_record *open_rec)
{
int msg_len = smb_len(req->inbuf) + 4;
struct pending_message_list *msg;
@@ -661,14 +661,8 @@ static bool push_queued_message(struct smb_request *req,
msg->processed = false;
SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
- if (private_data) {
- msg->private_data = data_blob_talloc(msg, private_data,
- private_len);
- if (msg->private_data.data == NULL) {
- DEBUG(0,("push_message: malloc fail (3)\n"));
- TALLOC_FREE(msg);
- return False;
- }
+ if (open_rec) {
+ msg->open_rec = talloc_move(msg, &open_rec);
}
#if 0
@@ -828,14 +822,14 @@ static struct pending_message_list *get_deferred_open_message_smb(
bool get_deferred_open_message_state(struct smb_request *smbreq,
struct timeval *p_request_time,
- void **pp_state)
+ struct deferred_open_record **open_rec)
{
struct pending_message_list *pml;
if (smbreq->sconn->using_smb2) {
return get_deferred_open_message_state_smb2(smbreq->smb2req,
p_request_time,
- pp_state);
+ open_rec);
}
pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
@@ -845,8 +839,8 @@ bool get_deferred_open_message_state(struct smb_request *smbreq,
if (p_request_time) {
*p_request_time = pml->request_time;
}
- if (pp_state) {
- *pp_state = (void *)pml->private_data.data;
+ if (open_rec != NULL) {
+ *open_rec = pml->open_rec;
}
return true;
}
@@ -860,7 +854,7 @@ bool push_deferred_open_message_smb(struct smb_request *req,
struct timeval request_time,
struct timeval timeout,
struct file_id id,
- char *private_data, size_t priv_len)
+ struct deferred_open_record *open_rec)
{
struct timeval end_time;
@@ -869,8 +863,7 @@ bool push_deferred_open_message_smb(struct smb_request *req,
request_time,
timeout,
id,
- private_data,
- priv_len);
+ open_rec);
}
if (req->unread_bytes) {
@@ -890,8 +883,7 @@ bool push_deferred_open_message_smb(struct smb_request *req,
(unsigned int)end_time.tv_sec,
(unsigned int)end_time.tv_usec));
- return push_queued_message(req, request_time, end_time,
- private_data, priv_len);
+ return push_queued_message(req, request_time, end_time, open_rec);
}
static void smbd_sig_term_handler(struct tevent_context *ev,
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 1e17f5b741..b25ef7b159 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -620,7 +620,8 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
const char *fname,
SMB_STRUCT_STAT *psbuf);
bool is_stat_open(uint32 access_mask);
-bool is_deferred_open_async(const void *ptr);
+struct deferred_open_record;
+bool is_deferred_open_async(const struct deferred_open_record *rec);
NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
struct smb_filename *smb_dname);
void msg_file_was_renamed(struct messaging_context *msg,
@@ -764,13 +765,12 @@ bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid);
bool get_deferred_open_message_state(struct smb_request *smbreq,
struct timeval *p_request_time,
- void **pp_state);
+ struct deferred_open_record **open_rec);
bool push_deferred_open_message_smb(struct smb_request *req,
- struct timeval request_time,
- struct timeval timeout,
- struct file_id id,
- char *private_data,
- size_t priv_len);
+ struct timeval request_time,
+ struct timeval timeout,
+ struct file_id id,
+ struct deferred_open_record *open_rec);
NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid);
void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes);
void smb_request_done(struct smb_request *req);
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 4e2e6bc3ff..976e81a33a 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -382,7 +382,7 @@ struct smbd_smb2_create_state {
struct tevent_immediate *im;
struct timeval request_time;
struct file_id id;
- DATA_BLOB private_data;
+ struct deferred_open_record *open_rec;
uint8_t out_oplock_level;
uint32_t out_create_action;
struct timespec out_creation_ts;
@@ -1177,7 +1177,7 @@ static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
struct timeval *p_request_time,
- void **pp_state)
+ struct deferred_open_record **open_rec)
{
struct smbd_smb2_create_state *state = NULL;
struct tevent_req *req = NULL;
@@ -1199,8 +1199,8 @@ bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
if (p_request_time) {
*p_request_time = state->request_time;
}
- if (pp_state) {
- *pp_state = (void *)state->private_data.data;
+ if (open_rec != NULL) {
+ *open_rec = state->open_rec;
}
return true;
}
@@ -1409,7 +1409,7 @@ static bool smbd_smb2_create_cancel(struct tevent_req *req)
smb2req = state->smb2req;
mid = get_mid_from_smb2req(smb2req);
- if (is_deferred_open_async(state->private_data.data)) {
+ if (is_deferred_open_async(state->open_rec)) {
/* Can't cancel an async create. */
return false;
}
@@ -1425,8 +1425,7 @@ bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
struct timeval request_time,
struct timeval timeout,
struct file_id id,
- char *private_data,
- size_t priv_len)
+ struct deferred_open_record *open_rec)
{
struct tevent_req *req = NULL;
struct smbd_smb2_create_state *state = NULL;
@@ -1445,11 +1444,7 @@ bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
}
state->id = id;
state->request_time = request_time;
- state->private_data = data_blob_talloc(state, private_data,
- priv_len);
- if (!state->private_data.data) {
- return false;
- }
+ state->open_rec = talloc_move(state, &open_rec);
/* Re-schedule us to retry on timer expiry. */
end_time = timeval_sum(&request_time, &timeout);