(unsigned int)pls->context.tid,
server_id_str(talloc_tos(), &pls->context.pid) ));
- DEBUG(10,("start = %.0f, size = %.0f, fnum = %llu, %s %s\n",
- (double)pls->start,
- (double)pls->size,
- (unsigned long long)pls->fnum,
- lock_type_name(pls->lock_type),
- lock_flav_name(pls->lock_flav) ));
+ DEBUG(10, ("start = %ju, size = %ju, fnum = %ju, %s %s\n",
+ (uintmax_t)pls->start,
+ (uintmax_t)pls->size,
+ (uintmax_t)pls->fnum,
+ lock_type_name(pls->lock_type),
+ lock_flav_name(pls->lock_flav)));
}
unsigned int brl_num_locks(const struct byte_range_lock *brl)
return False;
}
- /* Locks on the same context con't conflict. Ignore fnum. */
+ /* Locks on the same context don't conflict. Ignore fnum. */
if (brl_same_context(&lck1->context, &lck2->context)) {
return False;
}
This is never used in the POSIX lock case.
****************************************************************************/
-static bool brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2)
+static bool brl_conflict_other(const struct lock_struct *lock, const struct lock_struct *lck2)
{
- if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
+ if (IS_PENDING_LOCK(lock->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
return False;
- if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
+ if (lock->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
return False;
/* POSIX flavour locks never conflict here - this is only called
in the read/write path. */
- if (lck1->lock_flav == POSIX_LOCK && lck2->lock_flav == POSIX_LOCK)
+ if (lock->lock_flav == POSIX_LOCK && lck2->lock_flav == POSIX_LOCK)
return False;
/*
* if the context is the same. JRA. See LOCKTEST7 in smbtorture.
*/
- if (!(lck2->lock_type == WRITE_LOCK && lck1->lock_type == READ_LOCK)) {
- if (brl_same_context(&lck1->context, &lck2->context) &&
- lck1->fnum == lck2->fnum)
+ if (!(lck2->lock_type == WRITE_LOCK && lock->lock_type == READ_LOCK)) {
+ if (brl_same_context(&lock->context, &lck2->context) &&
+ lock->fnum == lck2->fnum)
return False;
}
- return brl_overlap(lck1, lck2);
+ return brl_overlap(lock, lck2);
}
/****************************************************************************
{
if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start))
return True;
- if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size))
+ if ((lock->start >= pend_lock->start) && (lock->start < pend_lock->start + pend_lock->size))
return True;
return False;
}
}
brlock_db = db_open(NULL, lock_path("brlock.tdb"),
- lp_open_files_db_hash_size(), tdb_flags,
+ SMB_OPEN_DATABASE_TDB_HASH_SIZE, tdb_flags,
read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644,
- DBWRAP_LOCK_ORDER_2);
+ DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
if (!brlock_db) {
DEBUG(0,("Failed to open byte range locking database %s\n",
lock_path("brlock.tdb")));
NTSTATUS smb_vfs_call_brl_lock_windows(struct vfs_handle_struct *handle,
struct byte_range_lock *br_lck,
struct lock_struct *plock,
- bool blocking_lock,
- struct blocking_lock_record *blr)
+ bool blocking_lock)
{
VFS_FIND(brl_lock_windows);
return handle->fns->brl_lock_windows_fn(handle, br_lck, plock,
- blocking_lock, blr);
+ blocking_lock);
}
/****************************************************************************
enum brl_type lock_type,
enum brl_flavour lock_flav,
bool blocking_lock,
- uint64_t *psmblctx,
- struct blocking_lock_record *blr)
+ uint64_t *psmblctx)
{
NTSTATUS ret;
struct lock_struct lock;
}
#endif
-#ifdef DEVELOPER
- /* Quieten valgrind on test. */
- ZERO_STRUCT(lock);
-#endif
-
- lock.context.smblctx = smblctx;
- 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_type = lock_type;
- lock.lock_flav = lock_flav;
+ lock = (struct lock_struct) {
+ .context.smblctx = smblctx,
+ .context.pid = pid,
+ .context.tid = br_lck->fsp->conn->cnum,
+ .start = start,
+ .size = size,
+ .fnum = br_lck->fsp->fnum,
+ .lock_type = lock_type,
+ .lock_flav = lock_flav
+ };
if (lock_flav == WINDOWS_LOCK) {
ret = SMB_VFS_BRL_LOCK_WINDOWS(br_lck->fsp->conn, br_lck,
- &lock, blocking_lock, blr);
+ &lock, blocking_lock);
} else {
ret = brl_lock_posix(msg_ctx, br_lck, &lock);
}
return ret;
}
+static void brl_delete_lock_struct(struct lock_struct *locks,
+ unsigned num_locks,
+ unsigned del_idx)
+{
+ if (del_idx >= num_locks) {
+ return;
+ }
+ memmove(&locks[del_idx], &locks[del_idx+1],
+ sizeof(*locks) * (num_locks - del_idx - 1));
+}
+
/****************************************************************************
Unlock a range of bytes - Windows semantics.
****************************************************************************/
unlock_continue:
#endif
- /* Actually delete the lock. */
- if (i < br_lck->num_locks - 1) {
- memmove(&locks[i], &locks[i+1],
- sizeof(*locks)*((br_lck->num_locks-1) - i));
- }
-
+ brl_delete_lock_struct(locks, br_lck->num_locks, i);
br_lck->num_locks -= 1;
br_lck->modified = True;
if(lp_posix_locking(fsp->conn->params) && (lock_flav == WINDOWS_LOCK)) {
ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK);
- DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for %s file %s\n",
- (double)start, (double)size, ret ? "locked" : "unlocked",
- fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
+ DEBUG(10, ("brl_locktest: posix start=%ju len=%ju %s for %s "
+ "file %s\n", (uintmax_t)start, (uintmax_t)size,
+ ret ? "locked" : "unlocked",
+ fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
/* We need to return the inverse of is_posix_locked. */
ret = !ret;
if(lp_posix_locking(fsp->conn->params)) {
bool ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK);
- DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for %s file %s\n",
- (double)*pstart, (double)*psize, ret ? "locked" : "unlocked",
- fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
+ DEBUG(10, ("brl_lockquery: posix start=%ju len=%ju %s for %s "
+ "file %s\n", (uintmax_t)*pstart,
+ (uintmax_t)*psize, ret ? "locked" : "unlocked",
+ fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
if (ret) {
/* Hmmm. No clue what to set smblctx to - use -1. */
bool smb_vfs_call_brl_cancel_windows(struct vfs_handle_struct *handle,
struct byte_range_lock *br_lck,
- struct lock_struct *plock,
- struct blocking_lock_record *blr)
+ struct lock_struct *plock)
{
VFS_FIND(brl_cancel_windows);
- return handle->fns->brl_cancel_windows_fn(handle, br_lck, plock, blr);
+ return handle->fns->brl_cancel_windows_fn(handle, br_lck, plock);
}
/****************************************************************************
struct server_id pid,
br_off start,
br_off size,
- enum brl_flavour lock_flav,
- struct blocking_lock_record *blr)
+ enum brl_flavour lock_flav)
{
bool ret;
struct lock_struct lock;
if (lock_flav == WINDOWS_LOCK) {
ret = SMB_VFS_BRL_CANCEL_WINDOWS(br_lck->fsp->conn, br_lck,
- &lock, blr);
+ &lock);
} else {
ret = brl_lock_cancel_default(br_lck, &lock);
}
return False;
}
- if (i < br_lck->num_locks - 1) {
- /* Found this particular pending lock - delete it */
- memmove(&locks[i], &locks[i+1],
- sizeof(*locks)*((br_lck->num_locks-1) - i));
- }
-
+ brl_delete_lock_struct(locks, br_lck->num_locks, i);
br_lck->num_locks -= 1;
br_lck->modified = True;
return True;
bool brl_mark_disconnected(struct files_struct *fsp)
{
uint32_t tid = fsp->conn->cnum;
- uint64_t smblctx = fsp->op->global->open_persistent_id;
+ uint64_t smblctx;
uint64_t fnum = fsp->fnum;
unsigned int i;
struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
struct byte_range_lock *br_lck = NULL;
+ if (fsp->op == NULL) {
+ return false;
+ }
+
+ smblctx = fsp->op->global->open_persistent_id;
+
if (!fsp->op->global->durable) {
return false;
}
bool brl_reconnect_disconnected(struct files_struct *fsp)
{
uint32_t tid = fsp->conn->cnum;
- uint64_t smblctx = fsp->op->global->open_persistent_id;
+ uint64_t smblctx;
uint64_t fnum = fsp->fnum;
unsigned int i;
struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
struct byte_range_lock *br_lck = NULL;
+ if (fsp->op == NULL) {
+ return false;
+ }
+
+ smblctx = fsp->op->global->open_persistent_id;
+
if (!fsp->op->global->durable) {
return false;
}
/****************************************************************************
Ensure this set of lock entries is valid.
****************************************************************************/
-static bool validate_lock_entries(TALLOC_CTX *mem_ctx,
- unsigned int *pnum_entries, struct lock_struct **pplocks,
+static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks,
bool keep_disconnected)
{
unsigned int i;
- unsigned int num_valid_entries = 0;
struct lock_struct *locks = *pplocks;
- TALLOC_CTX *frame = talloc_stackframe();
+ unsigned int num_entries = *pnum_entries;
+ TALLOC_CTX *frame;
struct server_id *ids;
bool *exists;
- ids = talloc_array(frame, struct server_id, *pnum_entries);
+ if (num_entries == 0) {
+ return true;
+ }
+
+ frame = talloc_stackframe();
+
+ ids = talloc_array(frame, struct server_id, num_entries);
if (ids == NULL) {
DEBUG(0, ("validate_lock_entries: "
"talloc_array(struct server_id, %u) failed\n",
- *pnum_entries));
+ num_entries));
talloc_free(frame);
return false;
}
- exists = talloc_array(frame, bool, *pnum_entries);
+ exists = talloc_array(frame, bool, num_entries);
if (exists == NULL) {
DEBUG(0, ("validate_lock_entries: "
"talloc_array(bool, %u) failed\n",
- *pnum_entries));
+ num_entries));
talloc_free(frame);
return false;
}
- for (i = 0; i < *pnum_entries; i++) {
+ for (i = 0; i < num_entries; i++) {
ids[i] = locks[i].context.pid;
}
- if (!serverids_exist(ids, *pnum_entries, exists)) {
+ if (!serverids_exist(ids, num_entries, exists)) {
DEBUG(3, ("validate_lock_entries: serverids_exists failed\n"));
talloc_free(frame);
return false;
}
- for (i = 0; i < *pnum_entries; i++) {
+ i = 0;
+
+ while (i < num_entries) {
if (exists[i]) {
- num_valid_entries++;
+ i++;
continue;
}
if (keep_disconnected &&
server_id_is_disconnected(&ids[i]))
{
- num_valid_entries++;
+ i++;
continue;
}
- /* This process no longer exists - mark this
- entry as invalid by zeroing it. */
- ZERO_STRUCTP(&locks[i]);
+ /* This process no longer exists */
+
+ brl_delete_lock_struct(locks, num_entries, i);
+ num_entries -= 1;
}
TALLOC_FREE(frame);
- if (num_valid_entries != *pnum_entries) {
- struct lock_struct *new_lock_data = NULL;
-
- if (num_valid_entries) {
- new_lock_data = talloc_array(
- mem_ctx, struct lock_struct,
- num_valid_entries);
- if (!new_lock_data) {
- DEBUG(3, ("malloc fail\n"));
- return False;
- }
-
- num_valid_entries = 0;
- for (i = 0; i < *pnum_entries; i++) {
- struct lock_struct *lock_data = &locks[i];
- if (lock_data->context.smblctx &&
- lock_data->context.tid) {
- /* Valid (nonzero) entry - copy it. */
- memcpy(&new_lock_data[num_valid_entries],
- lock_data, sizeof(struct lock_struct));
- num_valid_entries++;
- }
- }
- }
-
- TALLOC_FREE(*pplocks);
- *pplocks = new_lock_data;
- *pnum_entries = num_valid_entries;
- }
+ *pnum_entries = num_entries;
return True;
}
/* Ensure the lock db is clean of entries from invalid processes. */
- if (!validate_lock_entries(talloc_tos(), &num_locks, &locks, true)) {
+ if (!validate_lock_entries(&num_locks, &locks, true)) {
TALLOC_FREE(locks);
return -1; /* Terminate traversal */
}
* So we need to clean the disconnected brl entry.
*/
- if (!validate_lock_entries(br_lck, &br_lck->num_locks,
+ if (!validate_lock_entries(&br_lck->num_locks,
&br_lck->lock_data, false)) {
TALLOC_FREE(br_lck);
return NULL;
if ((data.dsize % sizeof(struct lock_struct)) == 1) {
br_lock->have_read_oplocks = (data.dptr[data.dsize-1] == 1);
+ } else {
+ br_lock->have_read_oplocks = false;
}
DEBUG(10, ("Got %d bytes, have_read_oplocks: %s\n", (int)data.dsize,
make_tdb_data((uint8_t *)&fsp->file_id,
sizeof(fsp->file_id)),
brl_get_locks_readonly_parser, &state);
- if (!NT_STATUS_IS_OK(status)) {
+
+ if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_FOUND)) {
+ /*
+ * No locks on this file. Return an empty br_lock.
+ */
+ br_lock = talloc(fsp, struct byte_range_lock);
+ if (br_lock == NULL) {
+ goto fail;
+ }
+
+ br_lock->have_read_oplocks = false;
+ br_lock->num_locks = 0;
+ br_lock->lock_data = NULL;
+
+ } else if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not parse byte range lock record: "
"%s\n", nt_errstr(status)));
goto fail;
const struct server_id *i2 = (const struct server_id *)p2;
if (i1->pid < i2->pid) return -1;
- if (i2->pid > i2->pid) return 1;
+ if (i1->pid > i2->pid) return 1;
return 0;
}