struct byte_range_lock *do_lock(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, BOOL blocking_lock, NTSTATUS *perr, uint32 *plock_pid) { struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; return NULL; } if (!lp_locking(fsp->conn->params)) { *perr = NT_STATUS_OK; return NULL; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { *perr = NT_STATUS_NO_MEMORY; return NULL; } *perr = brl_lock(br_lck, lock_pid, procid_self(), offset, count, lock_type, lock_flav, blocking_lock, plock_pid); if (lock_flav == WINDOWS_LOCK && fsp->current_lock_count != NO_LOCKING_COUNT) { /* blocking ie. pending, locks also count here, * as this is an efficiency counter to avoid checking * the lock db. on close. JRA. */ fsp->current_lock_count++; } else { /* Notice that this has had a POSIX lock request. * We can't count locks after this so forget them. */ fsp->current_lock_count = NO_LOCKING_COUNT; } return br_lck; }
static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { NTSTATUS status; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n", lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name )); if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { status = brl_lock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, offset, count, lock_type); if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) { /* * Try and get a POSIX lock on this range. * Note that this is ok if it is a read lock * overlapping on a different fd. JRA. */ if (!set_posix_lock(fsp, offset, count, lock_type)) { status = NT_STATUS_LOCK_NOT_GRANTED; /* * We failed to map - we must now remove the brl * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, offset, count, False); } } } return status; }
NTSTATUS do_lock(files_struct *fsp, uint16 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, BOOL *my_lock_ctx) { struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; if (!OPEN_FSP(fsp) || !fsp->can_lock) { return NT_STATUS_INVALID_HANDLE; } if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } status = brl_lock(br_lck, lock_pid, procid_self(), offset, count, lock_type, lock_flav, my_lock_ctx); byte_range_lock_destructor(br_lck); return status; }
bool push_blocking_lock_request( struct byte_range_lock *br_lck, struct smb_request *req, files_struct *fsp, int lock_timeout, int lock_num, uint32_t lock_pid, enum brl_type lock_type, enum brl_flavour lock_flav, uint64_t offset, uint64_t count, uint32_t blocking_pid) { struct blocking_lock_record *blr; NTSTATUS status; if(req_is_in_chain(req)) { DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); return False; } /* * Now queue an entry on the blocking lock queue. We setup * the expiration time here. */ blr = talloc(NULL, struct blocking_lock_record); if (blr == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); return False; } blr->next = NULL; blr->prev = NULL; blr->fsp = fsp; if (lock_timeout == -1) { blr->expire_time.tv_sec = 0; blr->expire_time.tv_usec = 0; /* Never expire. */ } else { blr->expire_time = timeval_current_ofs(lock_timeout/1000, (lock_timeout % 1000) * 1000); } blr->lock_num = lock_num; blr->lock_pid = lock_pid; blr->blocking_pid = blocking_pid; blr->lock_flav = lock_flav; blr->lock_type = lock_type; blr->offset = offset; blr->count = count; /* Specific brl_lock() implementations can fill this in. */ blr->blr_private = NULL; /* Add a pending lock record for this. */ status = brl_lock(smbd_messaging_context(), br_lck, lock_pid, procid_self(), offset, count, lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK, blr->lock_flav, lock_timeout ? True : False, /* blocking_lock. */ NULL, blr); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); TALLOC_FREE(blr); return False; } SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd); blr->req = talloc_move(blr, &req); DLIST_ADD_END(blocking_lock_queue, blr, struct blocking_lock_record *); recalc_brl_timeout(); /* Ensure we'll receive messages when this is unlocked. */ if (!blocking_lock_unlock_state) { messaging_register(smbd_messaging_context(), NULL, MSG_SMB_UNLOCK, received_unlock_msg); blocking_lock_unlock_state = true; } DEBUG(3,("push_blocking_lock_request: lock request blocked with " "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", (unsigned int)blr->expire_time.tv_sec, (unsigned int)blr->expire_time.tv_usec, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); return True; }
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; blocking_lock_record *blr, *tmp; BOOL my_lock_ctx = False; NTSTATUS status; if(in_chained_smb() ) { DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); return False; } /* * Now queue an entry on the blocking lock queue. We setup * the expiration time here. */ if((blr = SMB_MALLOC_P(blocking_lock_record)) == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); return False; } if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); SAFE_FREE(blr); return False; } blr->com_type = CVAL(inbuf,smb_com); blr->fsp = get_fsp_from_pkt(inbuf); blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; blr->lock_num = lock_num; blr->lock_pid = lock_pid; blr->offset = offset; blr->count = count; memcpy(blr->inbuf, inbuf, length); blr->length = length; /* Add a pending lock record for this. */ status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, lock_pid, sys_getpid(), blr->fsp->conn->cnum, offset, count, PENDING_LOCK, &my_lock_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); free_blocking_lock_record(blr); return False; } DLIST_ADD_END(blocking_lock_queue, blr, tmp); /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { message_register(MSG_SMB_UNLOCK, received_unlock_msg); set_lock_msg = True; } DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ srv_defer_sign_response(SVAL(inbuf,smb_mid)); return True; }
bool push_blocking_lock_request( struct byte_range_lock *br_lck, struct smb_request *req, files_struct *fsp, int lock_timeout, int lock_num, uint64_t smblctx, enum brl_type lock_type, enum brl_flavour lock_flav, uint64_t offset, uint64_t count, uint64_t blocking_smblctx) { struct smbd_server_connection *sconn = req->sconn; struct blocking_lock_record *blr; NTSTATUS status; if (req->smb2req) { return push_blocking_lock_request_smb2(br_lck, req, fsp, lock_timeout, lock_num, smblctx, lock_type, lock_flav, offset, count, blocking_smblctx); } if(req_is_in_chain(req)) { DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); return False; } /* * Now queue an entry on the blocking lock queue. We setup * the expiration time here. */ blr = talloc(NULL, struct blocking_lock_record); if (blr == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); return False; } blr->next = NULL; blr->prev = NULL; blr->fsp = fsp; if (lock_timeout == -1) { blr->expire_time.tv_sec = 0; blr->expire_time.tv_usec = 0; /* Never expire. */ } else { blr->expire_time = timeval_current_ofs_msec(lock_timeout); } blr->lock_num = lock_num; blr->smblctx = smblctx; blr->blocking_smblctx = blocking_smblctx; blr->lock_flav = lock_flav; blr->lock_type = lock_type; blr->offset = offset; blr->count = count; /* Specific brl_lock() implementations can fill this in. */ blr->blr_private = NULL; /* Add a pending lock record for this. */ status = brl_lock(req->sconn->msg_ctx, br_lck, smblctx, messaging_server_id(req->sconn->msg_ctx), offset, count, lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK, blr->lock_flav, True, NULL, blr); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); TALLOC_FREE(blr); return False; } SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd); blr->req = talloc_move(blr, &req); DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr, struct blocking_lock_record *); recalc_brl_timeout(sconn); /* Ensure we'll receive messages when this is unlocked. */ if (!sconn->smb1.locks.blocking_lock_unlock_state) { messaging_register(sconn->msg_ctx, sconn, MSG_SMB_UNLOCK, received_unlock_msg); sconn->smb1.locks.blocking_lock_unlock_state = true; } DEBUG(3,("push_blocking_lock_request: lock request blocked with " "expiry time (%u sec. %u usec) (+%d msec) for %s, name = %s\n", (unsigned int)blr->expire_time.tv_sec, (unsigned int)blr->expire_time.tv_usec, lock_timeout, fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp))); return True; }
BOOL do_lock(uint16 smbpid, files_struct * fsp, struct vfs_connection_struct *conn, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, uint32 *err) { BOOL ok = False; if (!lp_locking(conn->snum)) return (True); if (count == 0) { *err = NT_STATUS_ACCESS_DENIED; return False; } DEBUG(10, ("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n", lock_type_name(lock_type), (double)offset, (double)count, smbstrA(fsp->fsp_name))); if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum, smbpid, sys_getpid(), conn->snum, offset, count, lock_type); if (ok && lp_posix_locking(conn->snum)) { /* * Try and get a POSIX lock on this range. * Note that this is ok if it is a read lock * overlapping on a different fd. JRA. */ ok = set_posix_lock(fsp, offset, count, lock_type); if (!ok) { /* * We failed to map - we must now remove the brl * lock entry. */ (void)brl_unlock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum, smbpid, sys_getpid(), conn->snum, offset, count); } } } if (!ok) { *err = NT_STATUS_LOCK_NOT_GRANTED; return False; } return True; /* Got lock */ }
struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, files_struct *fsp, uint64_t smblctx, uint64_t count, uint64_t offset, enum brl_type lock_type, enum brl_flavour lock_flav, bool blocking_lock, NTSTATUS *perr, uint64_t *psmblctx, struct blocking_lock_record *blr) { struct byte_range_lock *br_lck = NULL; /* silently return ok on print files as we don't do locking there */ if (fsp->print_file) { *perr = NT_STATUS_OK; return NULL; } if (!fsp->can_lock) { *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; return NULL; } if (!lp_locking(fsp->conn->params)) { *perr = NT_STATUS_OK; return NULL; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f " "blocking_lock=%s requested for %s file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, blocking_lock ? "true" : "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { *perr = NT_STATUS_NO_MEMORY; return NULL; } *perr = brl_lock(msg_ctx, br_lck, smblctx, messaging_server_id(fsp->conn->sconn->msg_ctx), offset, count, lock_type, lock_flav, blocking_lock, psmblctx, blr); DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr))); increment_current_lock_count(fsp, lock_flav); return br_lck; }