1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

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>
This commit is contained in:
Volker Lendecke 2014-06-20 14:12:14 +00:00
parent 01c197dc15
commit 0ead434b84
5 changed files with 48 additions and 52 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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,

View File

@ -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);

View File

@ -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);