void smbd_cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck, enum file_close_type close_type) { struct smbd_server_connection *sconn = fsp->conn->sconn; struct blocking_lock_record *blr, *blr_cancelled, *next = NULL; if (sconn->using_smb2) { cancel_pending_lock_requests_by_fid_smb2(fsp, br_lck, close_type); return; } for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { unsigned char locktype = 0; next = blr->next; if (blr->fsp->fnum != fsp->fnum) { continue; } if (blr->req->cmd == SMBlockingX) { locktype = CVAL(blr->req->vwv+3, 0); } DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " "request type %d for file %s, %s\n", blr->req->cmd, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp))); blr_cancelled = blocking_lock_cancel_smb1(fsp, blr->smblctx, blr->offset, blr->count, blr->lock_flav, locktype, NT_STATUS_RANGE_NOT_LOCKED); SMB_ASSERT(blr_cancelled == blr); brl_lock_cancel(br_lck, blr->smblctx, messaging_server_id(sconn->msg_ctx), blr->offset, blr->count, blr->lock_flav, blr); /* We're closing the file fsp here, so ensure * we don't have a dangling pointer. */ blr->fsp = NULL; } }
NTSTATUS do_lock_cancel(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_flavour lock_flav) { BOOL ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } ok = brl_lock_cancel(br_lck, lock_pid, procid_self(), offset, count, lock_flav); TALLOC_FREE(br_lck); if (!ok) { DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" )); return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } if (lock_flav == WINDOWS_LOCK && fsp->current_lock_count != NO_LOCKING_COUNT) { SMB_ASSERT(fsp->current_lock_count > 0); fsp->current_lock_count--; } return NT_STATUS_OK; }
NTSTATUS do_lock_cancel(files_struct *fsp, uint64 smblctx, uint64_t count, uint64_t offset, enum brl_flavour lock_flav, struct blocking_lock_record *blr) { bool ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for %s file %s\n", (double)offset, (double)count, fsp_fnum_dbg(fsp), fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } ok = brl_lock_cancel(br_lck, smblctx, messaging_server_id(fsp->conn->sconn->msg_ctx), offset, count, lock_flav, blr); TALLOC_FREE(br_lck); if (!ok) { DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" )); return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } decrement_current_lock_count(fsp, lock_flav); return NT_STATUS_OK; }
void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) { struct blocking_lock_record *blr, *blr_cancelled, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { unsigned char locktype = 0; next = blr->next; if (blr->fsp->fnum != fsp->fnum) { continue; } if (blr->req->cmd == SMBlockingX) { locktype = CVAL(blr->req->vwv+3, 0); } DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " "request type %d for file %s fnum = %d\n", blr->req->cmd, fsp->fsp_name, fsp->fnum)); blr_cancelled = blocking_lock_cancel(fsp, blr->lock_pid, blr->offset, blr->count, blr->lock_flav, locktype, NT_STATUS_RANGE_NOT_LOCKED); SMB_ASSERT(blr_cancelled == blr); brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav, blr); /* We're closing the file fsp here, so ensure * we don't have a dangling pointer. */ blr->fsp = NULL; } }
void remove_pending_lock_requests_by_mid_smb1( struct smbd_server_connection *sconn, uint64_t mid) { struct blocking_lock_record *blr, *next = NULL; for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { files_struct *fsp; struct byte_range_lock *br_lck; next = blr->next; if (blr->req->mid != mid) { continue; } fsp = blr->fsp; br_lck = brl_get_locks(talloc_tos(), fsp); if (br_lck) { DEBUG(10, ("remove_pending_lock_requests_by_mid_smb1 - " "removing request type %d for file %s, %s\n", blr->req->cmd, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp))); brl_lock_cancel(br_lck, blr->smblctx, messaging_server_id(sconn->msg_ctx), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); TALLOC_FREE(blr); } }
void remove_pending_lock_requests_by_mid(int mid) { struct blocking_lock_record *blr, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { files_struct *fsp; struct byte_range_lock *br_lck; next = blr->next; if (blr->req->mid != mid) { continue; } fsp = blr->fsp; br_lck = brl_get_locks(talloc_tos(), fsp); if (br_lck) { DEBUG(10, ("remove_pending_lock_requests_by_mid - " "removing request type %d for file %s fnum " "= %d\n", blr->req->cmd, fsp->fsp_name, fsp->fnum )); brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(blocking_lock_queue, blr); TALLOC_FREE(blr); } }
void process_blocking_lock_queue(void) { struct timeval tv_curr = timeval_current(); struct blocking_lock_record *blr, *next = NULL; bool recalc_timeout = False; /* * Go through the queue and see if we can get any of the locks. */ for (blr = blocking_lock_queue; blr; blr = next) { next = blr->next; /* * Go through the remaining locks and try and obtain them. * The call returns True if all locks were obtained successfully * and False if we still need to wait. */ DEBUG(10, ("Processing BLR = %p\n", blr)); if(blocking_lock_record_process(blr)) { struct byte_range_lock *br_lck = brl_get_locks( talloc_tos(), blr->fsp); DEBUG(10, ("BLR_process returned true: cancelling and " "removing lock. BLR = %p\n", blr)); if (br_lck) { brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } DLIST_REMOVE(blocking_lock_queue, blr); TALLOC_FREE(blr); recalc_timeout = True; continue; } /* * We couldn't get the locks for this record on the list. * If the time has expired, return a lock error. */ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { struct byte_range_lock *br_lck = brl_get_locks( talloc_tos(), blr->fsp); DEBUG(10, ("Lock timed out! BLR = %p\n", blr)); /* * Lock expired - throw away all previously * obtained locks and return lock error. */ if (br_lck) { DEBUG(5,("process_blocking_lock_queue: " "pending lock fnum = %d for file %s " "timed out.\n", blr->fsp->fnum, blr->fsp->fsp_name )); brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(blocking_lock_queue, blr); TALLOC_FREE(blr); recalc_timeout = True; } } if (recalc_timeout) { recalc_brl_timeout(); } }
void process_blocking_lock_queue(struct smbd_server_connection *sconn) { struct timeval tv_curr = timeval_current(); struct blocking_lock_record *blr, *next = NULL; if (sconn->using_smb2) { process_blocking_lock_queue_smb2(sconn, tv_curr); return; } /* * Go through the queue and see if we can get any of the locks. */ for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { next = blr->next; /* * Go through the remaining locks and try and obtain them. * The call returns True if all locks were obtained successfully * and False if we still need to wait. */ DEBUG(10, ("Processing BLR = %p\n", blr)); /* We use set_current_service so connections with * pending locks are not marked as idle. */ set_current_service(blr->fsp->conn, SVAL(blr->req->inbuf,smb_flg), false); if(blocking_lock_record_process(blr)) { struct byte_range_lock *br_lck = brl_get_locks( talloc_tos(), blr->fsp); DEBUG(10, ("BLR_process returned true: cancelling and " "removing lock. BLR = %p\n", blr)); if (br_lck) { brl_lock_cancel(br_lck, blr->smblctx, messaging_server_id(sconn->msg_ctx), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); TALLOC_FREE(blr); continue; } /* * We couldn't get the locks for this record on the list. * If the time has expired, return a lock error. */ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { struct byte_range_lock *br_lck = brl_get_locks( talloc_tos(), blr->fsp); DEBUG(10, ("Lock timed out! BLR = %p\n", blr)); /* * Lock expired - throw away all previously * obtained locks and return lock error. */ if (br_lck) { DEBUG(5,("process_blocking_lock_queue: " "pending lock for %s, file %s " "timed out.\n", fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp))); brl_lock_cancel(br_lck, blr->smblctx, messaging_server_id(sconn->msg_ctx), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); TALLOC_FREE(blr); } } recalc_brl_timeout(sconn); }