From 0944797fef63123f0a984a05adcfe15a827661a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 Sep 2014 09:03:39 +0200 Subject: [PATCH] s3:smb2_lock: iterate over all sconn->client->connections Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam --- source3/smbd/smb2_lock.c | 190 ++++++++++++++++++++++----------------- 1 file changed, 109 insertions(+), 81 deletions(-) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 29abbb23672..d712290fe62 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -468,34 +468,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 smbXsrv_connection *xconn = sconn->conn; - 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 = xconn->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 != NULL && 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; + + psx_to = timeval_current_ofs(10, 0); + next_timeout = timeval_brl_min(&next_timeout, + &psx_to); } - - continue; } - - next_timeout = timeval_brl_min(&next_timeout, &blr->expire_time); } if (timeval_is_zero(&next_timeout)) { @@ -775,26 +789,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 smbXsrv_connection *xconn = sconn->conn; - struct smbd_smb2_request *smb2req, *nextreq; + struct smbXsrv_connection *xconn = NULL; - for (smb2req = xconn->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; - inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req); - if (SVAL(inhdr, SMB2_HDR_OPCODE) == SMB2_OP_LOCK) { - reprocess_blocked_smb2_lock(smb2req, tv_curr); + 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); + } } } @@ -810,66 +831,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 smbXsrv_connection *xconn = sconn->conn; - struct smbd_smb2_request *smb2req, *nextreq; + struct smbXsrv_connection *xconn = NULL; - 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; + 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); + 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); + } } } }