smbd: Store "struct deferred_open_record" instead of anonymous data on pml
authorVolker Lendecke <vl@samba.org>
Fri, 20 Jun 2014 14:12:14 +0000 (14:12 +0000)
committerVolker Lendecke <vl@samba.org>
Sat, 21 Jun 2014 18:38:11 +0000 (20:38 +0200)
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>
source3/smbd/globals.h
source3/smbd/open.c
source3/smbd/process.c
source3/smbd/proto.h
source3/smbd/smb2_create.c

index cd99fe72ca154423aa53f330ab46a58ef9eeb1a9..28e4f94430373e8d8ad39167a266baed465dba0c 100644 (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;
index 237e90cfd3ecf9df490d1fd87bbce39660ff8bfd..c0f4dea3ac986ca0d5961ffa45460cb5198aa30b 100644 (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;
                        }
index 8a1d1d677046cf48e7d513e692e92793d896ee37..b1d522dbc34fe2791030061ccf13abc7bec3f68b 100644 (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,
index 1e17f5b741a1ffe4d09c6e6c3df7d444bfd19668..b25ef7b159f5e56ac4dfe4831194b1127f7f994d 100644 (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);
index 4e2e6bc3ffd892986dbedfbbd7f4de59ada90783..976e81a33a156bba15b569422e2012cf5f8d4da3 100644 (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);