diff options
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/brlock.c | 66 | ||||
-rw-r--r-- | source3/locking/locking.c | 81 |
2 files changed, 95 insertions, 52 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index edba4ed30a..d12c4affc3 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -228,7 +228,7 @@ static bool brl_pending_overlap(const struct lock_struct *lock, const struct loc app depends on this ? ****************************************************************************/ -static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, bool blocking_lock) +NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, bool blocking_lock) { if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { /* amazing the little things you learn with a test @@ -305,14 +305,16 @@ static int lock_compare(const struct lock_struct *lck1, Lock a range of bytes - Windows lock semantics. ****************************************************************************/ -static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, - struct lock_struct *plock, bool blocking_lock) +NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck, + struct lock_struct *plock, bool blocking_lock) { unsigned int i; files_struct *fsp = br_lck->fsp; struct lock_struct *locks = br_lck->lock_data; NTSTATUS status; + SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); + for (i=0; i < br_lck->num_locks; i++) { /* Do any Windows or POSIX locks conflict ? */ if (brl_conflict(&locks[i], plock)) { @@ -781,7 +783,8 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, enum brl_type lock_type, enum brl_flavour lock_flav, bool blocking_lock, - uint32 *psmbpid) + uint32 *psmbpid, + struct blocking_lock_record *blr) { NTSTATUS ret; struct lock_struct lock; @@ -807,7 +810,8 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, lock.lock_flav = lock_flav; if (lock_flav == WINDOWS_LOCK) { - ret = brl_lock_windows(br_lck, &lock, blocking_lock); + ret = SMB_VFS_BRL_LOCK_WINDOWS(br_lck->fsp->conn, br_lck, + &lock, blocking_lock, blr); } else { ret = brl_lock_posix(msg_ctx, br_lck, &lock); } @@ -828,7 +832,7 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, Unlock a range of bytes - Windows semantics. ****************************************************************************/ -static bool brl_unlock_windows(struct messaging_context *msg_ctx, +bool brl_unlock_windows_default(struct messaging_context *msg_ctx, struct byte_range_lock *br_lck, const struct lock_struct *plock) { @@ -836,6 +840,8 @@ static bool brl_unlock_windows(struct messaging_context *msg_ctx, struct lock_struct *locks = br_lck->lock_data; enum brl_type deleted_lock_type = READ_LOCK; /* shut the compiler up.... */ + SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); + #if ZERO_ZERO /* Delete write locks by preference... The lock list is sorted in the zero zero case. */ @@ -1130,7 +1136,8 @@ bool brl_unlock(struct messaging_context *msg_ctx, lock.lock_flav = lock_flav; if (lock_flav == WINDOWS_LOCK) { - return brl_unlock_windows(msg_ctx, br_lck, &lock); + return SMB_VFS_BRL_UNLOCK_WINDOWS(br_lck->fsp->conn, msg_ctx, + br_lck, &lock); } else { return brl_unlock_posix(msg_ctx, br_lck, &lock); } @@ -1266,32 +1273,54 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, /**************************************************************************** Remove a particular pending lock. ****************************************************************************/ - bool brl_lock_cancel(struct byte_range_lock *br_lck, uint32 smbpid, struct server_id pid, br_off start, br_off size, - enum brl_flavour lock_flav) + enum brl_flavour lock_flav, + struct blocking_lock_record *blr) +{ + bool ret; + struct lock_struct lock; + + lock.context.smbpid = smbpid; + lock.context.pid = pid; + lock.context.tid = br_lck->fsp->conn->cnum; + lock.start = start; + lock.size = size; + lock.fnum = br_lck->fsp->fnum; + lock.lock_flav = lock_flav; + /* lock.lock_type doesn't matter */ + + if (lock_flav == WINDOWS_LOCK) { + ret = SMB_VFS_BRL_CANCEL_WINDOWS(br_lck->fsp->conn, br_lck, + &lock, blr); + } else { + ret = brl_lock_cancel_default(br_lck, &lock); + } + + return ret; +} + +bool brl_lock_cancel_default(struct byte_range_lock *br_lck, + struct lock_struct *plock) { unsigned int i; struct lock_struct *locks = br_lck->lock_data; - struct lock_context context; - context.smbpid = smbpid; - context.pid = pid; - context.tid = br_lck->fsp->conn->cnum; + SMB_ASSERT(plock); for (i = 0; i < br_lck->num_locks; i++) { struct lock_struct *lock = &locks[i]; /* For pending locks we *always* care about the fnum. */ - if (brl_same_context(&lock->context, &context) && - lock->fnum == br_lck->fsp->fnum && + if (brl_same_context(&lock->context, &plock->context) && + lock->fnum == plock->fnum && IS_PENDING_LOCK(lock->lock_type) && - lock->lock_flav == lock_flav && - lock->start == start && - lock->size == size) { + lock->lock_flav == plock->lock_flav && + lock->start == plock->start && + lock->size == plock->size) { break; } } @@ -1460,7 +1489,6 @@ void brl_close_fnum(struct messaging_context *msg_ctx, /**************************************************************************** Ensure this set of lock entries is valid. ****************************************************************************/ - static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks) { unsigned int i; diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b342fa9b1e..902b230e60 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -177,6 +177,34 @@ NTSTATUS query_lock(files_struct *fsp, return status; } +static void increment_current_lock_count(files_struct *fsp, + enum brl_flavour lock_flav) +{ + 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; + } +} + +static void decrement_current_lock_count(files_struct *fsp, + enum brl_flavour lock_flav) +{ + if (lock_flav == WINDOWS_LOCK && + fsp->current_lock_count != NO_LOCKING_COUNT) { + SMB_ASSERT(fsp->current_lock_count > 0); + fsp->current_lock_count--; + } +} + /**************************************************************************** Utility function called by locking requests. ****************************************************************************/ @@ -190,7 +218,8 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, enum brl_flavour lock_flav, bool blocking_lock, NTSTATUS *perr, - uint32 *plock_pid) + uint32 *plock_pid, + struct blocking_lock_record *blr) { struct byte_range_lock *br_lck = NULL; @@ -206,9 +235,11 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, /* 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", + DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f " + "blocking_lock=%s 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 )); + (double)offset, (double)count, blocking_lock ? "true" : + "false", fsp->fnum, fsp->fsp_name)); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { @@ -225,22 +256,12 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, lock_type, lock_flav, blocking_lock, - plock_pid); + plock_pid, + blr); - 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; - } + DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr))); + increment_current_lock_count(fsp, lock_flav); return br_lck; } @@ -289,12 +310,7 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx, return NT_STATUS_RANGE_NOT_LOCKED; } - if (lock_flav == WINDOWS_LOCK && - fsp->current_lock_count != NO_LOCKING_COUNT) { - SMB_ASSERT(fsp->current_lock_count > 0); - fsp->current_lock_count--; - } - + decrement_current_lock_count(fsp, lock_flav); return NT_STATUS_OK; } @@ -306,11 +322,14 @@ NTSTATUS do_lock_cancel(files_struct *fsp, uint32 lock_pid, uint64_t count, uint64_t offset, - enum brl_flavour lock_flav) + enum brl_flavour lock_flav, + struct blocking_lock_record *blr) { bool ok = False; struct byte_range_lock *br_lck = NULL; - + + SMB_ASSERT(blr); + if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; @@ -333,8 +352,9 @@ NTSTATUS do_lock_cancel(files_struct *fsp, procid_self(), offset, count, - lock_flav); - + lock_flav, + blr); + TALLOC_FREE(br_lck); if (!ok) { @@ -342,12 +362,7 @@ NTSTATUS do_lock_cancel(files_struct *fsp, 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--; - } - + decrement_current_lock_count(fsp, lock_flav); return NT_STATUS_OK; } |