lib: modules: Change XXX_init interface from XXX_init(void) to XXX_init(TALLOC_CTX *)
[amitay/samba.git] / source3 / smbd / smb2_lock.c
index b11462c54f4a458620776c4d68308bf8d9e8ab73..2fcd35926246b405016d146f4995c581c6e8feea 100644 (file)
@@ -139,7 +139,7 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
        if (!NT_STATUS_IS_OK(status)) {
                error = smbd_smb2_request_error(smb2req, status);
                if (!NT_STATUS_IS_OK(error)) {
-                       smbd_server_connection_terminate(smb2req->sconn,
+                       smbd_server_connection_terminate(smb2req->xconn,
                                                         nt_errstr(error));
                        return;
                }
@@ -150,7 +150,7 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
-                       smbd_server_connection_terminate(smb2req->sconn,
+                       smbd_server_connection_terminate(smb2req->xconn,
                                                         nt_errstr(error));
                        return;
                }
@@ -162,7 +162,7 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
 
        error = smbd_smb2_request_done(smb2req, outbody, NULL);
        if (!NT_STATUS_IS_OK(error)) {
-               smbd_server_connection_terminate(smb2req->sconn,
+               smbd_server_connection_terminate(smb2req->xconn,
                                                 nt_errstr(error));
                return;
        }
@@ -308,7 +308,7 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
                         * this is an invalid UNLOCK element
                         * and the backend needs to test for
                         * brltype != UNLOCK_LOCK and return
-                        * NT_STATUS_INVALID_PARAMER
+                        * NT_STATUS_INVALID_PARAMETER
                         */
                        locks[i].brltype = READ_LOCK;
                } else {
@@ -348,6 +348,8 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
        }
 
        if (async) {
+               tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
+               SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
                return req;
        }
 
@@ -388,7 +390,6 @@ static bool smbd_smb2_lock_cancel(struct tevent_req *req)
        smb2req = state->smb2req;
 
        remove_pending_lock(state, state->blr);
-       tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
 
        /*
         * If the request is canceled because of logoff, tdis or close
@@ -468,33 +469,48 @@ struct blocking_lock_record *get_pending_smb2req_blr(struct smbd_smb2_request *s
 
 static bool recalc_smb2_brl_timeout(struct smbd_server_connection *sconn)
 {
-       struct smbd_smb2_request *smb2req;
+       struct smbXsrv_connection *xconn = NULL;
        struct timeval next_timeout = timeval_zero();
        int max_brl_timeout = lp_parm_int(-1, "brl", "recalctime", 5);
 
        TALLOC_FREE(sconn->smb2.locks.brl_timeout);
 
-       for (smb2req = sconn->smb2.requests; smb2req; smb2req = smb2req->next) {
-               struct blocking_lock_record *blr =
-                       get_pending_smb2req_blr(smb2req);
-               if (!blr) {
-                       continue;
-               }
-               if (timeval_is_zero(&blr->expire_time)) {
+       if (sconn->client != NULL) {
+               xconn = sconn->client->connections;
+       }
+
+       for (; xconn != NULL; xconn = xconn->next) {
+               struct smbd_smb2_request *smb2req, *nextreq;
+
+               for (smb2req = xconn->smb2.requests; smb2req; smb2req = nextreq) {
+                       struct blocking_lock_record *blr =
+                               get_pending_smb2req_blr(smb2req);
+
+                       nextreq = smb2req->next;
+
+                       if (blr == NULL) {
+                               continue;
+                       }
+
+                       if (!timeval_is_zero(&blr->expire_time)) {
+                               next_timeout = timeval_brl_min(&next_timeout,
+                                                       &blr->expire_time);
+                               continue;
+                       }
+
                        /*
                         * If we're blocked on pid 0xFFFFFFFFFFFFFFFFLL this is
                         * a POSIX lock, so calculate a timeout of
                         * 10 seconds into the future.
                         */
                        if (blr->blocking_smblctx == 0xFFFFFFFFFFFFFFFFLL) {
-                               struct timeval psx_to = timeval_current_ofs(10, 0);
-                               next_timeout = timeval_brl_min(&next_timeout, &psx_to);
-                       }
+                               struct timeval psx_to;
 
-                       continue;
+                               psx_to = timeval_current_ofs(10, 0);
+                               next_timeout = timeval_brl_min(&next_timeout,
+                                                              &psx_to);
+                       }
                }
-
-               next_timeout = timeval_brl_min(&next_timeout, &blr->expire_time);
        }
 
        if (timeval_is_zero(&next_timeout)) {
@@ -664,8 +680,7 @@ static void remove_pending_lock(struct smbd_smb2_lock_state *state,
                                messaging_server_id(blr->fsp->conn->sconn->msg_ctx),
                                blr->offset,
                                blr->count,
-                               blr->lock_flav,
-                               blr);
+                               blr->lock_flav);
                TALLOC_FREE(br_lck);
        }
 }
@@ -688,6 +703,8 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req,
        if (!smb2req->subreq) {
                return;
        }
+       SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(smb2req->profile);
+
        state = tevent_req_data(smb2req->subreq, struct smbd_smb2_lock_state);
        if (!state) {
                return;
@@ -764,6 +781,7 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req,
                fsp_str_dbg(fsp),
                fsp_fnum_dbg(fsp)));
 
+       SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
         return;
 }
 
@@ -775,25 +793,33 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req,
 void process_blocking_lock_queue_smb2(
        struct smbd_server_connection *sconn, struct timeval tv_curr)
 {
-       struct smbd_smb2_request *smb2req, *nextreq;
+       struct smbXsrv_connection *xconn = NULL;
 
-       for (smb2req = sconn->smb2.requests; smb2req; smb2req = nextreq) {
-               const uint8_t *inhdr;
+       if (sconn != NULL && sconn->client != NULL) {
+               xconn = sconn->client->connections;
+       }
 
-               nextreq = smb2req->next;
+       for (; xconn != NULL; xconn = xconn->next) {
+               struct smbd_smb2_request *smb2req, *nextreq;
 
-               if (smb2req->subreq == NULL) {
-                       /* This message has been processed. */
-                       continue;
-               }
-               if (!tevent_req_is_in_progress(smb2req->subreq)) {
-                       /* This message has been processed. */
-                       continue;
-               }
+               for (smb2req = xconn->smb2.requests; smb2req; smb2req = nextreq) {
+                       const uint8_t *inhdr;
+
+                       nextreq = smb2req->next;
+
+                       if (smb2req->subreq == NULL) {
+                               /* This message has been processed. */
+                               continue;
+                       }
+                       if (!tevent_req_is_in_progress(smb2req->subreq)) {
+                               /* This message has been processed. */
+                               continue;
+                       }
 
-               inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
-               if (SVAL(inhdr, SMB2_HDR_OPCODE) == SMB2_OP_LOCK) {
-                       reprocess_blocked_smb2_lock(smb2req, tv_curr);
+                       inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
+                       if (SVAL(inhdr, SMB2_HDR_OPCODE) == SMB2_OP_LOCK) {
+                               reprocess_blocked_smb2_lock(smb2req, tv_curr);
+                       }
                }
        }
 
@@ -809,66 +835,73 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp,
                        enum file_close_type close_type)
 {
        struct smbd_server_connection *sconn = fsp->conn->sconn;
-       struct smbd_smb2_request *smb2req, *nextreq;
+       struct smbXsrv_connection *xconn = NULL;
 
-       for (smb2req = sconn->smb2.requests; smb2req; smb2req = nextreq) {
-               struct smbd_smb2_lock_state *state = NULL;
-               files_struct *fsp_curr = NULL;
-               struct blocking_lock_record *blr = NULL;
-               const uint8_t *inhdr;
+       if (sconn != NULL && sconn->client != NULL) {
+               xconn = sconn->client->connections;
+       }
 
-               nextreq = smb2req->next;
+       for (; xconn != NULL; xconn = xconn->next) {
+               struct smbd_smb2_request *smb2req, *nextreq;
 
-               if (smb2req->subreq == NULL) {
-                       /* This message has been processed. */
-                       continue;
-               }
-               if (!tevent_req_is_in_progress(smb2req->subreq)) {
-                       /* This message has been processed. */
-                       continue;
-               }
+               for (smb2req = xconn->smb2.requests; smb2req; smb2req = nextreq) {
+                       struct smbd_smb2_lock_state *state = NULL;
+                       files_struct *fsp_curr = NULL;
+                       struct blocking_lock_record *blr = NULL;
+                       const uint8_t *inhdr;
 
-               inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
-               if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_LOCK) {
-                       /* Not a lock call. */
-                       continue;
-               }
+                       nextreq = smb2req->next;
 
-               state = tevent_req_data(smb2req->subreq,
-                               struct smbd_smb2_lock_state);
-               if (!state) {
-                       /* Strange - is this even possible ? */
-                       continue;
-               }
+                       if (smb2req->subreq == NULL) {
+                               /* This message has been processed. */
+                               continue;
+                       }
+                       if (!tevent_req_is_in_progress(smb2req->subreq)) {
+                               /* This message has been processed. */
+                               continue;
+                       }
 
-               fsp_curr = smb2req->compat_chain_fsp;
-               if (fsp_curr == NULL) {
-                       /* Strange - is this even possible ? */
-                       continue;
-               }
+                       inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
+                       if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_LOCK) {
+                               /* Not a lock call. */
+                               continue;
+                       }
 
-               if (fsp_curr != fsp) {
-                       /* It's not our fid */
-                       continue;
-               }
+                       state = tevent_req_data(smb2req->subreq,
+                                       struct smbd_smb2_lock_state);
+                       if (!state) {
+                               /* Strange - is this even possible ? */
+                               continue;
+                       }
 
-               blr = state->blr;
+                       fsp_curr = smb2req->compat_chain_fsp;
+                       if (fsp_curr == NULL) {
+                               /* Strange - is this even possible ? */
+                               continue;
+                       }
 
-               /* Remove the entries from the lock db. */
-               brl_lock_cancel(br_lck,
-                               blr->smblctx,
-                               messaging_server_id(sconn->msg_ctx),
-                               blr->offset,
-                               blr->count,
-                               blr->lock_flav,
-                               blr);
+                       if (fsp_curr != fsp) {
+                               /* It's not our fid */
+                               continue;
+                       }
 
-               /* Finally end the request. */
-               if (close_type == SHUTDOWN_CLOSE) {
-                       tevent_req_done(smb2req->subreq);
-               } else {
-                       tevent_req_nterror(smb2req->subreq,
-                               NT_STATUS_RANGE_NOT_LOCKED);
+                       blr = state->blr;
+
+                       /* Remove the entries from the lock db. */
+                       brl_lock_cancel(br_lck,
+                                       blr->smblctx,
+                                       messaging_server_id(sconn->msg_ctx),
+                                       blr->offset,
+                                       blr->count,
+                                       blr->lock_flav);
+
+                       /* Finally end the request. */
+                       if (close_type == SHUTDOWN_CLOSE) {
+                               tevent_req_done(smb2req->subreq);
+                       } else {
+                               tevent_req_nterror(smb2req->subreq,
+                                       NT_STATUS_RANGE_NOT_LOCKED);
+                       }
                }
        }
 }