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:
parent
01c197dc15
commit
0ead434b84
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user