From fef617c31bd4a8be09449d6bc726c729ae758423 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 02:55:47 +0000 Subject: r3012: added initial support for byte range locking in the posix vfs. This is enough for us to pass locktest, but does not yet support lock timeouts and some of the other esoteric features. (This used to be commit 58a92abd88f190bc60894a68e0528e95ae33fe39) --- source4/ntvfs/common/brlock.c | 418 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 source4/ntvfs/common/brlock.c (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c new file mode 100644 index 0000000000..0eb644e943 --- /dev/null +++ b/source4/ntvfs/common/brlock.c @@ -0,0 +1,418 @@ +/* + Unix SMB/CIFS implementation. + + generic byte range locking code + + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Jeremy Allison 1992-2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* This module implements a tdb based byte range locking service, + replacing the fcntl() based byte range locking previously + used. This allows us to provide the same semantics as NT */ + +#include "includes.h" + +struct brl_context { + struct tdb_wrap *w; + servid_t server; + uint16_t tid; +}; + +/* + in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies + a file. For a local posix filesystem this will usually be a combination + of the device and inode numbers of the file, but it can be anything + that uniquely idetifies a file for locking purposes, as long + as it is applied consistently. +*/ + +/* + the lock context contains the elements that define whether one + lock is the same as another lock +*/ +struct lock_context { + servid_t server; + uint16_t smbpid; + uint16_t tid; +}; + +/* The data in brlock records is an unsorted linear array of these + records. It is unnecessary to store the count as tdb provides the + size of the record */ +struct lock_struct { + struct lock_context context; + uint64_t start; + uint64_t size; + uint16_t fnum; + enum brl_type lock_type; +}; + +/* + Open up the brlock.tdb database. Close it down using + talloc_free() +*/ +void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid) +{ + char *path; + struct brl_context *brl; + + brl = talloc_p(mem_ctx, struct brl_context); + if (brl == NULL) { + return NULL; + } + + path = lock_path(brl, "brlock.tdb"); + brl->w = tdb_wrap_open(brl, path, 0, + TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, 0600); + talloc_free(path); + if (brl->w == NULL) { + talloc_free(brl); + return NULL; + } + + brl->server = server; + brl->tid = tid; + + return (void *)brl; +} + + +/* + see if two locking contexts are equal +*/ +static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) +{ + return (ctx1->server == ctx2->server && + ctx1->smbpid == ctx2->smbpid && + ctx1->tid == ctx2->tid); +} + +/* + See if lock2 can be added when lock1 is in place. +*/ +static BOOL brl_conflict(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { + return False; + } + + if (brl_same_context(&lck1->context, &lck2->context) && + lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) { + return False; + } + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) { + return False; + } + + return True; +} + + +/* + Check to see if this lock conflicts, but ignore our own locks on the + same fnum only. +*/ +static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) + return False; + + if (brl_same_context(&lck1->context, &lck2->context) && + lck1->fnum == lck2->fnum) { + return False; + } + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) + return False; + + return True; +} + + + +/* + Lock a range of bytes. +*/ +NTSTATUS brl_lock(void *brl_ctx, + DATA_BLOB *file_key, + uint16_t smbpid, + uint16_t fnum, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct lock, *locks; + char *tp; + NTSTATUS status; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + + lock.context.smbpid = smbpid; + lock.context.server = brl->server; + lock.context.tid = brl->tid; + lock.start = start; + lock.size = size; + lock.fnum = fnum; + lock.lock_type = lock_type; + + if (dbuf.dptr) { + /* there are existing locks - make sure they don't conflict */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + for (i=0; iw->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + + fail: + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + Unlock a range of bytes. +*/ +NTSTATUS brl_unlock(void *brl_ctx, + DATA_BLOB *file_key, + uint16_t smbpid, + uint16_t fnum, + uint64_t start, uint64_t size) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct *locks; + struct lock_context context; + NTSTATUS status; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_RANGE_NOT_LOCKED; + } + + context.smbpid = smbpid; + context.server = brl->server; + context.tid = brl->tid; + + /* there are existing locks - find a match */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + for (i=0; icontext, &context) && + lock->fnum == fnum && + lock->start == start && + lock->size == size) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + dbuf.dsize -= sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + /* we didn't find it */ + status = NT_STATUS_RANGE_NOT_LOCKED; + + fail: + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + Test if we are allowed to perform IO on a region of an open file +*/ +NTSTATUS brl_locktest(void *brl_ctx, + DATA_BLOB *file_key, + uint16_t fnum, + uint16 smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct lock, *locks; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (dbuf.dptr == NULL) { + return NT_STATUS_OK; + } + + lock.context.smbpid = smbpid; + lock.context.server = brl->server; + lock.context.tid = brl->tid; + lock.start = start; + lock.size = size; + lock.fnum = fnum; + lock.lock_type = lock_type; + + /* there are existing locks - make sure they don't conflict */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; idata; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + + /* there are existing locks - remove any for this fnum */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; icontext.tid == brl->tid && + lock->context.server == brl->server && + lock->fnum == fnum) { + /* found it - delete it */ + if (count > 1 && i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + i--; + dcount++; + } + } + + status = NT_STATUS_OK; + + if (count == 0) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } else if (dcount != 0) { + dbuf.dsize -= dcount * sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + + return status; +} + -- cgit From d0cc571e30bf49443ac7d1b1a0b896ee72d7d9a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 07:40:17 +0000 Subject: r3029: implemented byte range lock timeouts. This adds a pvfs_wait_message() routine which uses the new messaging system, event timers and talloc destructors to give a nice generic async event handling system with a easy to use interface. The extensions to pvfs_lock.c are based on calls to pvfs_wait_message() routines. We now pass all of our smbtorture locking tests, although while writing this code I have thought of some additonal tests that should be added, particularly for lock cancel operations. I'll work on that soon. This commit also extends the smbtorture lock tests to test the rather weird 0xEEFFFFFF locking semantics that I have discovered in win2003. Win2003 treats the 0xEEFFFFFF boundary as special, and will give different error codes on either side of it. Locks on both sides are allowed, the only difference is which error code is given when a lock is denied. Anyone like to hazard a guess as to why? It has me stumped. (This used to be commit 4395c0557ab175d6a8dd99df03c266325949ffa5) --- source4/ntvfs/common/brlock.c | 272 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 244 insertions(+), 28 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 0eb644e943..792ee52ad5 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -27,12 +27,6 @@ #include "includes.h" -struct brl_context { - struct tdb_wrap *w; - servid_t server; - uint16_t tid; -}; - /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies a file. For a local posix filesystem this will usually be a combination @@ -60,13 +54,25 @@ struct lock_struct { uint64_t size; uint16_t fnum; enum brl_type lock_type; + void *notify_ptr; +}; + +struct brl_context { + struct tdb_wrap *w; + servid_t server; + uint16_t tid; + void *messaging_ctx; + struct lock_struct last_lock_failure; }; + /* Open up the brlock.tdb database. Close it down using - talloc_free() + talloc_free(). We need the messaging_ctx to allow for + pending lock notifications. */ -void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid) +void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, + void *messaging_ctx) { char *path; struct brl_context *brl; @@ -88,6 +94,8 @@ void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid) brl->server = server; brl->tid = tid; + brl->messaging_ctx = messaging_ctx; + ZERO_STRUCT(brl->last_lock_failure); return (void *)brl; } @@ -103,12 +111,31 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx ctx1->tid == ctx2->tid); } +/* + see if lck1 and lck2 overlap +*/ +static BOOL brl_overlap(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) { + return False; + } + return True; +} + /* See if lock2 can be added when lock1 is in place. */ static BOOL brl_conflict(struct lock_struct *lck1, struct lock_struct *lck2) { + /* pending locks don't conflict with anything */ + if (lck1->lock_type >= PENDING_READ_LOCK || + lck2->lock_type >= PENDING_READ_LOCK) { + return False; + } + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { return False; } @@ -118,12 +145,7 @@ static BOOL brl_conflict(struct lock_struct *lck1, return False; } - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) { - return False; - } - - return True; + return brl_overlap(lck1, lck2); } @@ -133,32 +155,68 @@ static BOOL brl_conflict(struct lock_struct *lck1, */ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) { + /* pending locks don't conflict with anything */ + if (lck1->lock_type >= PENDING_READ_LOCK || + lck2->lock_type >= PENDING_READ_LOCK) { + return False; + } + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) return False; + /* + * note that incoming write calls conflict with existing READ + * locks even if the context is the same. JRA. See LOCKTEST7 + * in smbtorture. + */ if (brl_same_context(&lck1->context, &lck2->context) && - lck1->fnum == lck2->fnum) { + lck1->fnum == lck2->fnum && + (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { return False; } - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) - return False; - - return True; + return brl_overlap(lck1, lck2); } +/* + amazingly enough, w2k3 "remembers" whether the last lock failure + is the same as this one and changes its error code. I wonder if any + app depends on this? +*/ +static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) +{ + if (brl_same_context(&lock->context, &brl->last_lock_failure.context) && + lock->fnum == brl->last_lock_failure.fnum && + lock->start == brl->last_lock_failure.start && + lock->size == brl->last_lock_failure.size) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + brl->last_lock_failure = *lock; + if (lock->start >= 0xEF000000) { + /* amazing the little things you learn with a test + suite. Locks beyond this offset (as a 64 bit + number!) always generate the conflict error + code. */ + return NT_STATUS_FILE_LOCK_CONFLICT; + } + return NT_STATUS_LOCK_NOT_GRANTED; +} /* - Lock a range of bytes. + Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in + which case a real lock is first tried, and if that fails then a + pending lock is created. When the pending lock is triggered (by + someone else closing an overlapping lock range) a messaging + notification is sent, identified by the notify_ptr */ NTSTATUS brl_lock(void *brl_ctx, DATA_BLOB *file_key, uint16_t smbpid, uint16_t fnum, uint64_t start, uint64_t size, - enum brl_type lock_type) + enum brl_type lock_type, + void *notify_ptr) { struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; @@ -174,6 +232,20 @@ NTSTATUS brl_lock(void *brl_ctx, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + /* if this is a pending lock, then with the chainlock held we + try to get the real lock. If we succeed then we don't need + to make it pending. This prevents a possible race condition + where the pending lock gets created after the lock that is + preventing the real lock gets removed */ + if (lock_type >= PENDING_READ_LOCK) { + enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); + status = brl_lock(brl_ctx, file_key, smbpid, fnum, start, size, rw, NULL); + if (NT_STATUS_IS_OK(status)) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + dbuf = tdb_fetch(brl->w->tdb, kbuf); lock.context.smbpid = smbpid; @@ -183,6 +255,7 @@ NTSTATUS brl_lock(void *brl_ctx, lock.size = size; lock.fnum = fnum; lock.lock_type = lock_type; + lock.notify_ptr = notify_ptr; if (dbuf.dptr) { /* there are existing locks - make sure they don't conflict */ @@ -190,7 +263,7 @@ NTSTATUS brl_lock(void *brl_ctx, count = dbuf.dsize / sizeof(*locks); for (i=0; iw->tdb, kbuf); + + /* the caller needs to know if the real lock was granted. If + we have reached here then it must be a pending lock that + was granted, so tell them the lock failed */ + if (lock_type >= PENDING_READ_LOCK) { + return brl_lock_failed(brl, &lock); + } + return NT_STATUS_OK; fail: @@ -224,6 +305,57 @@ NTSTATUS brl_lock(void *brl_ctx, } +/* + we are removing a lock that might be holding up a pending lock. Scan for pending + locks that cover this range and if we find any then notify the server that it should + retry the lock +*/ +static void brl_notify_unlock(struct brl_context *brl, + struct lock_struct *locks, int count, + struct lock_struct *removed_lock) +{ + int i, last_notice; + + /* the last_notice logic is to prevent stampeding on a lock + range. It prevents us sending hundreds of notifies on the + same range of bytes. It doesn't prevent all possible + stampedes, but it does prevent the most common problem */ + last_notice = -1; + + for (i=0;i= PENDING_READ_LOCK && + brl_overlap(&locks[i], removed_lock)) { + DATA_BLOB data; + + if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { + continue; + } + last_notice = i; + data.data = (void *)&locks[i].notify_ptr; + data.length = sizeof(void *); + messaging_send(brl->messaging_ctx, locks[i].context.server, MSG_BRL_RETRY, &data); + } + } +} + + +/* + send notifications for all pending locks - the file is being closed by this + user +*/ +static void brl_notify_all(struct brl_context *brl, + struct lock_struct *locks, int count) +{ + int i; + for (i=0;ilock_type >= PENDING_READ_LOCK) { + brl_notify_unlock(brl, locks, count, &locks[i]); + } + } +} + + + /* Unlock a range of bytes. */ @@ -261,15 +393,92 @@ NTSTATUS brl_unlock(void *brl_ctx, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); for (i=0; icontext, &context) && lock->fnum == fnum && lock->start == start && - lock->size == size) { + lock->size == size && + lock->notify_ptr == NULL) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + struct lock_struct removed_lock = *lock; + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + + /* send notifications for any relevant pending locks */ + brl_notify_unlock(brl, locks, count, &removed_lock); + + dbuf.dsize = count * sizeof(*locks); + + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + /* we didn't find it */ + status = NT_STATUS_RANGE_NOT_LOCKED; + + fail: + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + remove a pending lock. This is called when the caller has either + given up trying to establish a lock or when they have succeeded in + getting it. In either case they no longer need to be notified. +*/ +NTSTATUS brl_remove_pending(void *brl_ctx, + DATA_BLOB *file_key, + void *notify_ptr) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct *locks; + NTSTATUS status; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_RANGE_NOT_LOCKED; + } + + /* there are existing locks - find a match */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; inotify_ptr == notify_ptr && + lock->context.server == brl->server) { /* found it - delete it */ if (count == 1) { if (tdb_delete(brl->w->tdb, kbuf) != 0) { @@ -281,7 +490,8 @@ NTSTATUS brl_unlock(void *brl_ctx, memmove(&locks[i], &locks[i+1], sizeof(*locks)*((count-1) - i)); } - dbuf.dsize -= sizeof(*locks); + count--; + dbuf.dsize = count * sizeof(*locks); if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; goto fail; @@ -404,7 +614,13 @@ NTSTATUS brl_close(void *brl_ctx, status = NT_STATUS_INTERNAL_DB_CORRUPTION; } } else if (dcount != 0) { - dbuf.dsize -= dcount * sizeof(*locks); + /* tell all pending lock holders for this file that + they have a chance now. This is a bit indiscriminant, + but works OK */ + brl_notify_all(brl, locks, count); + + dbuf.dsize = count * sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From 43a80e1d83dad9450014b2a7e0ad5a5e495f69ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 09:16:55 +0000 Subject: r3031: added support for lock cancelation, which effectively just triggers an early lock timeout added support for more of the bizarre special lock offset semantics of w2k3 (This used to be commit d5bfc910b1200fb283e26572dc57fcf93652fd32) --- source4/ntvfs/common/brlock.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 792ee52ad5..2da32891fb 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -117,8 +117,16 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx static BOOL brl_overlap(struct lock_struct *lck1, struct lock_struct *lck2) { - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) { + /* this extra check is not redundent - it copes with locks + that go beyond the end of 64 bit file space */ + if (lck1->size != 0 && + lck1->start == lck2->start && + lck1->size == lck2->size) { + return True; + } + + if (lck1->start >= (lck2->start+lck2->size) || + lck2->start >= (lck1->start+lck1->size)) { return False; } return True; @@ -193,11 +201,12 @@ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *loc return NT_STATUS_FILE_LOCK_CONFLICT; } brl->last_lock_failure = *lock; - if (lock->start >= 0xEF000000) { + if (lock->start >= 0xEF000000 && + (lock->start >> 63) == 0) { /* amazing the little things you learn with a test suite. Locks beyond this offset (as a 64 bit - number!) always generate the conflict error - code. */ + number!) always generate the conflict error code, + unless the top bit is set */ return NT_STATUS_FILE_LOCK_CONFLICT; } return NT_STATUS_LOCK_NOT_GRANTED; -- cgit From 1ec644619d9607758cf090ea904eb2d84500481c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 01:14:49 +0000 Subject: r3126: in the brlock code I had used a void* for the brl context as I didn't want to expose the brl context structure outside the brlock.c code. Instead, I now use "struct brl_context *" and rely on C being happy to pass around pointers to unknown structures as long as they are not dereferenced. I will be interested to see how the build farm likes this. (This used to be commit cb155c8ad837285c5a7f5b104968239df0b65fd2) --- source4/ntvfs/common/brlock.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 2da32891fb..607947615e 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -71,8 +71,8 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, - void *messaging_ctx) +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, + void *messaging_ctx) { char *path; struct brl_context *brl; @@ -97,7 +97,7 @@ void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, brl->messaging_ctx = messaging_ctx; ZERO_STRUCT(brl->last_lock_failure); - return (void *)brl; + return brl; } @@ -219,7 +219,7 @@ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *loc someone else closing an overlapping lock range) a messaging notification is sent, identified by the notify_ptr */ -NTSTATUS brl_lock(void *brl_ctx, +NTSTATUS brl_lock(struct brl_context *brl, DATA_BLOB *file_key, uint16_t smbpid, uint16_t fnum, @@ -227,7 +227,6 @@ NTSTATUS brl_lock(void *brl_ctx, enum brl_type lock_type, void *notify_ptr) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; @@ -248,7 +247,7 @@ NTSTATUS brl_lock(void *brl_ctx, preventing the real lock gets removed */ if (lock_type >= PENDING_READ_LOCK) { enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); - status = brl_lock(brl_ctx, file_key, smbpid, fnum, start, size, rw, NULL); + status = brl_lock(brl, file_key, smbpid, fnum, start, size, rw, NULL); if (NT_STATUS_IS_OK(status)) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_OK; @@ -368,13 +367,12 @@ static void brl_notify_all(struct brl_context *brl, /* Unlock a range of bytes. */ -NTSTATUS brl_unlock(void *brl_ctx, +NTSTATUS brl_unlock(struct brl_context *brl, DATA_BLOB *file_key, uint16_t smbpid, uint16_t fnum, uint64_t start, uint64_t size) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct *locks; @@ -456,11 +454,10 @@ NTSTATUS brl_unlock(void *brl_ctx, given up trying to establish a lock or when they have succeeded in getting it. In either case they no longer need to be notified. */ -NTSTATUS brl_remove_pending(void *brl_ctx, +NTSTATUS brl_remove_pending(struct brl_context *brl, DATA_BLOB *file_key, void *notify_ptr) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct *locks; @@ -526,14 +523,13 @@ NTSTATUS brl_remove_pending(void *brl_ctx, /* Test if we are allowed to perform IO on a region of an open file */ -NTSTATUS brl_locktest(void *brl_ctx, +NTSTATUS brl_locktest(struct brl_context *brl, DATA_BLOB *file_key, uint16_t fnum, uint16 smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; @@ -573,10 +569,9 @@ NTSTATUS brl_locktest(void *brl_ctx, /* Remove any locks associated with a open file. */ -NTSTATUS brl_close(void *brl_ctx, +NTSTATUS brl_close(struct brl_context *brl, DATA_BLOB *file_key, int fnum) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i, dcount=0; struct lock_struct *locks; -- cgit From 05ad898f68a2df1b102af95fdba0704479bde073 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 22:45:33 +0000 Subject: r3271: use "struct messaging_context *" instead of "void *" in messaging API (This used to be commit cc93813e4a09c538ad485dc2b3cb4c9be34f3d18) --- source4/ntvfs/common/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 607947615e..d4b152cf42 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -61,7 +61,7 @@ struct brl_context { struct tdb_wrap *w; servid_t server; uint16_t tid; - void *messaging_ctx; + struct messaging_context *messaging_ctx; struct lock_struct last_lock_failure; }; @@ -72,7 +72,7 @@ struct brl_context { pending lock notifications. */ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, - void *messaging_ctx) + struct messaging_context *messaging_ctx) { char *path; struct brl_context *brl; -- cgit From c8c3a56b8bf0db89fdb8f548fe6016cb87d115ad Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 06:45:28 +0000 Subject: r3312: in the brlock code, we prevent lock stampedes by attempting to not wakeup all pending locks at once. This change means that we only trigger this anti-stampede code for write locks, as for pending read locks the correct behaviour is to stampede (as they will all succeed) (This used to be commit 8021d1d74207db1204139309592b9d2f80f2bd0e) --- source4/ntvfs/common/brlock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d4b152cf42..b43f0705a5 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -338,7 +338,9 @@ static void brl_notify_unlock(struct brl_context *brl, if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { continue; } - last_notice = i; + if (locks[i].lock_type == PENDING_WRITE_LOCK) { + last_notice = i; + } data.data = (void *)&locks[i].notify_ptr; data.length = sizeof(void *); messaging_send(brl->messaging_ctx, locks[i].context.server, MSG_BRL_RETRY, &data); -- cgit From dbf03959244c392073281c10badd2095397ad2f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 07:29:26 +0000 Subject: r3357: removed the need to use TDB_CLEAR_IF_FIRST in Samba4. We found a few months ago that TDB_CLEAR_IF_FIRST is extremely inefficient for large numbers of connections, due to a fundamental limitation in the way posix byte range locking is implemented. Rather than the nasty workaround we had for Samba3, we now have a single "cleanup tmp files" function that runs when smbd starts. That deletes the tmp tdbs, so TDB_CLEAR_IF_FIRST is not needed at all. (This used to be commit ffa285bc783c775a2d53a58fb691ca339e6c76ae) --- source4/ntvfs/common/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index b43f0705a5..0f6af3e971 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -84,7 +84,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, path = lock_path(brl, "brlock.tdb"); brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (brl->w == NULL) { -- cgit From 09d0b152b7bd85aa01898af81bd166a7673ab886 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 08:38:59 +0000 Subject: r3360: improved the deletion of tmp files. smbd now puts all tmp files in var/locks/smbd.tmp/ and deletes that dir on startup. (This used to be commit 7e942e7f1bd2c293a0e6648df43a96f8b8a2a295) --- source4/ntvfs/common/brlock.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 0f6af3e971..a952cb1dc7 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -82,10 +82,9 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, return NULL; } - path = lock_path(brl, "brlock.tdb"); + path = smbd_tmp_path(brl, "brlock.tdb"); brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT, - O_RDWR|O_CREAT, 0600); + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (brl->w == NULL) { talloc_free(brl); -- cgit From 3643fb11092e28a9538ef32cedce8ff21ad86a28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:42:15 +0000 Subject: r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h) (This used to be commit b97e395c814762024336c1cf4d7c25be8da5813a) --- source4/ntvfs/common/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index a952cb1dc7..d1df0413ce 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,6 +26,7 @@ used. This allows us to provide the same semantics as NT */ #include "includes.h" +#include "messages.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies -- cgit From dde07058075d357cfdc63624c8dcaa67ebd40add Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 10:09:48 +0000 Subject: r3507: - added deferred replies on sharing violation in pvfs open. The deferred reply is short-circuited immediately when the file is closed by another user, allowing it to be opened by the waiting user. - added a sane set of timeval manipulation routines - converted all the events code and code that uses it to use struct timeval instead of time_t, which allows for microsecond resolution instead of 1 second resolution. This was needed for doing the pvfs deferred open code, and is why the patch is so big. (This used to be commit 0d51511d408d91eb5f68a35e980e0875299b1831) --- source4/ntvfs/common/brlock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d1df0413ce..6fae7c6e4c 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -333,17 +333,14 @@ static void brl_notify_unlock(struct brl_context *brl, for (i=0;i= PENDING_READ_LOCK && brl_overlap(&locks[i], removed_lock)) { - DATA_BLOB data; - if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { continue; } if (locks[i].lock_type == PENDING_WRITE_LOCK) { last_notice = i; } - data.data = (void *)&locks[i].notify_ptr; - data.length = sizeof(void *); - messaging_send(brl->messaging_ctx, locks[i].context.server, MSG_BRL_RETRY, &data); + messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, + MSG_BRL_RETRY, locks[i].notify_ptr); } } } -- cgit From c870ae8b898d3bcc81ed9fd1afd505d78dea52cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Nov 2004 11:28:38 +0000 Subject: r3528: added support for the SMBntcancel() operation, which cancels any outstanding async operation (triggering an immediate timeout). pvfs now passes the RAW-MUX test (This used to be commit 3423e2f41461d054067ef168b9b986f62cc8f77c) --- source4/ntvfs/common/brlock.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 6fae7c6e4c..2b30270eff 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -63,7 +63,7 @@ struct brl_context { servid_t server; uint16_t tid; struct messaging_context *messaging_ctx; - struct lock_struct last_lock_failure; + struct lock_struct last_lock; }; @@ -95,7 +95,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, brl->server = server; brl->tid = tid; brl->messaging_ctx = messaging_ctx; - ZERO_STRUCT(brl->last_lock_failure); + ZERO_STRUCT(brl->last_lock); return brl; } @@ -194,13 +194,14 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck */ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) { - if (brl_same_context(&lock->context, &brl->last_lock_failure.context) && - lock->fnum == brl->last_lock_failure.fnum && - lock->start == brl->last_lock_failure.start && - lock->size == brl->last_lock_failure.size) { + if (lock->context.server == brl->last_lock.context.server && + lock->context.tid == brl->last_lock.context.tid && + lock->fnum == brl->last_lock.fnum && + lock->start == brl->last_lock.start && + lock->size == brl->last_lock.size) { return NT_STATUS_FILE_LOCK_CONFLICT; } - brl->last_lock_failure = *lock; + brl->last_lock = *lock; if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { /* amazing the little things you learn with a test -- cgit From daea5e8c8c6cf83af0a41e858be571886fae7218 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 19:31:53 +0000 Subject: r3969: fix compiler warnings metze (This used to be commit 7d24b98f3ff55049a7c0d430c15e0a060b4aa2d3) --- source4/ntvfs/common/brlock.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 2b30270eff..e01f458e74 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -234,7 +234,7 @@ NTSTATUS brl_lock(struct brl_context *brl, char *tp; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -379,7 +379,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -463,7 +463,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -534,7 +534,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, int count, i; struct lock_struct lock, *locks; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; dbuf = tdb_fetch(brl->w->tdb, kbuf); @@ -577,7 +577,7 @@ NTSTATUS brl_close(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { -- cgit From e5ce904ddbd6175ba86ed827bf096b76b11b5511 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:42:06 +0000 Subject: r4054: got rid of Realloc(), replacing it with the type safe macro realloc_p() (This used to be commit b0f6e21481745d1b2ced28d9ed6f09f6ffd99562) --- source4/ntvfs/common/brlock.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e01f458e74..7b351f77b0 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -229,9 +229,8 @@ NTSTATUS brl_lock(struct brl_context *brl, void *notify_ptr) { TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct lock, *locks; - char *tp; + int count=0, i; + struct lock_struct lock, *locks=NULL; NTSTATUS status; kbuf.dptr = (char *)file_key->data; @@ -279,14 +278,14 @@ NTSTATUS brl_lock(struct brl_context *brl, } /* no conflicts - add it to the list of locks */ - tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); - if (!tp) { + locks = realloc_p(locks, struct lock_struct, count+1); + if (!locks) { status = NT_STATUS_NO_MEMORY; goto fail; } else { - dbuf.dptr = tp; + dbuf.dptr = (char *)locks; } - memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock)); + locks[count] = lock; dbuf.dsize += sizeof(lock); if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/ntvfs/common/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 7b351f77b0..f51e3d0694 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -78,7 +78,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, char *path; struct brl_context *brl; - brl = talloc_p(mem_ctx, struct brl_context); + brl = talloc(mem_ctx, struct brl_context); if (brl == NULL) { return NULL; } -- cgit From 55d4d36993293fee914a009f1d8f05810e347f2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 00:54:57 +0000 Subject: r5102: This is a major simplification of the logic for controlling top level servers in smbd. The old code still contained a fairly bit of legacy from the time when smbd was only handling SMB connection. The new code gets rid of all of the smb_server specific code in smbd/, and creates a much simpler infrastructures for new server code. Major changes include: - simplified the process model code a lot. - got rid of the top level server and service structures completely. The top level context is now the event_context. This got rid of service.h and server.h completely (they were the most confusing parts of the old code) - added service_stream.[ch] for the helper functions that are specific to stream type services (services that handle streams, and use a logically separate process per connection) - got rid of the builtin idle_handler code in the service logic, as none of the servers were using it, and it can easily be handled by a server in future by adding its own timed_event to the event context. - fixed some major memory leaks in the rpc server code. - added registration of servers, rather than hard coding our list of possible servers. This allows for servers as modules in the future. - temporarily disabled the winbind code until I add the helper functions for that type of server - added error checking on service startup. If a configured server fails to startup then smbd doesn't startup. - cleaned up the command line handling in smbd, removing unused options (This used to be commit cf6a46c3cbde7b1eb1b86bd3882b953a2de3a42e) --- source4/ntvfs/common/brlock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index f51e3d0694..d521dc80d3 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -41,7 +41,7 @@ lock is the same as another lock */ struct lock_context { - servid_t server; + uint32_t server; uint16_t smbpid; uint16_t tid; }; @@ -60,7 +60,7 @@ struct lock_struct { struct brl_context { struct tdb_wrap *w; - servid_t server; + uint32_t server; uint16_t tid; struct messaging_context *messaging_ctx; struct lock_struct last_lock; @@ -72,7 +72,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, struct messaging_context *messaging_ctx) { char *path; -- cgit From d8d3a5ffe3fb73d64869c133fe398efeb4e79d77 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 16:06:21 +0000 Subject: r5137: fix types metze (This used to be commit add1c579375d08040f722946da31ee3862f9e7ac) --- source4/ntvfs/common/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d521dc80d3..d0385fbb0b 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -525,7 +525,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, NTSTATUS brl_locktest(struct brl_context *brl, DATA_BLOB *file_key, uint16_t fnum, - uint16 smbpid, + uint16_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { -- cgit From fedf0b0d91fdf2a6ae0ef47acd4047f662bd3374 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 03:48:43 +0000 Subject: r5296: - only include the tdb headers where they are needed - removed the u32 hack in events.c as I think this was only needed as tdb.h defines u32. Metze, can you check that this hack is indeed no longer needed on your suse system? (This used to be commit 6f79432fe656164d4770dbce114a30dda5e7bf9a) --- source4/ntvfs/common/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d0385fbb0b..e88e9638a3 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,6 +26,7 @@ used. This allows us to provide the same semantics as NT */ #include "includes.h" +#include "lib/tdb/include/tdb.h" #include "messages.h" /* -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/ntvfs/common/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e88e9638a3..e693d57ca0 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,6 +26,7 @@ used. This allows us to provide the same semantics as NT */ #include "includes.h" +#include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messages.h" -- cgit From a5bd1ccadab723c531963c219a1ac2b6b0c8b845 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:22:25 +0000 Subject: r5307: removed db_wrap.h from includes.h (This used to be commit 826baec7b348814a7bbdcdbec8c8526514f25da1) --- source4/ntvfs/common/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e693d57ca0..5e404768e0 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -29,6 +29,7 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messages.h" +#include "db_wrap.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies -- cgit From bf1ffa283caef6a3c98b5cc7f5bc8205c2818b06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 Jun 2005 06:53:07 +0000 Subject: r7294: implemented the irpc messaging system. This is the core of the management system I proposed on samba-technical a couple of days ago. Essentially it is a very lightweight way for any code in Samba to make IDL based rpc calls to anywhere else in the code, without the client or server having to go to the trouble of setting up a full rpc service. It can be used with any of our existing IDL, but I expect it will mostly be used for a new set of Samba specific management calls. The LOCAL-IRPC torture test demonstrates how it can be used by calling the echo_AddOne() call over this transport. (This used to be commit 3d589a09954eb8b318f567e1150b0c27412fb942) --- source4/ntvfs/common/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 5e404768e0..e06cb0602e 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -30,6 +30,7 @@ #include "lib/tdb/include/tdb.h" #include "messages.h" #include "db_wrap.h" +#include "lib/messaging/irpc.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies -- cgit From 78c50015bb8bd5a1d831a6e7ec796b3367c73145 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 15:40:05 +0000 Subject: r12694: Move some headers to the directory of the subsystem they belong to. (This used to be commit c722f665c90103f3ed57621c460e32ad33e7a8a3) --- source4/ntvfs/common/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e06cb0602e..3fc3c09316 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -28,7 +28,7 @@ #include "includes.h" #include "system/filesys.h" #include "lib/tdb/include/tdb.h" -#include "messages.h" +#include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" -- cgit From dfc517b05395d925a4d7b1ce9633a849f9468e70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 15:52:24 +0000 Subject: r13658: More moving around of files: - Collect the generic utility functions into a lib/util/ (a la GLib is for the GNOME folks) - Remove even more files from include/ (This used to be commit ba62880f5b05c2a505dc7f54676b231197a7e707) --- source4/ntvfs/common/brlock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 3fc3c09316..6548a2c199 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -31,6 +31,7 @@ #include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" +#include "libcli/libcli.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies @@ -237,7 +238,7 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = (uint8_t *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -287,7 +288,7 @@ NTSTATUS brl_lock(struct brl_context *brl, status = NT_STATUS_NO_MEMORY; goto fail; } else { - dbuf.dptr = (char *)locks; + dbuf.dptr = (uint8_t *)locks; } locks[count] = lock; dbuf.dsize += sizeof(lock); @@ -382,7 +383,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = (uint8_t *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { -- cgit From 04cf19bd597df38c391e236bfe95f5df7138cdef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Feb 2006 01:03:21 +0000 Subject: r13701: removed some unnecessary casts (This used to be commit f7d0ac936380102e087d4b7c336d7feb68b62314) --- source4/ntvfs/common/brlock.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 6548a2c199..ddbab257bc 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -238,7 +238,7 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = (uint8_t *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -383,7 +383,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = (uint8_t *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -467,7 +467,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -538,7 +538,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, int count, i; struct lock_struct lock, *locks; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; dbuf = tdb_fetch(brl->w->tdb, kbuf); @@ -581,7 +581,7 @@ NTSTATUS brl_close(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { -- cgit From 96b5dd789be8468ca73665dc47da3779aaefe609 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Mar 2006 13:56:25 +0000 Subject: r14822: if we use the snum used by the lp_* functions instead of the wire TID, then don't use tid as name... metze (This used to be commit d41d48caf209fec9f5f04d38d75277b1cfeed22f) --- source4/ntvfs/common/brlock.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index ddbab257bc..bc9d8b1288 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -48,7 +48,7 @@ struct lock_context { uint32_t server; uint16_t smbpid; - uint16_t tid; + int snum; }; /* The data in brlock records is an unsorted linear array of these @@ -66,7 +66,7 @@ struct lock_struct { struct brl_context { struct tdb_wrap *w; uint32_t server; - uint16_t tid; + int snum; struct messaging_context *messaging_ctx; struct lock_struct last_lock; }; @@ -77,7 +77,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, int snum, struct messaging_context *messaging_ctx) { char *path; @@ -98,7 +98,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, } brl->server = server; - brl->tid = tid; + brl->snum = snum; brl->messaging_ctx = messaging_ctx; ZERO_STRUCT(brl->last_lock); @@ -113,7 +113,7 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx { return (ctx1->server == ctx2->server && ctx1->smbpid == ctx2->smbpid && - ctx1->tid == ctx2->tid); + ctx1->snum == ctx2->snum); } /* @@ -200,7 +200,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) { if (lock->context.server == brl->last_lock.context.server && - lock->context.tid == brl->last_lock.context.tid && + lock->context.snum == brl->last_lock.context.snum && lock->fnum == brl->last_lock.fnum && lock->start == brl->last_lock.start && lock->size == brl->last_lock.size) { @@ -263,7 +263,7 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.tid = brl->tid; + lock.context.snum = brl->snum; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -398,7 +398,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, context.smbpid = smbpid; context.server = brl->server; - context.tid = brl->tid; + context.snum = brl->snum; /* there are existing locks - find a match */ locks = (struct lock_struct *)dbuf.dptr; @@ -548,7 +548,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.tid = brl->tid; + lock.context.snum = brl->snum; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -601,7 +601,7 @@ NTSTATUS brl_close(struct brl_context *brl, for (i=0; icontext.tid == brl->tid && + if (lock->context.snum == brl->snum && lock->context.server == brl->server && lock->fnum == fnum) { /* found it - delete it */ -- cgit From 8dbffb37d53f1ef4f8b160c8452c13ac6a471e4d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 May 2006 10:45:38 +0000 Subject: r15612: look at the lock_type and not at the notify_ptr being NULL or not metze (This used to be commit 7fa6d736913af2d1d2215ca1a04ed8763ccb3d45) --- source4/ntvfs/common/brlock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index bc9d8b1288..80c4350eac 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -411,7 +411,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, lock->fnum == fnum && lock->start == start && lock->size == size && - lock->notify_ptr == NULL) { + lock->lock_type < PENDING_READ_LOCK) { /* found it - delete it */ if (count == 1) { if (tdb_delete(brl->w->tdb, kbuf) != 0) { @@ -487,7 +487,8 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, for (i=0; inotify_ptr == notify_ptr && + if (lock->lock_type >= PENDING_READ_LOCK && + lock->notify_ptr == notify_ptr && lock->context.server == brl->server) { /* found it - delete it */ if (count == 1) { -- cgit From be0bd9fa336464e7c1fa2ab7cc5cd34075d595ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 May 2006 11:43:25 +0000 Subject: r15613: the snum doesn't identify the tcon, but the brl_context pointer does metze (This used to be commit 5e256f4b78441269de2e53c9582f3237e4220f6c) --- source4/ntvfs/common/brlock.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 80c4350eac..07f1593c2e 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -41,6 +41,7 @@ as it is applied consistently. */ +struct brl_context; /* the lock context contains the elements that define whether one lock is the same as another lock @@ -48,7 +49,7 @@ struct lock_context { uint32_t server; uint16_t smbpid; - int snum; + struct brl_context *ctx; }; /* The data in brlock records is an unsorted linear array of these @@ -66,7 +67,6 @@ struct lock_struct { struct brl_context { struct tdb_wrap *w; uint32_t server; - int snum; struct messaging_context *messaging_ctx; struct lock_struct last_lock; }; @@ -77,7 +77,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, int snum, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, struct messaging_context *messaging_ctx) { char *path; @@ -98,7 +98,6 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, int snum, } brl->server = server; - brl->snum = snum; brl->messaging_ctx = messaging_ctx; ZERO_STRUCT(brl->last_lock); @@ -113,7 +112,7 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx { return (ctx1->server == ctx2->server && ctx1->smbpid == ctx2->smbpid && - ctx1->snum == ctx2->snum); + ctx1->ctx == ctx2->ctx); } /* @@ -200,7 +199,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) { if (lock->context.server == brl->last_lock.context.server && - lock->context.snum == brl->last_lock.context.snum && + lock->context.ctx == brl->last_lock.context.ctx && lock->fnum == brl->last_lock.fnum && lock->start == brl->last_lock.start && lock->size == brl->last_lock.size) { @@ -263,7 +262,7 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.snum = brl->snum; + lock.context.ctx = brl; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -398,7 +397,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, context.smbpid = smbpid; context.server = brl->server; - context.snum = brl->snum; + context.ctx = brl; /* there are existing locks - find a match */ locks = (struct lock_struct *)dbuf.dptr; @@ -549,7 +548,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.snum = brl->snum; + lock.context.ctx = brl; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -602,7 +601,7 @@ NTSTATUS brl_close(struct brl_context *brl, for (i=0; icontext.snum == brl->snum && + if (lock->context.ctx == brl && lock->context.server == brl->server && lock->fnum == fnum) { /* found it - delete it */ -- cgit From 5e6d1ea2618851ef99522a806f36916127e5294a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 May 2006 12:22:00 +0000 Subject: r15614: the byte range locking error handling caches the last failed lock per file handle and not per tree connect metze (This used to be commit 5d825261c0b8341f0a7f0f6d96d83807352566f4) --- source4/ntvfs/common/brlock.c | 132 ++++++++++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 43 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 07f1593c2e..b5df434435 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -57,21 +57,27 @@ struct lock_context { size of the record */ struct lock_struct { struct lock_context context; + uint16_t fnum; uint64_t start; uint64_t size; - uint16_t fnum; enum brl_type lock_type; void *notify_ptr; }; +/* this struct is attached to on oprn file handle */ +struct brl_handle { + DATA_BLOB key; + uint16_t fnum; + struct lock_struct last_lock; +}; + +/* this struct is typicaly attached to tcon */ struct brl_context { struct tdb_wrap *w; uint32_t server; struct messaging_context *messaging_ctx; - struct lock_struct last_lock; }; - /* Open up the brlock.tdb database. Close it down using talloc_free(). We need the messaging_ctx to allow for @@ -89,7 +95,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, } path = smbd_tmp_path(brl, "brlock.tdb"); - brl->w = tdb_wrap_open(brl, path, 0, + brl->w = tdb_wrap_open(brl, path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (brl->w == NULL) { @@ -99,11 +105,25 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, brl->server = server; brl->messaging_ctx = messaging_ctx; - ZERO_STRUCT(brl->last_lock); return brl; } +struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, uint16_t fnum) +{ + struct brl_handle *brlh; + + brlh = talloc(mem_ctx, struct brl_handle); + if (brlh == NULL) { + return NULL; + } + + brlh->key = *file_key; + brlh->fnum = fnum; + ZERO_STRUCT(brlh->last_lock); + + return brlh; +} /* see if two locking contexts are equal @@ -196,24 +216,47 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck is the same as this one and changes its error code. I wonder if any app depends on this? */ -static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) +static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *lock) { - if (lock->context.server == brl->last_lock.context.server && - lock->context.ctx == brl->last_lock.context.ctx && - lock->fnum == brl->last_lock.fnum && - lock->start == brl->last_lock.start && - lock->size == brl->last_lock.size) { + /* + * this function is only called for non pending lock! + */ + + /* + * if the notify_ptr is non NULL, + * it means that we're at the end of a pending lock + * and the real lock is requested after the timout went by + * In this case we need to remember the last_lock and always + * give FILE_LOCK_CONFLICT + */ + if (lock->notify_ptr) { + brlh->last_lock = *lock; return NT_STATUS_FILE_LOCK_CONFLICT; } - brl->last_lock = *lock; - if (lock->start >= 0xEF000000 && - (lock->start >> 63) == 0) { - /* amazing the little things you learn with a test - suite. Locks beyond this offset (as a 64 bit - number!) always generate the conflict error code, - unless the top bit is set */ + + /* + * amazing the little things you learn with a test + * suite. Locks beyond this offset (as a 64 bit + * number!) always generate the conflict error code, + * unless the top bit is set + */ + if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { + brlh->last_lock = *lock; return NT_STATUS_FILE_LOCK_CONFLICT; } + + /* + * if the current lock matches the last failed lock on the file handle + * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned + */ + if (lock->context.server == brlh->last_lock.context.server && + lock->context.ctx == brlh->last_lock.context.ctx && + lock->fnum == brlh->last_lock.fnum && + lock->start == brlh->last_lock.start) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + brlh->last_lock = *lock; return NT_STATUS_LOCK_NOT_GRANTED; } @@ -225,9 +268,8 @@ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *loc notification is sent, identified by the notify_ptr */ NTSTATUS brl_lock(struct brl_context *brl, - DATA_BLOB *file_key, + struct brl_handle *brlh, uint16_t smbpid, - uint16_t fnum, uint64_t start, uint64_t size, enum brl_type lock_type, void *notify_ptr) @@ -237,8 +279,8 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -251,7 +293,12 @@ NTSTATUS brl_lock(struct brl_context *brl, preventing the real lock gets removed */ if (lock_type >= PENDING_READ_LOCK) { enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); - status = brl_lock(brl, file_key, smbpid, fnum, start, size, rw, NULL); + + /* here we need to force that the last_lock isn't overwritten */ + lock = brlh->last_lock; + status = brl_lock(brl, brlh, smbpid, start, size, rw, NULL); + brlh->last_lock = lock; + if (NT_STATUS_IS_OK(status)) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_OK; @@ -263,9 +310,10 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; + lock.fnum = brlh->fnum; + lock.context.ctx = brl; lock.start = start; lock.size = size; - lock.fnum = fnum; lock.lock_type = lock_type; lock.notify_ptr = notify_ptr; @@ -275,7 +323,7 @@ NTSTATUS brl_lock(struct brl_context *brl, count = dbuf.dsize / sizeof(*locks); for (i=0; i= PENDING_READ_LOCK) { - return brl_lock_failed(brl, &lock); + return NT_STATUS_LOCK_NOT_GRANTED; } return NT_STATUS_OK; @@ -371,9 +419,8 @@ static void brl_notify_all(struct brl_context *brl, Unlock a range of bytes. */ NTSTATUS brl_unlock(struct brl_context *brl, - DATA_BLOB *file_key, + struct brl_handle *brlh, uint16_t smbpid, - uint16_t fnum, uint64_t start, uint64_t size) { TDB_DATA kbuf, dbuf; @@ -382,8 +429,8 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -407,7 +454,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_struct *lock = &locks[i]; if (brl_same_context(&lock->context, &context) && - lock->fnum == fnum && + lock->fnum == brlh->fnum && lock->start == start && lock->size == size && lock->lock_type < PENDING_READ_LOCK) { @@ -458,7 +505,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, getting it. In either case they no longer need to be notified. */ NTSTATUS brl_remove_pending(struct brl_context *brl, - DATA_BLOB *file_key, + struct brl_handle *brlh, void *notify_ptr) { TDB_DATA kbuf, dbuf; @@ -466,8 +513,8 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -528,8 +575,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, Test if we are allowed to perform IO on a region of an open file */ NTSTATUS brl_locktest(struct brl_context *brl, - DATA_BLOB *file_key, - uint16_t fnum, + struct brl_handle *brlh, uint16_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) @@ -538,8 +584,8 @@ NTSTATUS brl_locktest(struct brl_context *brl, int count, i; struct lock_struct lock, *locks; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; dbuf = tdb_fetch(brl->w->tdb, kbuf); if (dbuf.dptr == NULL) { @@ -549,9 +595,9 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; + lock.fnum = brlh->fnum; lock.start = start; lock.size = size; - lock.fnum = fnum; lock.lock_type = lock_type; /* there are existing locks - make sure they don't conflict */ @@ -574,15 +620,15 @@ NTSTATUS brl_locktest(struct brl_context *brl, Remove any locks associated with a open file. */ NTSTATUS brl_close(struct brl_context *brl, - DATA_BLOB *file_key, int fnum) + struct brl_handle *brlh) { TDB_DATA kbuf, dbuf; int count, i, dcount=0; struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -603,7 +649,7 @@ NTSTATUS brl_close(struct brl_context *brl, if (lock->context.ctx == brl && lock->context.server == brl->server && - lock->fnum == fnum) { + lock->fnum == brlh->fnum) { /* found it - delete it */ if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], -- cgit From 9ef33f5f5c786b83311ca088357fb2f0aa72fc9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 08:15:22 +0000 Subject: r15734: This is a major change to the NTVFS subsystem: - to use a struct ntvfs_handle instead of a uint16_t fnum. (to make it independend from the frontend protocol) - the allocation of handles now is provided by the frontend (smbsrv_*) via callbacks and not by each backend module - this also makes sure that file handles are only passed to the ntvfs subsystem when the tcon and session matches, so modules can rely on this and need to check this. - this allows multiple modules in the ntvfs module chain to allocate file handles. This can be used for virtual files like "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"... - also this will make SMB2 with 128 bit file handles possible metze (This used to be commit 287fc1c22d670f6e568014b420f7f4cb31dc7958) --- source4/ntvfs/common/brlock.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index b5df434435..2816c563b8 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -57,7 +57,7 @@ struct lock_context { size of the record */ struct lock_struct { struct lock_context context; - uint16_t fnum; + struct ntvfs_handle *ntvfs; uint64_t start; uint64_t size; enum brl_type lock_type; @@ -67,7 +67,7 @@ struct lock_struct { /* this struct is attached to on oprn file handle */ struct brl_handle { DATA_BLOB key; - uint16_t fnum; + struct ntvfs_handle *ntvfs; struct lock_struct last_lock; }; @@ -109,7 +109,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, return brl; } -struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, uint16_t fnum) +struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) { struct brl_handle *brlh; @@ -119,7 +119,7 @@ struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, u } brlh->key = *file_key; - brlh->fnum = fnum; + brlh->ntvfs = ntvfs; ZERO_STRUCT(brlh->last_lock); return brlh; @@ -173,7 +173,7 @@ static BOOL brl_conflict(struct lock_struct *lck1, } if (brl_same_context(&lck1->context, &lck2->context) && - lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) { + lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) { return False; } @@ -202,7 +202,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck * in smbtorture. */ if (brl_same_context(&lck1->context, &lck2->context) && - lck1->fnum == lck2->fnum && + lck1->ntvfs == lck2->ntvfs && (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { return False; } @@ -251,7 +251,7 @@ static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *loc */ if (lock->context.server == brlh->last_lock.context.server && lock->context.ctx == brlh->last_lock.context.ctx && - lock->fnum == brlh->last_lock.fnum && + lock->ntvfs == brlh->last_lock.ntvfs && lock->start == brlh->last_lock.start) { return NT_STATUS_FILE_LOCK_CONFLICT; } @@ -310,7 +310,7 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; - lock.fnum = brlh->fnum; + lock.ntvfs = brlh->ntvfs; lock.context.ctx = brl; lock.start = start; lock.size = size; @@ -454,7 +454,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_struct *lock = &locks[i]; if (brl_same_context(&lock->context, &context) && - lock->fnum == brlh->fnum && + lock->ntvfs == brlh->ntvfs && lock->start == start && lock->size == size && lock->lock_type < PENDING_READ_LOCK) { @@ -595,7 +595,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; - lock.fnum = brlh->fnum; + lock.ntvfs = brlh->ntvfs; lock.start = start; lock.size = size; lock.lock_type = lock_type; @@ -649,7 +649,7 @@ NTSTATUS brl_close(struct brl_context *brl, if (lock->context.ctx == brl && lock->context.server == brl->server && - lock->fnum == brlh->fnum) { + lock->ntvfs == brlh->ntvfs) { /* found it - delete it */ if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], -- cgit From 1cd4339b9a2786aa26691ca4f02fa93ab0958b88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 10:52:09 +0000 Subject: r20646: first preparations for cluster enablement. This changes " uint32_t server_id to struct server_id server_id; which allows a server ID to have an node number. The node number will be zero in non-clustered case. This is the most basic hook needed for clustering, and ctdb. (This used to be commit 2365abaa991d57d68c6ebe9be608e01c907102eb) --- source4/ntvfs/common/brlock.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 2816c563b8..d7fb97415f 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -47,7 +47,7 @@ struct brl_context; lock is the same as another lock */ struct lock_context { - uint32_t server; + struct server_id server; uint16_t smbpid; struct brl_context *ctx; }; @@ -74,7 +74,7 @@ struct brl_handle { /* this struct is typicaly attached to tcon */ struct brl_context { struct tdb_wrap *w; - uint32_t server; + struct server_id server; struct messaging_context *messaging_ctx; }; @@ -83,7 +83,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx) { char *path; @@ -130,7 +130,7 @@ struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *n */ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) { - return (ctx1->server == ctx2->server && + return (cluster_id_equal(&ctx1->server, &ctx2->server) && ctx1->smbpid == ctx2->smbpid && ctx1->ctx == ctx2->ctx); } @@ -249,7 +249,7 @@ static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *loc * if the current lock matches the last failed lock on the file handle * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned */ - if (lock->context.server == brlh->last_lock.context.server && + if (cluster_id_equal(&lock->context.server, &brlh->last_lock.context.server) && lock->context.ctx == brlh->last_lock.context.ctx && lock->ntvfs == brlh->last_lock.ntvfs && lock->start == brlh->last_lock.start) { @@ -535,7 +535,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, if (lock->lock_type >= PENDING_READ_LOCK && lock->notify_ptr == notify_ptr && - lock->context.server == brl->server) { + cluster_id_equal(&lock->context.server, &brl->server)) { /* found it - delete it */ if (count == 1) { if (tdb_delete(brl->w->tdb, kbuf) != 0) { @@ -648,7 +648,7 @@ NTSTATUS brl_close(struct brl_context *brl, struct lock_struct *lock = &locks[i]; if (lock->context.ctx == brl && - lock->context.server == brl->server && + cluster_id_equal(&lock->context.server, &brl->server) && lock->ntvfs == brlh->ntvfs) { /* found it - delete it */ if (count > 1 && i < count-1) { -- cgit From 98ac70b6a3f7eb48beb86f543f629f77d2aa4549 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 10 Jan 2007 13:25:39 +0000 Subject: r20653: If this is the wrong way to fix the build, I apologize. But these includes are necessary in my environment to get through make. Volker (This used to be commit 47e80da39f27a7e7aa6f85d6333f2d1772292ec9) --- source4/ntvfs/common/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d7fb97415f..c42c2f3a11 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -32,6 +32,7 @@ #include "db_wrap.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" +#include "cluster/cluster.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies -- cgit From be05a5ca2525f7f3ab732a5b5c7baceb7c7a4ada Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jan 2007 03:58:16 +0000 Subject: r20891: enable multiple brlock backends. The tdb backend is the default. The prototype ctdb backend is in cluster/ctdb/brlock_ctdb.c (This used to be commit 84d0e5316299931dc26f2a7b86962d2fffcc4b71) --- source4/ntvfs/common/brlock.c | 689 ------------------------------------------ 1 file changed, 689 deletions(-) delete mode 100644 source4/ntvfs/common/brlock.c (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c deleted file mode 100644 index c42c2f3a11..0000000000 --- a/source4/ntvfs/common/brlock.c +++ /dev/null @@ -1,689 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - generic byte range locking code - - Copyright (C) Andrew Tridgell 1992-2004 - Copyright (C) Jeremy Allison 1992-2000 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* This module implements a tdb based byte range locking service, - replacing the fcntl() based byte range locking previously - used. This allows us to provide the same semantics as NT */ - -#include "includes.h" -#include "system/filesys.h" -#include "lib/tdb/include/tdb.h" -#include "messaging/messaging.h" -#include "db_wrap.h" -#include "lib/messaging/irpc.h" -#include "libcli/libcli.h" -#include "cluster/cluster.h" - -/* - in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies - a file. For a local posix filesystem this will usually be a combination - of the device and inode numbers of the file, but it can be anything - that uniquely idetifies a file for locking purposes, as long - as it is applied consistently. -*/ - -struct brl_context; -/* - the lock context contains the elements that define whether one - lock is the same as another lock -*/ -struct lock_context { - struct server_id server; - uint16_t smbpid; - struct brl_context *ctx; -}; - -/* The data in brlock records is an unsorted linear array of these - records. It is unnecessary to store the count as tdb provides the - size of the record */ -struct lock_struct { - struct lock_context context; - struct ntvfs_handle *ntvfs; - uint64_t start; - uint64_t size; - enum brl_type lock_type; - void *notify_ptr; -}; - -/* this struct is attached to on oprn file handle */ -struct brl_handle { - DATA_BLOB key; - struct ntvfs_handle *ntvfs; - struct lock_struct last_lock; -}; - -/* this struct is typicaly attached to tcon */ -struct brl_context { - struct tdb_wrap *w; - struct server_id server; - struct messaging_context *messaging_ctx; -}; - -/* - Open up the brlock.tdb database. Close it down using - talloc_free(). We need the messaging_ctx to allow for - pending lock notifications. -*/ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, - struct messaging_context *messaging_ctx) -{ - char *path; - struct brl_context *brl; - - brl = talloc(mem_ctx, struct brl_context); - if (brl == NULL) { - return NULL; - } - - path = smbd_tmp_path(brl, "brlock.tdb"); - brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - talloc_free(path); - if (brl->w == NULL) { - talloc_free(brl); - return NULL; - } - - brl->server = server; - brl->messaging_ctx = messaging_ctx; - - return brl; -} - -struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) -{ - struct brl_handle *brlh; - - brlh = talloc(mem_ctx, struct brl_handle); - if (brlh == NULL) { - return NULL; - } - - brlh->key = *file_key; - brlh->ntvfs = ntvfs; - ZERO_STRUCT(brlh->last_lock); - - return brlh; -} - -/* - see if two locking contexts are equal -*/ -static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) -{ - return (cluster_id_equal(&ctx1->server, &ctx2->server) && - ctx1->smbpid == ctx2->smbpid && - ctx1->ctx == ctx2->ctx); -} - -/* - see if lck1 and lck2 overlap -*/ -static BOOL brl_overlap(struct lock_struct *lck1, - struct lock_struct *lck2) -{ - /* this extra check is not redundent - it copes with locks - that go beyond the end of 64 bit file space */ - if (lck1->size != 0 && - lck1->start == lck2->start && - lck1->size == lck2->size) { - return True; - } - - if (lck1->start >= (lck2->start+lck2->size) || - lck2->start >= (lck1->start+lck1->size)) { - return False; - } - return True; -} - -/* - See if lock2 can be added when lock1 is in place. -*/ -static BOOL brl_conflict(struct lock_struct *lck1, - struct lock_struct *lck2) -{ - /* pending locks don't conflict with anything */ - if (lck1->lock_type >= PENDING_READ_LOCK || - lck2->lock_type >= PENDING_READ_LOCK) { - return False; - } - - if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { - return False; - } - - if (brl_same_context(&lck1->context, &lck2->context) && - lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) { - return False; - } - - return brl_overlap(lck1, lck2); -} - - -/* - Check to see if this lock conflicts, but ignore our own locks on the - same fnum only. -*/ -static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) -{ - /* pending locks don't conflict with anything */ - if (lck1->lock_type >= PENDING_READ_LOCK || - lck2->lock_type >= PENDING_READ_LOCK) { - return False; - } - - if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) - return False; - - /* - * note that incoming write calls conflict with existing READ - * locks even if the context is the same. JRA. See LOCKTEST7 - * in smbtorture. - */ - if (brl_same_context(&lck1->context, &lck2->context) && - lck1->ntvfs == lck2->ntvfs && - (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { - return False; - } - - return brl_overlap(lck1, lck2); -} - - -/* - amazingly enough, w2k3 "remembers" whether the last lock failure - is the same as this one and changes its error code. I wonder if any - app depends on this? -*/ -static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *lock) -{ - /* - * this function is only called for non pending lock! - */ - - /* - * if the notify_ptr is non NULL, - * it means that we're at the end of a pending lock - * and the real lock is requested after the timout went by - * In this case we need to remember the last_lock and always - * give FILE_LOCK_CONFLICT - */ - if (lock->notify_ptr) { - brlh->last_lock = *lock; - return NT_STATUS_FILE_LOCK_CONFLICT; - } - - /* - * amazing the little things you learn with a test - * suite. Locks beyond this offset (as a 64 bit - * number!) always generate the conflict error code, - * unless the top bit is set - */ - if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { - brlh->last_lock = *lock; - return NT_STATUS_FILE_LOCK_CONFLICT; - } - - /* - * if the current lock matches the last failed lock on the file handle - * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned - */ - if (cluster_id_equal(&lock->context.server, &brlh->last_lock.context.server) && - lock->context.ctx == brlh->last_lock.context.ctx && - lock->ntvfs == brlh->last_lock.ntvfs && - lock->start == brlh->last_lock.start) { - return NT_STATUS_FILE_LOCK_CONFLICT; - } - - brlh->last_lock = *lock; - return NT_STATUS_LOCK_NOT_GRANTED; -} - -/* - Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in - which case a real lock is first tried, and if that fails then a - pending lock is created. When the pending lock is triggered (by - someone else closing an overlapping lock range) a messaging - notification is sent, identified by the notify_ptr -*/ -NTSTATUS brl_lock(struct brl_context *brl, - struct brl_handle *brlh, - uint16_t smbpid, - uint64_t start, uint64_t size, - enum brl_type lock_type, - void *notify_ptr) -{ - TDB_DATA kbuf, dbuf; - int count=0, i; - struct lock_struct lock, *locks=NULL; - NTSTATUS status; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - /* if this is a pending lock, then with the chainlock held we - try to get the real lock. If we succeed then we don't need - to make it pending. This prevents a possible race condition - where the pending lock gets created after the lock that is - preventing the real lock gets removed */ - if (lock_type >= PENDING_READ_LOCK) { - enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); - - /* here we need to force that the last_lock isn't overwritten */ - lock = brlh->last_lock; - status = brl_lock(brl, brlh, smbpid, start, size, rw, NULL); - brlh->last_lock = lock; - - if (NT_STATUS_IS_OK(status)) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - - lock.context.smbpid = smbpid; - lock.context.server = brl->server; - lock.context.ctx = brl; - lock.ntvfs = brlh->ntvfs; - lock.context.ctx = brl; - lock.start = start; - lock.size = size; - lock.lock_type = lock_type; - lock.notify_ptr = notify_ptr; - - if (dbuf.dptr) { - /* there are existing locks - make sure they don't conflict */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - for (i=0; iw->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - - /* the caller needs to know if the real lock was granted. If - we have reached here then it must be a pending lock that - was granted, so tell them the lock failed */ - if (lock_type >= PENDING_READ_LOCK) { - return NT_STATUS_LOCK_NOT_GRANTED; - } - - return NT_STATUS_OK; - - fail: - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return status; -} - - -/* - we are removing a lock that might be holding up a pending lock. Scan for pending - locks that cover this range and if we find any then notify the server that it should - retry the lock -*/ -static void brl_notify_unlock(struct brl_context *brl, - struct lock_struct *locks, int count, - struct lock_struct *removed_lock) -{ - int i, last_notice; - - /* the last_notice logic is to prevent stampeding on a lock - range. It prevents us sending hundreds of notifies on the - same range of bytes. It doesn't prevent all possible - stampedes, but it does prevent the most common problem */ - last_notice = -1; - - for (i=0;i= PENDING_READ_LOCK && - brl_overlap(&locks[i], removed_lock)) { - if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { - continue; - } - if (locks[i].lock_type == PENDING_WRITE_LOCK) { - last_notice = i; - } - messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, - MSG_BRL_RETRY, locks[i].notify_ptr); - } - } -} - - -/* - send notifications for all pending locks - the file is being closed by this - user -*/ -static void brl_notify_all(struct brl_context *brl, - struct lock_struct *locks, int count) -{ - int i; - for (i=0;ilock_type >= PENDING_READ_LOCK) { - brl_notify_unlock(brl, locks, count, &locks[i]); - } - } -} - - - -/* - Unlock a range of bytes. -*/ -NTSTATUS brl_unlock(struct brl_context *brl, - struct brl_handle *brlh, - uint16_t smbpid, - uint64_t start, uint64_t size) -{ - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct *locks; - struct lock_context context; - NTSTATUS status; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_RANGE_NOT_LOCKED; - } - - context.smbpid = smbpid; - context.server = brl->server; - context.ctx = brl; - - /* there are existing locks - find a match */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; icontext, &context) && - lock->ntvfs == brlh->ntvfs && - lock->start == start && - lock->size == size && - lock->lock_type < PENDING_READ_LOCK) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - struct lock_struct removed_lock = *lock; - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - - /* send notifications for any relevant pending locks */ - brl_notify_unlock(brl, locks, count, &removed_lock); - - dbuf.dsize = count * sizeof(*locks); - - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - } - - /* we didn't find it */ - status = NT_STATUS_RANGE_NOT_LOCKED; - - fail: - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return status; -} - - -/* - remove a pending lock. This is called when the caller has either - given up trying to establish a lock or when they have succeeded in - getting it. In either case they no longer need to be notified. -*/ -NTSTATUS brl_remove_pending(struct brl_context *brl, - struct brl_handle *brlh, - void *notify_ptr) -{ - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct *locks; - NTSTATUS status; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_RANGE_NOT_LOCKED; - } - - /* there are existing locks - find a match */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; ilock_type >= PENDING_READ_LOCK && - lock->notify_ptr == notify_ptr && - cluster_id_equal(&lock->context.server, &brl->server)) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - dbuf.dsize = count * sizeof(*locks); - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - } - - /* we didn't find it */ - status = NT_STATUS_RANGE_NOT_LOCKED; - - fail: - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return status; -} - - -/* - Test if we are allowed to perform IO on a region of an open file -*/ -NTSTATUS brl_locktest(struct brl_context *brl, - struct brl_handle *brlh, - uint16_t smbpid, - uint64_t start, uint64_t size, - enum brl_type lock_type) -{ - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct lock, *locks; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (dbuf.dptr == NULL) { - return NT_STATUS_OK; - } - - lock.context.smbpid = smbpid; - lock.context.server = brl->server; - lock.context.ctx = brl; - lock.ntvfs = brlh->ntvfs; - lock.start = start; - lock.size = size; - lock.lock_type = lock_type; - - /* there are existing locks - make sure they don't conflict */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; ikey.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - - /* there are existing locks - remove any for this fnum */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; icontext.ctx == brl && - cluster_id_equal(&lock->context.server, &brl->server) && - lock->ntvfs == brlh->ntvfs) { - /* found it - delete it */ - if (count > 1 && i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - i--; - dcount++; - } - } - - status = NT_STATUS_OK; - - if (count == 0) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } else if (dcount != 0) { - /* tell all pending lock holders for this file that - they have a chance now. This is a bit indiscriminant, - but works OK */ - brl_notify_all(brl, locks, count); - - dbuf.dsize = count * sizeof(*locks); - - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - - return status; -} - -- cgit From 72316674bf8a53fb704f14690d900a6c5799deb7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jan 2007 04:08:33 +0000 Subject: r20894: the new brlock.c is needed (seems a svn rename + new file didn't make it in one commit) (This used to be commit 3315e877ab6504569e2869b52d989fc821982a3b) --- source4/ntvfs/common/brlock.c | 132 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 source4/ntvfs/common/brlock.c (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c new file mode 100644 index 0000000000..e483a6ba9b --- /dev/null +++ b/source4/ntvfs/common/brlock.c @@ -0,0 +1,132 @@ +/* + Unix SMB/CIFS implementation. + + generic byte range locking code + + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Jeremy Allison 1992-2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* This module implements a tdb based byte range locking service, + replacing the fcntl() based byte range locking previously + used. This allows us to provide the same semantics as NT */ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/tdb/include/tdb.h" +#include "messaging/messaging.h" +#include "db_wrap.h" +#include "lib/messaging/irpc.h" +#include "libcli/libcli.h" +#include "cluster/cluster.h" +#include "ntvfs/common/brlock.h" + +static const struct brlock_ops *ops; + +/* + set the brl backend ops +*/ +void brl_set_ops(const struct brlock_ops *new_ops) +{ + ops = new_ops; +} + +/* + Open up the brlock database. Close it down using talloc_free(). We + need the messaging_ctx to allow for pending lock notifications. +*/ +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, + struct messaging_context *messaging_ctx) +{ + if (ops == NULL) { + if (lp_parm_bool(-1, "ctdb", "brlock", False)) { + brl_ctdb_init_ops(); + } else { + brl_tdb_init_ops(); + } + } + return ops->brl_init(mem_ctx, server, messaging_ctx); +} + +struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) +{ + return ops->brl_create_handle(mem_ctx, ntvfs, file_key); +} + +/* + Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in + which case a real lock is first tried, and if that fails then a + pending lock is created. When the pending lock is triggered (by + someone else closing an overlapping lock range) a messaging + notification is sent, identified by the notify_ptr +*/ +NTSTATUS brl_lock(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type, + void *notify_ptr) +{ + return ops->brl_lock(brl, brlh, smbpid, start, size, lock_type, notify_ptr); +} + + +/* + Unlock a range of bytes. +*/ +NTSTATUS brl_unlock(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size) +{ + return ops->brl_unlock(brl, brlh, smbpid, start, size); +} + +/* + remove a pending lock. This is called when the caller has either + given up trying to establish a lock or when they have succeeded in + getting it. In either case they no longer need to be notified. +*/ +NTSTATUS brl_remove_pending(struct brl_context *brl, + struct brl_handle *brlh, + void *notify_ptr) +{ + return ops->brl_remove_pending(brl, brlh, notify_ptr); +} + + +/* + Test if we are allowed to perform IO on a region of an open file +*/ +NTSTATUS brl_locktest(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + return ops->brl_locktest(brl, brlh, smbpid, start, size, lock_type); +} + + +/* + Remove any locks associated with a open file. +*/ +NTSTATUS brl_close(struct brl_context *brl, + struct brl_handle *brlh) +{ + return ops->brl_close(brl, brlh); +} -- cgit From f40182cb123c91d4bc8fd3dbf9c3cca615f72c31 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jan 2007 11:58:03 +0000 Subject: r20897: fix compiler warnings metze (This used to be commit 5ac562e1e0e8de03c8bcd083a1822b31667c5e21) --- source4/ntvfs/common/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e483a6ba9b..8397c3bdd3 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -33,7 +33,7 @@ #include "lib/messaging/irpc.h" #include "libcli/libcli.h" #include "cluster/cluster.h" -#include "ntvfs/common/brlock.h" +#include "ntvfs/common/ntvfs_common.h" static const struct brlock_ops *ops; -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/ntvfs/common/brlock.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 8397c3bdd3..56d3ff80f6 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* This module implements a tdb based byte range locking service, -- cgit From 4792285282e2ec78ccb0ebc3cac6465d1d26ef10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 9 Aug 2007 06:36:16 +0000 Subject: r24284: change brlock_tdb.c to use the dbwrap API. This actually makes the backend abstraction for brlock pointless, but I have left it in place for now. It would be useful for other clustering systems that can't map to dbwrap, and would also be useful if we wanted to keep the remote function call capabilities in ctdb instead of the less efficient fetch_locked() call in dbwrap (This used to be commit 912c014b7c131ab051ff6eb2db4e68cb6fbbeb14) --- source4/ntvfs/common/brlock.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 56d3ff80f6..27d7437f4f 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -52,11 +52,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx) { if (ops == NULL) { - if (lp_parm_bool(-1, "ctdb", "brlock", False)) { - brl_ctdb_init_ops(); - } else { - brl_tdb_init_ops(); - } + brl_tdb_init_ops(); } return ops->brl_init(mem_ctx, server, messaging_ctx); } -- cgit From ca0b72a1fdb7bd965065e833df34662afef0423e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Nov 2007 20:12:00 +0100 Subject: r26003: Split up DB_WRAP, as first step in an attempt to sanitize dependencies. (This used to be commit 56dfcb4f2f8e74c9d8b2fe3a0df043781188a555) --- source4/ntvfs/common/brlock.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 27d7437f4f..ddf3219a9a 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -28,7 +28,6 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messaging/messaging.h" -#include "db_wrap.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" #include "cluster/cluster.h" -- cgit From b65dba2245bf382c47d65c95ac9b1efa43918fc0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 04:33:16 +0100 Subject: r26355: Eliminate global_loadparm in more places. (This used to be commit 5d589a0d94bd76a9b4c9fc748854e8098ea43c4d) --- source4/ntvfs/common/brlock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index ddf3219a9a..c87eca8aff 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -48,12 +48,13 @@ void brl_set_ops(const struct brlock_ops *new_ops) need the messaging_ctx to allow for pending lock notifications. */ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, + struct loadparm_context *lp_ctx, struct messaging_context *messaging_ctx) { if (ops == NULL) { brl_tdb_init_ops(); } - return ops->brl_init(mem_ctx, server, messaging_ctx); + return ops->brl_init(mem_ctx, server, lp_ctx, messaging_ctx); } struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) -- cgit From 1bdd08227e7d046305705050f21f0f1b6dd6994a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Jun 2008 11:03:19 +1000 Subject: smbpid needs to be 32 bit now to cope with SMB2 (This used to be commit a2854fd6eaf097b5a9a562e0b8f1a599485fec42) --- source4/ntvfs/common/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs/common/brlock.c') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index c87eca8aff..3b34873152 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -109,7 +109,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, */ NTSTATUS brl_locktest(struct brl_context *brl, struct brl_handle *brlh, - uint16_t smbpid, + uint32_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { -- cgit