From 6c2a1fdf360a8fcb100543fdb994860fe6268102 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Jan 2000 12:09:36 +0000 Subject: the bulk of the new byte range locking coode it doesn't map to posix locks yet, that will come later. (This used to be commit 7f2a493095887cb0aae915ac36b9cded71d3a7a7) --- source3/locking/brlock.c | 275 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 source3/locking/brlock.c (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c new file mode 100644 index 0000000000..5d928daa58 --- /dev/null +++ b/source3/locking/brlock.c @@ -0,0 +1,275 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + byte range locking code + Copyright (C) Andrew Tridgell 1992-1998 + + 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" + +extern int DEBUGLEVEL; + +/* this contains elements that differentiate locks. The smbpid is a + client supplied pid, and is essentially the locking context for + this client */ +struct lock_context { + uint16 smbpid; + uint16 tid; + pid_t pid; +}; + +/* 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; + br_off start; + br_off size; + enum lock_type lock_type; +}; + +/* the key used in the brlock database */ +struct lock_key { + SMB_DEV_T device; + SMB_INO_T inode; +}; + +/* the open brlock.tdb database */ +static TDB_CONTEXT *tdb; + + +/**************************************************************************** +see if two locking contexts are equal +****************************************************************************/ +static BOOL brl_same_context(struct lock_context *ctx1, + struct lock_context *ctx2) +{ + return (ctx1->pid == ctx2->pid) && + (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) return False; + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) return False; + + return True; +} + + +/**************************************************************************** +open up the brlock.tdb database +****************************************************************************/ +void brl_init(void) +{ + if (tdb) return; + tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT, 0644); + if (!tdb) { + DEBUG(0,("Failed to open byte range locking database\n")); + } +} + + +/**************************************************************************** +lock a range of bytes +****************************************************************************/ +BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, + uint16 smbpid, pid_t pid, uint16 tid, + br_off start, br_off size, + enum lock_type lock_type) +{ + struct lock_key key; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct lock, *locks; + + key.device = dev; + key.inode = ino; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + + dbuf.dptr = NULL; + + tdb_lockchain(tdb, kbuf); + dbuf = tdb_fetch(tdb, kbuf); + + lock.context.smbpid = smbpid; + lock.context.pid = pid; + lock.context.tid = tid; + lock.start = start; + lock.size = size; + 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; i Date: Fri, 14 Jan 2000 04:32:57 +0000 Subject: we now pass all byte range locking tests the last piece was to use a smb timeout slightly larger than the locking timeout in bloking locks to prevent a race (This used to be commit 1b54cb4a33a65e62c2e3189b78ef073869a60c75) --- source3/locking/brlock.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 5d928daa58..653a40728b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -43,6 +43,7 @@ struct lock_struct { struct lock_context context; br_off start; br_off size; + int fnum; enum lock_type lock_type; }; @@ -102,7 +103,7 @@ void brl_init(void) /**************************************************************************** lock a range of bytes ****************************************************************************/ -BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, +BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, enum lock_type lock_type) @@ -127,6 +128,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, lock.context.tid = tid; lock.start = start; lock.size = size; + lock.fnum = fnum; lock.lock_type = lock_type; if (dbuf.dptr) { @@ -161,7 +163,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, /**************************************************************************** unlock a range of bytes ****************************************************************************/ -BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, +BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size) { @@ -192,6 +194,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, count = dbuf.dsize / sizeof(*locks); for (i=0; i 1 && i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + i--; + } + } + + if (count == 0) { + tdb_delete(tdb, kbuf); + } else if (count < (dbuf.dsize / sizeof(*locks))) { + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + } + + /* we didn't find it */ + fail: + if (dbuf.dptr) free(dbuf.dptr); + tdb_unlockchain(tdb, kbuf); +} -- cgit From 7bc1cc7e07991641d436b2c8a35b52663d4c5c05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 08:01:44 +0000 Subject: damn, Solaris already has a "enum lock_type" changed it to "enum brl_type" (This used to be commit 6b9ee7662c7afa70f6b20889e6b0ae1dcd677f9f) --- source3/locking/brlock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 653a40728b..11766433fc 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -44,7 +44,7 @@ struct lock_struct { br_off start; br_off size; int fnum; - enum lock_type lock_type; + enum brl_type lock_type; }; /* the key used in the brlock database */ @@ -74,7 +74,8 @@ 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 (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) return False; @@ -106,7 +107,7 @@ lock a range of bytes BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum lock_type lock_type) + enum brl_type lock_type) { struct lock_key key; TDB_DATA kbuf, dbuf; @@ -231,7 +232,7 @@ test if we could add a lock if we wanted to BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum lock_type lock_type) + enum brl_type lock_type) { struct lock_key key; TDB_DATA kbuf, dbuf; -- cgit From 54e1176ba17eaaba82254e4b629fa135802cec10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2000 11:14:44 +0000 Subject: added code to allow traversal of the byte range lock database this is used with "smbstatus -B" to dump the lock list (This used to be commit 5f022629146701e6d543f77007dc944e4277ab0c) --- source3/locking/brlock.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 11766433fc..7e8adf4f86 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -90,11 +90,11 @@ static BOOL brl_conflict(struct lock_struct *lck1, /**************************************************************************** open up the brlock.tdb database ****************************************************************************/ -void brl_init(void) +void brl_init(int read_only) { if (tdb) return; tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT, 0644); + read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); } @@ -329,3 +329,43 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) if (dbuf.dptr) free(dbuf.dptr); tdb_unlockchain(tdb, kbuf); } + + +static void (*traverse_callback)(SMB_DEV_T dev, SMB_INO_T ino, int pid, + enum brl_type lock_type, + br_off start, br_off size); + +/**************************************************************************** +traverse the whole database with this function, calling traverse_callback +on each lock +****************************************************************************/ +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) +{ + struct lock_struct *locks; + struct lock_key *key; + int i; + + locks = (struct lock_struct *)dbuf.dptr; + key = (struct lock_key *)kbuf.dptr; + + for (i=0;idevice, key->inode, + locks[i].context.pid, + locks[i].lock_type, + locks[i].start, + locks[i].size); + } + return 0; +} + +/******************************************************************* + Call the specified function on each lock in the database +********************************************************************/ +int brl_forall(void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, + enum brl_type lock_type, + br_off start, br_off size)) +{ + if (!tdb) return 0; + traverse_callback = fn; + return tdb_traverse(tdb, traverse_fn); +} -- cgit From bbe275e95b86bc7af5a641455cbb379974823f84 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 4 Feb 2000 04:59:31 +0000 Subject: 1) added void* state argument to tdb_traverse. guess what! there were two places i found where it was appropriate to _use_ that third argument, in locking.c and brlock.c! there was a static traverse_function and i removed the static variable, typecast it to a void*, passed it to tdb_traverse and re-cast it back to the traverse_function inside the tdb_traverse function. this makes the use of tdb_traverse() reentrant, which is never going to happen, i know, i just don't like to see statics lying about when there's no need for them. as i had to do in samba-tng, all uses of tdb_traverse modified to take the new void* state argument. 2) disabled rpcclient: referring people to use SAMBA_TNG rpcclient. i don't know how the other samba team members would react if i deleted rpcclient from cvs main. damn, that code's so old, it's unreal. 20 rpcclient commands, instead of about 70 in SAMBA_TNG. (This used to be commit 49d7f0afbc1c5425d53019e234d54ddf205c8e9a) --- source3/locking/brlock.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 7e8adf4f86..71fc45854a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -331,20 +331,18 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) } -static void (*traverse_callback)(SMB_DEV_T dev, SMB_INO_T ino, int pid, - enum brl_type lock_type, - br_off start, br_off size); - /**************************************************************************** traverse the whole database with this function, calling traverse_callback on each lock ****************************************************************************/ -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) +static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct lock_struct *locks; struct lock_key *key; int i; + BRLOCK_FN(traverse_callback) = (BRLOCK_FN_CAST())state; + locks = (struct lock_struct *)dbuf.dptr; key = (struct lock_key *)kbuf.dptr; @@ -361,11 +359,8 @@ static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) /******************************************************************* Call the specified function on each lock in the database ********************************************************************/ -int brl_forall(void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, - enum brl_type lock_type, - br_off start, br_off size)) +int brl_forall(BRLOCK_FN(fn)) { if (!tdb) return 0; - traverse_callback = fn; - return tdb_traverse(tdb, traverse_fn); + return tdb_traverse(tdb, traverse_fn, (BRLOCK_FN_CAST())fn); } -- cgit From e4d382750caa522b5e249d690fdb469d7b0c12a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Apr 2000 20:30:58 +0000 Subject: Added the hard code :-). HEAD should now map brl locks correctly into POSIX locks, including the really nasty case of large range unlock. There is a lot of pretty ASCII art in locking/brlock.c explaining exactly how this code works. If it is unclear, please ask me. Jeremy. (This used to be commit 135855dbd3b8934a49229b81646cd4469acba926) --- source3/locking/brlock.c | 359 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 332 insertions(+), 27 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 71fc45854a..68daa7e0bb 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -2,7 +2,10 @@ Unix SMB/Netbios implementation. Version 3.0 byte range locking code - Copyright (C) Andrew Tridgell 1992-1998 + Updated to handle range splits/merges. + + Copyright (C) Andrew Tridgell 1992-2000 + 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 @@ -19,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* this module implements a tdb based byte range locking service, +/* 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 */ @@ -27,18 +30,20 @@ extern int DEBUGLEVEL; -/* this contains elements that differentiate locks. The smbpid is a +/* This contains elements that differentiate locks. The smbpid is a client supplied pid, and is essentially the locking context for this client */ + struct lock_context { uint16 smbpid; uint16 tid; pid_t pid; }; -/* the data in brlock records is an unsorted linear array of these +/* 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; br_off start; @@ -47,19 +52,21 @@ struct lock_struct { enum brl_type lock_type; }; -/* the key used in the brlock database */ +/* The key used in the brlock database. */ + struct lock_key { SMB_DEV_T device; SMB_INO_T inode; }; -/* the open brlock.tdb database */ -static TDB_CONTEXT *tdb; +/* The open brlock.tdb database. */ +static TDB_CONTEXT *tdb; /**************************************************************************** -see if two locking contexts are equal + See if two locking contexts are equal. ****************************************************************************/ + static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) { @@ -69,8 +76,9 @@ static BOOL brl_same_context(struct lock_context *ctx1, } /**************************************************************************** -see if lock2 can be added when lock1 is in place + See if lock2 can be added when lock1 is in place. ****************************************************************************/ + static BOOL brl_conflict(struct lock_struct *lck1, struct lock_struct *lck2) { @@ -88,8 +96,9 @@ static BOOL brl_conflict(struct lock_struct *lck1, /**************************************************************************** -open up the brlock.tdb database + Open up the brlock.tdb database. ****************************************************************************/ + void brl_init(int read_only) { if (tdb) return; @@ -102,8 +111,9 @@ void brl_init(int read_only) /**************************************************************************** -lock a range of bytes + Lock a range of bytes. ****************************************************************************/ + BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, @@ -160,10 +170,238 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, return False; } +/**************************************************************************** + Create a list of lock ranges that don't overlap a given range. Used in calculating + POSIX lock unlocks. This is a difficult function that requires ASCII art to + understand it :-). +****************************************************************************/ + +struct unlock_list *brl_unlock_list(TALLOC_CTX *ctx, struct unlock_list *ulhead, + pid_t pid, SMB_DEV_T dev, SMB_INO_T ino) +{ + struct lock_key key; + TDB_DATA kbuf, dbuf; + struct lock_struct *locks; + int num_locks, i; + + /* + * Setup the key for this fetch. + */ + key.device = dev; + key.inode = ino; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + + dbuf.dptr = NULL; + + tdb_lockchain(tdb, kbuf); + dbuf = tdb_fetch(tdb, kbuf); + + if (!dbuf.dptr) { + tdb_unlockchain(tdb, kbuf); + return ulhead; + } + + locks = (struct lock_struct *)dbuf.dptr; + num_locks = dbuf.dsize / sizeof(*locks); + + /* + * Check the current lock list on this dev/inode pair. + * Quit if the list is deleted. + */ + + for (i=0; icontext.pid != pid) + continue; + + /* + * Walk the unlock list, checking for overlaps. Note that + * the unlock list can expand within this loop if the current + * range being examined needs to be split. + */ + + for (ul_curr = ulhead; ul_curr;) { + + DEBUG(10,("brl_unlock_list: curr: start=%.0f,size=%.0f \ +lock: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size, + (double)lock->start, (double)lock->size )); + + if ( (ul_curr->start >= (lock->start + lock->size)) || + (lock->start > (ul_curr->start + ul_curr->size))) { + + /* No overlap with this lock - leave this range alone. */ +/********************************************* + +---------+ + | ul_curr | + +---------+ + +-------+ + | lock | + +-------+ +OR.... + +---------+ + | ul_curr | + +---------+ +**********************************************/ + + DEBUG(10,("brl_unlock_list: no overlap case.\n" )); + + ul_curr = ul_curr->next; + + } else if ( (ul_curr->start >= lock->start) && + (ul_curr->start + ul_curr->size <= lock->start + lock->size) ) { + + /* + * This unlock is completely overlapped by this existing lock range + * and thus should have no effect (not be unlocked). Delete it from the list. + */ +/********************************************* + +---------+ + | ul_curr | + +---------+ + +---------------------------+ + | lock | + +---------------------------+ +**********************************************/ + /* Save the next pointer */ + struct unlock_list *ul_next = ul_curr->next; + + DEBUG(10,("brl_unlock_list: delete case.\n" )); + + DLIST_REMOVE(ulhead, ul_curr); + if(ulhead == NULL) + break; /* No more list... */ + + ul_curr = ul_next; + + } else if ( (ul_curr->start >= lock->start) && + (ul_curr->start < lock->start + lock->size) && + (ul_curr->start + ul_curr->size > lock->start + lock->size) ) { + + /* + * This unlock overlaps the existing lock range at the high end. + * Truncate by moving start to existing range end and reducing size. + */ +/********************************************* + +---------------+ + | ul_curr | + +---------------+ + +---------------+ + | lock | + +---------------+ +BECOMES.... + +-------+ + |ul_curr| + +-------+ +**********************************************/ + + ul_curr->size = (ul_curr->start + ul_curr->size) - (lock->start + lock->size); + ul_curr->start = lock->start + lock->size; + + DEBUG(10,("brl_unlock_list: truncate high case: start=%.0f,size=%.0f\n", + (double)ul_curr->start, (double)ul_curr->size )); + + ul_curr = ul_curr->next; + + } else if ( (ul_curr->start < lock->start) && + (ul_curr->start + ul_curr->size > lock->start) ) { + + /* + * This unlock overlaps the existing lock range at the low end. + * Truncate by reducing size. + */ +/********************************************* + +---------------+ + | ul_curr | + +---------------+ + +---------------+ + | lock | + +---------------+ +BECOMES.... + +-------+ + |ul_curr| + +-------+ +**********************************************/ + + ul_curr->size = lock->start - ul_curr->start; + + DEBUG(10,("brl_unlock_list: truncate low case: start=%.0f,size=%.0f\n", + (double)ul_curr->start, (double)ul_curr->size )); + + ul_curr = ul_curr->next; + + } else if ( (ul_curr->start < lock->start) && + (ul_curr->start + ul_curr->size > lock->start + lock->size) ) { + /* + * Worst case scenario. Unlock request completely overlaps an existing + * lock range. Split the request into two, push the new (upper) request + * into the dlink list, and continue with the entry after ul_new (as we + * know that ul_new will not overlap with this lock). + */ +/********************************************* + +---------------------------+ + | ul_curr | + +---------------------------+ + +---------+ + | lock | + +---------+ +BECOMES..... + +-------+ +---------+ + |ul_curr| |ul_new | + +-------+ +---------+ +**********************************************/ + struct unlock_list *ul_new = (struct unlock_list *)talloc(ctx, + sizeof(struct unlock_list)); + + if(ul_new == NULL) { + DEBUG(0,("brl_unlock_list: talloc fail.\n")); + return NULL; /* The talloc_destroy takes care of cleanup. */ + } + + ZERO_STRUCTP(ul_new); + ul_new->start = lock->start + lock->size; + ul_new->size = ul_curr->start + ul_curr->size - ul_new->start; + + /* Add into the dlink list after the ul_curr point - NOT at ulhead. */ + DLIST_ADD(ul_curr, ul_new); + + /* Truncate the ul_curr. */ + ul_curr->size = lock->start - ul_curr->start; + + DEBUG(10,("brl_unlock_list: split case: curr: start=%.0f,size=%.0f \ +new: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size, + (double)ul_new->start, (double)ul_new->size )); + + ul_curr = ul_new->next; + + } else { + + /* + * This logic case should never happen. Ensure this is the + * case by forcing an abort.... Remove in production. + */ + + smb_panic("brl_unlock_list: logic flaw in cases...\n"); + } + } /* end for ( ul_curr = ulhead; ul_curr;) */ + } /* end for (i=0; icontext, &context) && + lock->fnum == fnum && + lock->start == start && + lock->size == size) { /* found it - delete it */ if (count == 1) { tdb_delete(tdb, kbuf); @@ -224,11 +465,10 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, return False; } - - /**************************************************************************** -test if we could add a lock if we wanted to + Test if we could add a lock if we wanted to. ****************************************************************************/ + BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, @@ -278,10 +518,10 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, return False; } - /**************************************************************************** -remove any locks associated with a open file + Remove any locks associated with a open file. ****************************************************************************/ + void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) { struct lock_key key; @@ -305,9 +545,11 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); for (i=0; icontext.tid == tid && + lock->context.pid == pid && + lock->fnum == fnum) { /* found it - delete it */ if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], @@ -330,11 +572,73 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) tdb_unlockchain(tdb, kbuf); } +/**************************************************************************** + Return a lock list associated with an open file. +****************************************************************************/ + +struct unlock_list *brl_getlocklist( TALLOC_CTX *ctx, SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) +{ + struct lock_key key; + TDB_DATA kbuf, dbuf; + int i, count; + struct lock_struct *locks; + struct unlock_list *ulist = NULL; + + key.device = dev; + key.inode = ino; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + + dbuf.dptr = NULL; + + tdb_lockchain(tdb, kbuf); + dbuf = tdb_fetch(tdb, kbuf); + + if (!dbuf.dptr) { + tdb_unlockchain(tdb, kbuf); + return NULL; + } + + /* There are existing locks - allocate an entry for each one. */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; icontext.tid == tid && + lock->context.pid == pid && + lock->fnum == fnum) { + + struct unlock_list *ul_new = (struct unlock_list *)talloc(ctx, + sizeof(struct unlock_list)); + + if(ul_new == NULL) { + DEBUG(0,("brl_getlocklist: talloc fail.\n")); + return NULL; /* The talloc_destroy takes care of cleanup. */ + } + + ZERO_STRUCTP(ul_new); + ul_new->start = lock->start; + ul_new->size = lock->size; + + DLIST_ADD(ulist, ul_new); + } + } + + if (dbuf.dptr) + free(dbuf.dptr); + tdb_unlockchain(tdb, kbuf); + + return ulist; +} + /**************************************************************************** -traverse the whole database with this function, calling traverse_callback -on each lock + Traverse the whole database with this function, calling traverse_callback + on each lock. ****************************************************************************/ + static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct lock_struct *locks; @@ -357,8 +661,9 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } /******************************************************************* - Call the specified function on each lock in the database + Call the specified function on each lock in the database. ********************************************************************/ + int brl_forall(BRLOCK_FN(fn)) { if (!tdb) return 0; -- cgit From 36db78fedad935aaa689d52d7f58e075f1f71812 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Apr 2000 22:23:04 +0000 Subject: Fixed subtle unlocking bug when a file is closed. We need to store the smbpid used when a file was opened in the files_struct. Else we use the wrong global_smbpid when we are closing the file and trying to remove the brl locks - this causes the brl locks to be left when the file is closed as the samba_context check fails. Jeremy. (This used to be commit 2746e5602e493e5b022764b4b839eb4d2f14363b) --- source3/locking/brlock.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 68daa7e0bb..ed1f73df5e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -210,6 +210,9 @@ struct unlock_list *brl_unlock_list(TALLOC_CTX *ctx, struct unlock_list *ulhead, * Quit if the list is deleted. */ + DEBUG(10,("brl_unlock_list: curr: start=%.0f,size=%.0f\n", + (double)ulhead->start, (double)ulhead->size )); + for (i=0; istart, (double)ul_curr->size, - (double)lock->start, (double)lock->size )); + DEBUG(10,("brl_unlock_list: lock: start=%.0f,size=%.0f:", + (double)lock->start, (double)lock->size )); if ( (ul_curr->start >= (lock->start + lock->size)) || (lock->start > (ul_curr->start + ul_curr->size))) { @@ -248,7 +250,7 @@ OR.... +---------+ **********************************************/ - DEBUG(10,("brl_unlock_list: no overlap case.\n" )); + DEBUG(10,("no overlap case.\n" )); ul_curr = ul_curr->next; @@ -270,7 +272,7 @@ OR.... /* Save the next pointer */ struct unlock_list *ul_next = ul_curr->next; - DEBUG(10,("brl_unlock_list: delete case.\n" )); + DEBUG(10,("delete case.\n" )); DLIST_REMOVE(ulhead, ul_curr); if(ulhead == NULL) @@ -302,7 +304,7 @@ BECOMES.... ul_curr->size = (ul_curr->start + ul_curr->size) - (lock->start + lock->size); ul_curr->start = lock->start + lock->size; - DEBUG(10,("brl_unlock_list: truncate high case: start=%.0f,size=%.0f\n", + DEBUG(10,("truncate high case: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size )); ul_curr = ul_curr->next; @@ -329,7 +331,7 @@ BECOMES.... ul_curr->size = lock->start - ul_curr->start; - DEBUG(10,("brl_unlock_list: truncate low case: start=%.0f,size=%.0f\n", + DEBUG(10,("truncate low case: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size )); ul_curr = ul_curr->next; @@ -372,7 +374,7 @@ BECOMES..... /* Truncate the ul_curr. */ ul_curr->size = lock->start - ul_curr->start; - DEBUG(10,("brl_unlock_list: split case: curr: start=%.0f,size=%.0f \ + DEBUG(10,("split case: curr: start=%.0f,size=%.0f \ new: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size, (double)ul_new->start, (double)ul_new->size )); @@ -385,7 +387,7 @@ new: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size, * case by forcing an abort.... Remove in production. */ - smb_panic("brl_unlock_list: logic flaw in cases...\n"); + smb_panic("logic flaw in cases...\n"); } } /* end for ( ul_curr = ulhead; ul_curr;) */ } /* end for (i=0; icontext, &context)) { + DEBUG(10,("brl_unlock: Not same context. l_smbpid = %u, l_pid = %u, l_tid = %u: \ +smbpid = %u, pid = %u, tid = %u\n", + lock->context.smbpid, lock->context.pid, lock->context.tid, + context.smbpid, context.pid, context.tid )); + + } + /* JRATEST */ +#endif + if (brl_same_context(&lock->context, &context) && lock->fnum == fnum && lock->start == start && -- cgit From 4b60a33c6fa733060068e192b87c2e858103d6eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Apr 2000 23:28:56 +0000 Subject: Ok - this is more subtle than it looks :-). When a file is being closed, once it passes the fnum and tid tests then the locking context should be ignored when removing all locks. This is what is done in the brl close case, but when you have outstanding POSIX locks, then you cannot remove all the brl locks in one go, you have to get the lock list and call do_unlock individually. As this uses global_smbpid as the locking context, you need to make sure that this is set correctly for the specific lock being removed. I now do this by storing the smbpid in each entry in the unlock list returned from the query call. I removed the smbpid from fsp (not needed) and things seem ok (even with the stupid smbpid tricks that smbtorture plays :-). Jeremy. (This used to be commit 6baa96bb466915cc17e8cbad50254d6bd47b967b) --- source3/locking/brlock.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index ed1f73df5e..410fb3fc0b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -367,6 +367,7 @@ BECOMES..... ZERO_STRUCTP(ul_new); ul_new->start = lock->start + lock->size; ul_new->size = ul_curr->start + ul_curr->size - ul_new->start; + ul_new->smbpid = ul_curr->smbpid; /* Add into the dlink list after the ul_curr point - NOT at ulhead. */ DLIST_ADD(ul_curr, ul_new); @@ -638,6 +639,7 @@ struct unlock_list *brl_getlocklist( TALLOC_CTX *ctx, SMB_DEV_T dev, SMB_INO_T i ZERO_STRUCTP(ul_new); ul_new->start = lock->start; ul_new->size = lock->size; + ul_new->smbpid = lock->context.smbpid; DLIST_ADD(ulist, ul_new); } -- cgit From 9a5eb068ab32418e793d482db1f078f147f9ee08 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Apr 2000 20:54:23 +0000 Subject: Ok - this is the *third* implementation of this (third time's the charm :-). This implementation keeps all POSIX lock records in a separate in memory tdb database only known about in locking/posix.c. In addition, the pending close fd's are also held in a tdb which has an array of fd's indexed by device and inode. The walk-split code uglyness has been moved to posix.c from brlock.c, which is the only place that needs to know about it, and the extra functions hacked into brlock to expose internal state have been removed. This implementation passes smbtorture locktest4, the only thing I need to check now for completeness is what to do about lock upgrade/downgrades which Win32 allows under some *very* strange circumstances. Jeremy. (This used to be commit 3f655de1c764b9ee1472a111621d4317f19f624d) --- source3/locking/brlock.c | 296 +---------------------------------------------- 1 file changed, 1 insertion(+), 295 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 410fb3fc0b..0ded1846b4 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -170,237 +170,6 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, return False; } -/**************************************************************************** - Create a list of lock ranges that don't overlap a given range. Used in calculating - POSIX lock unlocks. This is a difficult function that requires ASCII art to - understand it :-). -****************************************************************************/ - -struct unlock_list *brl_unlock_list(TALLOC_CTX *ctx, struct unlock_list *ulhead, - pid_t pid, SMB_DEV_T dev, SMB_INO_T ino) -{ - struct lock_key key; - TDB_DATA kbuf, dbuf; - struct lock_struct *locks; - int num_locks, i; - - /* - * Setup the key for this fetch. - */ - key.device = dev; - key.inode = ino; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); - - dbuf.dptr = NULL; - - tdb_lockchain(tdb, kbuf); - dbuf = tdb_fetch(tdb, kbuf); - - if (!dbuf.dptr) { - tdb_unlockchain(tdb, kbuf); - return ulhead; - } - - locks = (struct lock_struct *)dbuf.dptr; - num_locks = dbuf.dsize / sizeof(*locks); - - /* - * Check the current lock list on this dev/inode pair. - * Quit if the list is deleted. - */ - - DEBUG(10,("brl_unlock_list: curr: start=%.0f,size=%.0f\n", - (double)ulhead->start, (double)ulhead->size )); - - for (i=0; icontext.pid != pid) - continue; - - /* - * Walk the unlock list, checking for overlaps. Note that - * the unlock list can expand within this loop if the current - * range being examined needs to be split. - */ - - for (ul_curr = ulhead; ul_curr;) { - - DEBUG(10,("brl_unlock_list: lock: start=%.0f,size=%.0f:", - (double)lock->start, (double)lock->size )); - - if ( (ul_curr->start >= (lock->start + lock->size)) || - (lock->start > (ul_curr->start + ul_curr->size))) { - - /* No overlap with this lock - leave this range alone. */ -/********************************************* - +---------+ - | ul_curr | - +---------+ - +-------+ - | lock | - +-------+ -OR.... - +---------+ - | ul_curr | - +---------+ -**********************************************/ - - DEBUG(10,("no overlap case.\n" )); - - ul_curr = ul_curr->next; - - } else if ( (ul_curr->start >= lock->start) && - (ul_curr->start + ul_curr->size <= lock->start + lock->size) ) { - - /* - * This unlock is completely overlapped by this existing lock range - * and thus should have no effect (not be unlocked). Delete it from the list. - */ -/********************************************* - +---------+ - | ul_curr | - +---------+ - +---------------------------+ - | lock | - +---------------------------+ -**********************************************/ - /* Save the next pointer */ - struct unlock_list *ul_next = ul_curr->next; - - DEBUG(10,("delete case.\n" )); - - DLIST_REMOVE(ulhead, ul_curr); - if(ulhead == NULL) - break; /* No more list... */ - - ul_curr = ul_next; - - } else if ( (ul_curr->start >= lock->start) && - (ul_curr->start < lock->start + lock->size) && - (ul_curr->start + ul_curr->size > lock->start + lock->size) ) { - - /* - * This unlock overlaps the existing lock range at the high end. - * Truncate by moving start to existing range end and reducing size. - */ -/********************************************* - +---------------+ - | ul_curr | - +---------------+ - +---------------+ - | lock | - +---------------+ -BECOMES.... - +-------+ - |ul_curr| - +-------+ -**********************************************/ - - ul_curr->size = (ul_curr->start + ul_curr->size) - (lock->start + lock->size); - ul_curr->start = lock->start + lock->size; - - DEBUG(10,("truncate high case: start=%.0f,size=%.0f\n", - (double)ul_curr->start, (double)ul_curr->size )); - - ul_curr = ul_curr->next; - - } else if ( (ul_curr->start < lock->start) && - (ul_curr->start + ul_curr->size > lock->start) ) { - - /* - * This unlock overlaps the existing lock range at the low end. - * Truncate by reducing size. - */ -/********************************************* - +---------------+ - | ul_curr | - +---------------+ - +---------------+ - | lock | - +---------------+ -BECOMES.... - +-------+ - |ul_curr| - +-------+ -**********************************************/ - - ul_curr->size = lock->start - ul_curr->start; - - DEBUG(10,("truncate low case: start=%.0f,size=%.0f\n", - (double)ul_curr->start, (double)ul_curr->size )); - - ul_curr = ul_curr->next; - - } else if ( (ul_curr->start < lock->start) && - (ul_curr->start + ul_curr->size > lock->start + lock->size) ) { - /* - * Worst case scenario. Unlock request completely overlaps an existing - * lock range. Split the request into two, push the new (upper) request - * into the dlink list, and continue with the entry after ul_new (as we - * know that ul_new will not overlap with this lock). - */ -/********************************************* - +---------------------------+ - | ul_curr | - +---------------------------+ - +---------+ - | lock | - +---------+ -BECOMES..... - +-------+ +---------+ - |ul_curr| |ul_new | - +-------+ +---------+ -**********************************************/ - struct unlock_list *ul_new = (struct unlock_list *)talloc(ctx, - sizeof(struct unlock_list)); - - if(ul_new == NULL) { - DEBUG(0,("brl_unlock_list: talloc fail.\n")); - return NULL; /* The talloc_destroy takes care of cleanup. */ - } - - ZERO_STRUCTP(ul_new); - ul_new->start = lock->start + lock->size; - ul_new->size = ul_curr->start + ul_curr->size - ul_new->start; - ul_new->smbpid = ul_curr->smbpid; - - /* Add into the dlink list after the ul_curr point - NOT at ulhead. */ - DLIST_ADD(ul_curr, ul_new); - - /* Truncate the ul_curr. */ - ul_curr->size = lock->start - ul_curr->start; - - DEBUG(10,("split case: curr: start=%.0f,size=%.0f \ -new: start=%.0f,size=%.0f\n", (double)ul_curr->start, (double)ul_curr->size, - (double)ul_new->start, (double)ul_new->size )); - - ul_curr = ul_new->next; - - } else { - - /* - * This logic case should never happen. Ensure this is the - * case by forcing an abort.... Remove in production. - */ - - smb_panic("logic flaw in cases...\n"); - } - } /* end for ( ul_curr = ulhead; ul_curr;) */ - } /* end for (i=0; icontext.tid == tid && - lock->context.pid == pid && - lock->fnum == fnum) { - - struct unlock_list *ul_new = (struct unlock_list *)talloc(ctx, - sizeof(struct unlock_list)); - - if(ul_new == NULL) { - DEBUG(0,("brl_getlocklist: talloc fail.\n")); - return NULL; /* The talloc_destroy takes care of cleanup. */ - } - - ZERO_STRUCTP(ul_new); - ul_new->start = lock->start; - ul_new->size = lock->size; - ul_new->smbpid = lock->context.smbpid; - - DLIST_ADD(ulist, ul_new); - } - } - - if (dbuf.dptr) - free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); - - return ulist; -} - - /**************************************************************************** Traverse the whole database with this function, calling traverse_callback on each lock. -- cgit From 20ce61ccc88dd3868176932736e03e4d85f1bfd0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 May 2000 02:27:41 +0000 Subject: Fix for stacking locks in brlock and POSIX. Windows only allows a read lock to overlay a write lock on the same fnum. When overlaying read locks onto a write lock, the number of locks is counted, and the first unlock removes the write lock and downgrades this to a read lock. Do the same when mapping to POSIX. Jeremy. (This used to be commit 74d42644e6e52808037975e909aa56c850838b76) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 0ded1846b4..7e403bc954 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -86,7 +86,7 @@ static BOOL brl_conflict(struct lock_struct *lck1, return False; if (brl_same_context(&lck1->context, &lck2->context) && - lck2->lock_type == READ_LOCK) return False; + 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; -- cgit From c6230f64313feb596def5685141a5de958b07d43 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 May 2000 14:29:05 +0000 Subject: - clear dead locks at startup - fixed a bug which caused lock records to not decrease in size (This used to be commit 51624a3a2f5a4ac55b4f26f572a2fc399f9c808e) --- source3/locking/brlock.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 7e403bc954..c590c51272 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -96,9 +96,46 @@ static BOOL brl_conflict(struct lock_struct *lck1, /**************************************************************************** - Open up the brlock.tdb database. +delete a record if it is for a dead process ****************************************************************************/ +static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct lock_struct *locks; + struct lock_key *key; + int count, i; + + tdb_lockchain(tdb, kbuf); + + locks = (struct lock_struct *)dbuf.dptr; + key = (struct lock_key *)kbuf.dptr; + + count = dbuf.dsize / sizeof(*locks); + for (i=0; icontext.pid)) continue; + + if (count > 1 && i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + i--; + } + if (count == 0) { + tdb_delete(tdb, kbuf); + } else if (count < (dbuf.dsize / sizeof(*locks))) { + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + } + + tdb_unlockchain(tdb, kbuf); + return 0; +} + +/**************************************************************************** + Open up the brlock.tdb database. +****************************************************************************/ void brl_init(int read_only) { if (tdb) return; @@ -106,6 +143,12 @@ void brl_init(int read_only) read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); + return; + } + + /* delete any dead locks */ + if (!read_only) { + tdb_traverse(tdb, delete_fn, NULL); } } @@ -313,7 +356,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) { struct lock_key key; TDB_DATA kbuf, dbuf; - int count, i; + int count, i, dcount=0; struct lock_struct *locks; key.device = dev; @@ -344,12 +387,14 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) } count--; i--; + dcount++; } } if (count == 0) { tdb_delete(tdb, kbuf); } else if (count < (dbuf.dsize / sizeof(*locks))) { + dbuf.dsize -= dcount * sizeof(*locks); tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); } -- cgit From 8c19fa8f7abaf97a994e733394ad3631a31dca40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 May 2000 20:33:25 +0000 Subject: Fix based on Elrond's code to reduce the store size on removing dead records. Jeremy. (This used to be commit 09e92a61a966d09f543ba541ddb3240cc4718579) --- source3/locking/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index c590c51272..51f3175dbf 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -126,6 +126,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat if (count == 0) { tdb_delete(tdb, kbuf); } else if (count < (dbuf.dsize / sizeof(*locks))) { + dbuf.dsize = count * sizeof(*locks); tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); } -- cgit From 6d9ce383061782b888f4b3403099a3c2c34b1a4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 May 2000 20:50:22 +0000 Subject: Fix for uninitialized memory read in brlock code. brl_locktest now needs to correctly set the fnum, as the brl_conflict code looks at it. Jeremy. (This used to be commit df87259a356b91989604a10b3691480dcd16cf3f) --- source3/locking/brlock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 51f3175dbf..78a9174141 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -300,7 +300,7 @@ smbpid = %u, pid = %u, tid = %u\n", Test if we could add a lock if we wanted to. ****************************************************************************/ -BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, +BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, enum brl_type lock_type) @@ -325,6 +325,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, lock.context.tid = tid; lock.start = start; lock.size = size; + lock.fnum = fnum; lock.lock_type = lock_type; if (dbuf.dptr) { -- cgit From e522de480891b9d72ba4cd2d4c8decb6909809a9 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 10 May 2000 00:05:27 +0000 Subject: Using a structure for a tdb key can lead to insideous, hard to find bugs. On 64 bit IRIX, structure packing means that a struct { SMB_DEV_T dev /* 4 bytes */ SMB_INO_T ino /* 8 bytes */ } has 4 bytes of padding between the two members. If you don't null the memory before using it as a tdb key, you randomly can't find keys depending on what is in the padding. This caused me immense pain and was hard to track down.... :-) Jeremy. (This used to be commit f2a5ba3f0939f59097f0ef6a25f1cf9b5574f157) --- source3/locking/brlock.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 78a9174141..933fc142e9 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -63,6 +63,23 @@ struct lock_key { static TDB_CONTEXT *tdb; +/**************************************************************************** + Create a locking key - ensuring zero filled for pad purposes. +****************************************************************************/ + +static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) +{ + static struct lock_key key; + TDB_DATA kbuf; + + memset(&key, '\0', sizeof(key)); + key.device = dev; + key.inode = inode; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + return kbuf; +} + /**************************************************************************** See if two locking contexts are equal. ****************************************************************************/ @@ -163,15 +180,11 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, br_off start, br_off size, enum brl_type lock_type) { - struct lock_key key; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; - key.device = dev; - key.inode = ino; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); + kbuf = locking_key(dev,ino); dbuf.dptr = NULL; @@ -222,16 +235,12 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size) { - struct lock_key key; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct *locks; struct lock_context context; - key.device = dev; - key.inode = ino; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); + kbuf = locking_key(dev,ino); dbuf.dptr = NULL; @@ -305,15 +314,11 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, br_off start, br_off size, enum brl_type lock_type) { - struct lock_key key; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; - key.device = dev; - key.inode = ino; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); + kbuf = locking_key(dev,ino); dbuf.dptr = NULL; @@ -356,15 +361,11 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) { - struct lock_key key; TDB_DATA kbuf, dbuf; int count, i, dcount=0; struct lock_struct *locks; - key.device = dev; - key.inode = ino; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); + kbuf = locking_key(dev,ino); dbuf.dptr = NULL; -- cgit From 33179a95d82a27a077acbad57d3cd9c403afb7eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Jun 2000 15:46:15 +0000 Subject: add some brackets (This used to be commit bf67721ef5cc6d5ad1762fca320ef612025b4593) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 933fc142e9..7e22b8ac7a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -158,7 +158,7 @@ void brl_init(int read_only) { if (tdb) return; tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, - read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); return; -- cgit From ac4d2775618a9ac3428d60bf667e3b968d634799 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Nov 2000 23:10:56 +0000 Subject: Fix from John Reilly for equivalence tests. Jeremy. (This used to be commit b456274a7ba22d512bab5ede979cd9363398825b) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 7e22b8ac7a..979910970f 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -440,5 +440,5 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st int brl_forall(BRLOCK_FN(fn)) { if (!tdb) return 0; - return tdb_traverse(tdb, traverse_fn, (BRLOCK_FN_CAST())fn); + return tdb_traverse(tdb, traverse_fn, (void *)fn); } -- cgit From 7e4c4721b4fbfa71ce6712ec5b9f3e8e8a105147 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Dec 2000 00:05:15 +0000 Subject: Changed to sourceforge tdb code. This includes spinlocks (so we now have a --with-spinlocks option to configure, this does mean the on-disk tdb format has changed, so 2.2alphaX sites will need to re-create their tdb's. The upside is no more tdb fragmentation and a +5% on netbench. Swings and roundabouts.... Jeremy. (This used to be commit 9dea7b7c257db487f8ced7dad3fce92fba03ea91) --- source3/locking/brlock.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 979910970f..5c3dae02c0 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -121,7 +121,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat struct lock_key *key; int count, i; - tdb_lockchain(tdb, kbuf); + tdb_chainlock(tdb, kbuf); locks = (struct lock_struct *)dbuf.dptr; key = (struct lock_key *)kbuf.dptr; @@ -147,7 +147,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); } - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return 0; } @@ -188,7 +188,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; - tdb_lockchain(tdb, kbuf); + tdb_chainlock(tdb, kbuf); dbuf = tdb_fetch(tdb, kbuf); lock.context.smbpid = smbpid; @@ -218,12 +218,12 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return True; fail: if (dbuf.dptr) free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return False; } @@ -244,7 +244,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; - tdb_lockchain(tdb, kbuf); + tdb_chainlock(tdb, kbuf); dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) { @@ -292,7 +292,7 @@ smbpid = %u, pid = %u, tid = %u\n", } free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return True; } } @@ -301,7 +301,7 @@ smbpid = %u, pid = %u, tid = %u\n", fail: if (dbuf.dptr) free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return False; } @@ -322,7 +322,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; - tdb_lockchain(tdb, kbuf); + tdb_chainlock(tdb, kbuf); dbuf = tdb_fetch(tdb, kbuf); lock.context.smbpid = smbpid; @@ -346,12 +346,12 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, /* no conflicts - we could have added it */ free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return True; fail: if (dbuf.dptr) free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); return False; } @@ -369,7 +369,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) dbuf.dptr = NULL; - tdb_lockchain(tdb, kbuf); + tdb_chainlock(tdb, kbuf); dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) goto fail; @@ -404,7 +404,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) /* we didn't find it */ fail: if (dbuf.dptr) free(dbuf.dptr); - tdb_unlockchain(tdb, kbuf); + tdb_chainunlock(tdb, kbuf); } /**************************************************************************** -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/locking/brlock.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 5c3dae02c0..175ab5c9b0 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -118,13 +118,11 @@ delete a record if it is for a dead process static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct lock_struct *locks; - struct lock_key *key; int count, i; tdb_chainlock(tdb, kbuf); locks = (struct lock_struct *)dbuf.dptr; - key = (struct lock_key *)kbuf.dptr; count = dbuf.dsize / sizeof(*locks); for (i=0; i Date: Tue, 22 May 2001 20:35:48 +0000 Subject: Defensive brlock and locking database cleaning code. Jeremy. (This used to be commit d7aa42e4593b02ee6e487f7a4633bd7e7620ef2f) --- source3/locking/brlock.c | 49 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 175ab5c9b0..089818c9aa 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -113,12 +113,16 @@ static BOOL brl_conflict(struct lock_struct *lck1, /**************************************************************************** -delete a record if it is for a dead process + Delete a record if it is for a dead process, if check_self is true, then + delete any records belonging to this pid also (there shouldn't be any). ****************************************************************************/ + static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct lock_struct *locks; int count, i; + BOOL check_self = *(BOOL *)state; + pid_t mypid = sys_getpid(); tdb_chainlock(tdb, kbuf); @@ -128,7 +132,20 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat for (i=0; icontext.pid)) continue; + /* If check_self is true we want to remove our own records. */ + if (check_self && (mypid == lock->context.pid)) { + + DEBUG(0,("brlock : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", + (unsigned int)lock->context.pid )); + + } else if (process_exists(lock->context.pid)) { + + DEBUG(10,("brlock : delete_fn. pid %u exists.\n", (unsigned int)lock->context.pid )); + continue; + } + + DEBUG(10,("brlock : delete_fn. Deleting record for process %u\n", + (unsigned int)lock->context.pid )); if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], @@ -152,9 +169,13 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat /**************************************************************************** Open up the brlock.tdb database. ****************************************************************************/ + void brl_init(int read_only) { - if (tdb) return; + BOOL check_self = False; + + if (tdb) + return; tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { @@ -163,11 +184,27 @@ void brl_init(int read_only) } /* delete any dead locks */ - if (!read_only) { - tdb_traverse(tdb, delete_fn, NULL); - } + if (!read_only) + tdb_traverse(tdb, delete_fn, &check_self); } +/**************************************************************************** + Close down the brlock.tdb database. +****************************************************************************/ + +void brl_shutdown(int read_only) +{ + BOOL check_self = True; + + if (tdb) + return; + + /* delete any dead locks */ + if (!read_only) + tdb_traverse(tdb, delete_fn, &check_self); + + tdb_close(tdb); +} /**************************************************************************** Lock a range of bytes. -- cgit From 840fb1643dbaa3ca1b435ccd85ce50123cf6252d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 May 2001 18:33:45 +0000 Subject: Stupid typo. Should be if (!tdb). Jeremy. (This used to be commit d3496897f167a8deb1d0034797e8b29f2c51acef) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 089818c9aa..552ea617aa 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -196,7 +196,7 @@ void brl_shutdown(int read_only) { BOOL check_self = True; - if (tdb) + if (!tdb) return; /* delete any dead locks */ -- cgit From 05fc3e578c895f632b351969d09cd00feb7599c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jun 2001 05:13:59 +0000 Subject: use LDSHFLAGS not -shared in several places (This used to be commit 8ec9c87b5d1a7dae17d5b1a30f58effaf5e69e4b) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 552ea617aa..8f73327830 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -176,7 +176,7 @@ void brl_init(int read_only) if (tdb) return; - tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, + tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); -- cgit From d1f38ac53107d818b88cae9ee4d4442381dc4702 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Jun 2001 01:59:48 +0000 Subject: Fixed the first locking error (test #8 found by locktest code from Clarion locktest. Jeremy. (This used to be commit 5c42845b5bb6fafd0ebf93fbdd23d9bf861da865) --- source3/locking/brlock.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 8f73327830..7f3ec6757e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -340,6 +340,26 @@ smbpid = %u, pid = %u, tid = %u\n", return False; } +/**************************************************************************** + 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; +} + /**************************************************************************** Test if we could add a lock if we wanted to. ****************************************************************************/ @@ -347,7 +367,7 @@ smbpid = %u, pid = %u, tid = %u\n", BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum brl_type lock_type) + enum brl_type lock_type, int check_self) { TDB_DATA kbuf, dbuf; int count, i; @@ -373,8 +393,15 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); for (i=0; i Date: Mon, 30 Jul 2001 22:21:31 +0000 Subject: Added "use mmap" for HPUX. Jeremy. (This used to be commit 840802f10677cb0009cb4df4c37c7d01aa5edacd) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 7f3ec6757e..1982d9982c 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -176,7 +176,7 @@ void brl_init(int read_only) if (tdb) return; - tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST, + tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); -- cgit From 2e783a47076bd0994b6ce86df7ec967bc1c2da63 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 12 Aug 2001 17:30:01 +0000 Subject: this is a big global fix for the ptr = Realloc(ptr, size) bug. many possible mem leaks, and segfaults fixed. someone should port this fix to 2.2 also. (This used to be commit fa8e55b8b465114ce209344965c1ca0333b84db9) --- source3/locking/brlock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 1982d9982c..d22297a948 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -218,6 +218,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; + char *tp; kbuf = locking_key(dev,ino); @@ -246,8 +247,9 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, } /* no conflicts - add it to the list of locks */ - dbuf.dptr = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); - if (!dbuf.dptr) goto fail; + tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); + if (!tp) goto fail; + else dbuf.dptr = tp; memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock)); dbuf.dsize += sizeof(lock); tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); -- cgit From c1598db18e2f9aafaa42bce833192bd5b83f5723 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2001 21:09:38 +0000 Subject: we now have all but the dreaded 0/0 lock working (This used to be commit 98b6aef18c793187f392f944af516c8b9ebf86e9) --- source3/locking/brlock.c | 97 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 30 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index d22297a948..a642be317c 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -98,12 +98,37 @@ static BOOL brl_same_context(struct lock_context *ctx1, 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) && - lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) return False; + lck1->fnum == lck2->fnum) + return False; if (lck1->start >= (lck2->start + lck2->size) || lck2->start >= (lck1->start + lck1->size)) return False; @@ -224,6 +249,13 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; +#if 0 + if (start == 0 && size == 0) { + tdb_delete(tdb, kbuf); + return True; + } +#endif + tdb_chainlock(tdb, kbuf); dbuf = tdb_fetch(tdb, kbuf); @@ -246,6 +278,14 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, } } +#if 0 + if (start == 0 && size == 0) { + if (dbuf.dptr) free(dbuf.dptr); + tdb_chainunlock(tdb, kbuf); + return True; + } +#endif + /* no conflicts - add it to the list of locks */ tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); if (!tp) goto fail; @@ -296,21 +336,37 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, /* there are existing locks - find a match */ locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); - for (i=0; icontext, &context)) { - DEBUG(10,("brl_unlock: Not same context. l_smbpid = %u, l_pid = %u, l_tid = %u: \ -smbpid = %u, pid = %u, tid = %u\n", - lock->context.smbpid, lock->context.pid, lock->context.tid, - context.smbpid, context.pid, context.tid )); + if (lock->lock_type == WRITE_LOCK && + brl_same_context(&lock->context, &context) && + lock->fnum == fnum && + lock->start == start && + lock->size == size) { + /* found it - delete it */ + if (count == 1) { + tdb_delete(tdb, kbuf); + } else { + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + dbuf.dsize -= sizeof(*locks); + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + } + free(dbuf.dptr); + tdb_chainunlock(tdb, kbuf); + return True; } - /* JRATEST */ -#endif + } + + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + for (i=0; icontext, &context) && lock->fnum == fnum && @@ -342,25 +398,6 @@ smbpid = %u, pid = %u, tid = %u\n", return False; } -/**************************************************************************** - 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; -} /**************************************************************************** Test if we could add a lock if we wanted to. -- cgit From 10c240ef977333e3ad0f340961c5d4a807d35144 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 26 Aug 2001 19:27:18 +0000 Subject: Don't use CLEAR_IF_FIRST if opening read-only. Jeremy. (This used to be commit f5ba19c12989dd1e996473869468afcfc5dce72e) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index a642be317c..dc2f39e7d9 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -201,7 +201,7 @@ void brl_init(int read_only) if (tdb) return; - tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG, + tdb = tdb_open_log(lock_path("brlock.tdb"), 0, USE_TDB_MMAP_FLAG|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); -- cgit From e8e98c9ea0690e3acf1126b50882e59e1056c7b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 08:19:43 +0000 Subject: converted smbd to use NTSTATUS by default major changes include: - added NSTATUS type - added automatic mapping between dos and nt error codes - changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT() these calls auto-translate to the client error code system - got rid of the cached error code and the writebmpx code We eventually will need to also: - get rid of BOOL, so we don't lose error info - replace all ERROR_DOS() calls with ERROR_NT() calls but that is too much for one night (This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518) --- source3/locking/brlock.c | 71 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 11 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index dc2f39e7d9..e21effe6eb 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -30,6 +30,8 @@ extern int DEBUGLEVEL; +#define ZERO_ZERO 0 + /* This contains elements that differentiate locks. The smbpid is a client supplied pid, and is essentially the locking context for this client */ @@ -116,6 +118,32 @@ static BOOL brl_conflict(struct lock_struct *lck1, return True; } +#if ZERO_ZERO +static BOOL brl_conflict1(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 (lck2->start == 0 && lck2->size == 0 && lck1->size != 0) { + return True; + } + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) { + return False; + } + + return True; +} +#endif + /**************************************************************************** Check to see if this lock conflicts, but ignore our own locks on the same fnum only. @@ -231,6 +259,21 @@ void brl_shutdown(int read_only) tdb_close(tdb); } +#if ZERO_ZERO +/**************************************************************************** +compare two locks for sorting +****************************************************************************/ +static int lock_compare(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->start != lck2->start) return (lck1->start - lck2->start); + if (lck2->size != lck1->size) { + return ((int)lck1->size - (int)lck2->size); + } + return 0; +} +#endif + /**************************************************************************** Lock a range of bytes. ****************************************************************************/ @@ -249,10 +292,10 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; -#if 0 +#if !ZERO_ZERO if (start == 0 && size == 0) { - tdb_delete(tdb, kbuf); - return True; + DEBUG(0,("client sent 0/0 lock - please report this\n")); + return False; } #endif @@ -275,23 +318,27 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, if (brl_conflict(&locks[i], &lock)) { goto fail; } +#if ZERO_ZERO + if (lock.start == 0 && lock.size == 0 && + locks[i].size == 0) { + break; + } +#endif } } -#if 0 - if (start == 0 && size == 0) { - if (dbuf.dptr) free(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return True; - } -#endif - /* no conflicts - add it to the list of locks */ tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); if (!tp) goto fail; else dbuf.dptr = tp; memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock)); dbuf.dsize += sizeof(lock); + +#if ZERO_ZERO + /* sort the lock list */ + qsort(dbuf.dptr, dbuf.dsize/sizeof(lock), sizeof(lock), lock_compare); +#endif + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); free(dbuf.dptr); @@ -337,6 +384,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); +#if ZERO_ZERO for (i=0; i Date: Thu, 6 Sep 2001 01:19:35 +0000 Subject: use NTSTATUS not BOOL in do_lock() (This used to be commit b1b2a5fa5d084dad8ae47777419ab75db1e51eff) --- source3/locking/brlock.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index e21effe6eb..f4c41d0349 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -278,15 +278,16 @@ static int lock_compare(struct lock_struct *lck1, Lock a range of bytes. ****************************************************************************/ -BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, pid_t pid, uint16 tid, - br_off start, br_off size, - enum brl_type lock_type) +NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, + uint16 smbpid, pid_t pid, uint16 tid, + br_off start, br_off size, + enum brl_type lock_type) { TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; char *tp; + NTSTATUS status = NT_STATUS_OK; kbuf = locking_key(dev,ino); @@ -295,7 +296,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, #if !ZERO_ZERO if (start == 0 && size == 0) { DEBUG(0,("client sent 0/0 lock - please report this\n")); - return False; + return NT_STATUS_INVALID_PARAMETER; } #endif @@ -316,6 +317,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, count = dbuf.dsize / sizeof(*locks); for (i=0; i Date: Thu, 6 Sep 2001 22:08:19 +0000 Subject: got rid of USE_TDB_MMAP_FLAG as its not needed any more (This used to be commit c26e0d3f27a05ecc8bd2390f9aab7f9451524e47) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index f4c41d0349..2b21761cb2 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -229,7 +229,7 @@ void brl_init(int read_only) if (tdb) return; - tdb = tdb_open_log(lock_path("brlock.tdb"), 0, USE_TDB_MMAP_FLAG|(read_only?0x0:TDB_CLEAR_IF_FIRST), + tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); -- cgit From 81fdc3c3f76075babe3e1f4bf43ed2cfd5723472 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 04:16:35 +0000 Subject: move to SAFE_FREE() (This used to be commit e61aec84edaf55b9ee087b076d2f1311033dc839) --- source3/locking/brlock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 2b21761cb2..b16cc539c8 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -347,12 +347,12 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return NT_STATUS_OK; fail: - if (dbuf.dptr) free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return status; } @@ -411,7 +411,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); } - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return True; } @@ -439,7 +439,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); } - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return True; } @@ -448,7 +448,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, /* we didn't find it */ fail: - if (dbuf.dptr) free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return False; } @@ -501,12 +501,12 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, } /* no conflicts - we could have added it */ - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return True; fail: - if (dbuf.dptr) free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return False; } @@ -559,7 +559,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) /* we didn't find it */ fail: - if (dbuf.dptr) free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/locking/brlock.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index b16cc539c8..cbf98c46a5 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -28,8 +28,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - #define ZERO_ZERO 0 /* This contains elements that differentiate locks. The smbpid is a -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/locking/brlock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index cbf98c46a5..2131919674 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. byte range locking code Updated to handle range splits/merges. -- cgit From d160b3524063607b6e7431ec5973af3eaa176f6c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 5 Mar 2002 19:54:45 +0000 Subject: accept the 0/0 lock but don't treat it in any sort of special way (This used to be commit 8f7bf38de16a1f5316aa6a413fb697c43862c4c6) --- source3/locking/brlock.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 2131919674..10c1d5053b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -293,7 +293,6 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, #if !ZERO_ZERO if (start == 0 && size == 0) { DEBUG(0,("client sent 0/0 lock - please report this\n")); - return NT_STATUS_INVALID_PARAMETER; } #endif -- cgit From be389e25ddff982a490c2b88c4649ce437a0d4d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 23:17:07 +0000 Subject: this attempts to handle the rather bizarre lock cache semantics in w2k. It isn't entirely accurate, but its close (This used to be commit e02d7364707c4939efa4ff0ddf9b6d4f48e5d411) --- source3/locking/brlock.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 10c1d5053b..e7fa4022f6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -285,6 +285,8 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, struct lock_struct lock, *locks; char *tp; NTSTATUS status = NT_STATUS_OK; + static int last_failed = -1; + static br_off last_failed_start; kbuf = locking_key(dev,ino); @@ -348,6 +350,18 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, return NT_STATUS_OK; fail: + /* this is a nasty hack to try to simulate the lock result cache code in w2k. + It isn't completely accurate as I haven't yet worked out the correct + semantics (tridge) + */ + if (last_failed == fnum && + last_failed_start == start && + NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) { + status = NT_STATUS_FILE_LOCK_CONFLICT; + } + last_failed = fnum; + last_failed_start = start; + SAFE_FREE(dbuf.dptr); tdb_chainunlock(tdb, kbuf); return status; -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/locking/brlock.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index e7fa4022f6..8c22f7d7ab 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -162,6 +162,10 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck } +#if DONT_DO_THIS + /* doing this traversal could kill solaris machines under high load (tridge) */ + /* delete any dead locks */ + /**************************************************************************** Delete a record if it is for a dead process, if check_self is true, then delete any records belonging to this pid also (there shouldn't be any). @@ -215,6 +219,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat tdb_chainunlock(tdb, kbuf); return 0; } +#endif /**************************************************************************** Open up the brlock.tdb database. @@ -222,8 +227,6 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat void brl_init(int read_only) { - BOOL check_self = False; - if (tdb) return; tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), @@ -233,9 +236,14 @@ void brl_init(int read_only) return; } +#if DONT_DO_THIS + /* doing this traversal could kill solaris machines under high load (tridge) */ /* delete any dead locks */ - if (!read_only) + if (!read_only) { + BOOL check_self = False; tdb_traverse(tdb, delete_fn, &check_self); + } +#endif } /**************************************************************************** @@ -244,14 +252,17 @@ void brl_init(int read_only) void brl_shutdown(int read_only) { - BOOL check_self = True; - if (!tdb) return; +#if DONT_DO_THIS + /* doing this traversal could kill solaris machines under high load (tridge) */ /* delete any dead locks */ - if (!read_only) + if (!read_only) { + BOOL check_self = True; tdb_traverse(tdb, delete_fn, &check_self); + } +#endif tdb_close(tdb); } -- cgit From 285a3b0ef869382aea892cad37284ba9cbe529d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 22 Feb 2003 01:09:57 +0000 Subject: When checking is_locked() new WRITE locks conflict with existing READ locks even if the context is the same. See LOCKTEST7 in smbtorture. Jeremy. (This used to be commit 1698092ba5a169de369ad1182a6f270de174c3f5) --- source3/locking/brlock.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 8c22f7d7ab..9902c7bbd7 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -151,9 +151,16 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck 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; + /* + * Incoming WRITE locks conflict with existing READ locks even + * if the context is the same. JRA. See LOCKTEST7 in smbtorture. + */ + + if (!(lck2->lock_type == WRITE_LOCK && lck1->lock_type == READ_LOCK)) { + if (brl_same_context(&lck1->context, &lck2->context) && + lck1->fnum == lck2->fnum) + return False; + } if (lck1->start >= (lck2->start + lck2->size) || lck2->start >= (lck1->start + lck1->size)) return False; -- cgit From fb3e4b87973e9ad0c818e8d9dd60329c47f22afe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Feb 2003 01:04:34 +0000 Subject: Fix to allow blocking lock notification to be done rapidly (no wait for smb -> smb lock release). Adds new PENDING_LOCK type to lockdb (does not interfere with existing locks). Jeremy. (This used to be commit 766928bbba1e597c9c2b12458dd8d37e6080593e) --- source3/locking/brlock.c | 82 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 6 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9902c7bbd7..4cd885f1a6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -98,6 +98,9 @@ static BOOL brl_same_context(struct lock_context *ctx1, static BOOL brl_conflict(struct lock_struct *lck1, struct lock_struct *lck2) { + if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + return False; + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { return False; } @@ -119,6 +122,9 @@ static BOOL brl_conflict(struct lock_struct *lck1, static BOOL brl_conflict1(struct lock_struct *lck1, struct lock_struct *lck2) { + if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + return False; + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { return False; } @@ -148,6 +154,9 @@ static BOOL brl_conflict1(struct lock_struct *lck1, static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) { + if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + return False; + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) return False; @@ -385,16 +394,30 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, return status; } +/**************************************************************************** + Check if an unlock overlaps a pending lock. +****************************************************************************/ + +static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pend_lock) +{ + if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) + return True; + if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size)) + return True; + return False; +} + /**************************************************************************** Unlock a range of bytes. ****************************************************************************/ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, - br_off start, br_off size) + br_off start, br_off size, + BOOL remove_pending_locks_only) { TDB_DATA kbuf, dbuf; - int count, i; + int count, i, j; struct lock_struct *locks; struct lock_context context; @@ -452,9 +475,34 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, struct lock_struct *lock = &locks[i]; if (brl_same_context(&lock->context, &context) && - lock->fnum == fnum && - lock->start == start && - lock->size == size) { + lock->fnum == fnum && + lock->start == start && + lock->size == size) { + + if (remove_pending_locks_only && lock->lock_type != PENDING_LOCK) + continue; + + if (lock->lock_type != PENDING_LOCK) { + /* Send unlock messages to any pending waiters that overlap. */ + for (j=0; jlock_type != PENDING_LOCK) + continue; + + /* We could send specific lock info here... */ + if (brl_pending_overlap(lock, pend_lock)) { + DEBUG(10,("brl_unlock: sending unlock message to pid %u\n", + (unsigned int)pend_lock->context.pid )); + + message_send_pid(pend_lock->context.pid, + MSG_SMB_UNLOCK, + NULL, 0, True); + } + } + } + /* found it - delete it */ if (count == 1) { tdb_delete(tdb, kbuf); @@ -546,7 +594,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) { TDB_DATA kbuf, dbuf; - int count, i, dcount=0; + int count, i, j, dcount=0; struct lock_struct *locks; kbuf = locking_key(dev,ino); @@ -561,12 +609,34 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) /* 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 == tid && lock->context.pid == pid && lock->fnum == fnum) { + + /* Send unlock messages to any pending waiters that overlap. */ + for (j=0; jlock_type != PENDING_LOCK) + continue; + + if (pend_lock->context.tid == tid && + pend_lock->context.pid == pid && + pend_lock->fnum == fnum) + continue; + + /* We could send specific lock info here... */ + if (brl_pending_overlap(lock, pend_lock)) + message_send_pid(pend_lock->context.pid, + MSG_SMB_UNLOCK, + NULL, 0, True); + } + /* found it - delete it */ if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], -- cgit From 34226f1bd4d90ffe0f324277b11bbc4f2b575740 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Apr 2003 20:38:12 +0000 Subject: Fix for very subtle POSIX lock interaction race condition found by Herb. We need to unlock POSIX locks before notifying pending lock processes. Jeremy. (This used to be commit 6999eef51c3e597b3b2cd9cc26138acdfbb6a23a) --- source3/locking/brlock.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 4cd885f1a6..20d76c9c79 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -414,7 +414,9 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - BOOL remove_pending_locks_only) + BOOL remove_pending_locks_only, + void (*pre_unlock_fn)(void *), + void *pre_unlock_data) { TDB_DATA kbuf, dbuf; int count, i, j; @@ -450,6 +452,10 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, lock->fnum == fnum && lock->start == start && lock->size == size) { + + if (pre_unlock_fn) + (*pre_unlock_fn)(pre_unlock_data); + /* found it - delete it */ if (count == 1) { tdb_delete(tdb, kbuf); @@ -483,6 +489,11 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, continue; if (lock->lock_type != PENDING_LOCK) { + + /* Do any POSIX unlocks needed. */ + if (pre_unlock_fn) + (*pre_unlock_fn)(pre_unlock_data); + /* Send unlock messages to any pending waiters that overlap. */ for (j=0; j Date: Thu, 9 Oct 2003 01:46:01 +0000 Subject: Changes to allow Samba3 to pass the Samba4 RAW-READ tests. Jeremy. (This used to be commit e7565dbba696adbb0fd8cca6b86a1a7e5a655f2e) --- source3/locking/brlock.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 20d76c9c79..c51a5a2aac 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -172,7 +172,8 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck } if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) return False; + lck2->start >= (lck1->start + lck1->size)) + return False; return True; } @@ -305,7 +306,7 @@ static int lock_compare(struct lock_struct *lck1, NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum brl_type lock_type) + enum brl_type lock_type, BOOL *my_lock_ctx) { TDB_DATA kbuf, dbuf; int count, i; @@ -315,6 +316,7 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, static int last_failed = -1; static br_off last_failed_start; + *my_lock_ctx = False; kbuf = locking_key(dev,ino); dbuf.dptr = NULL; @@ -343,6 +345,9 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, for (i=0; i Date: Thu, 12 Feb 2004 05:24:02 +0000 Subject: merge from old APP_HEAD * remove corrupt tdb and shutdown (only for printing tdbs, connections, sessionid & locking) * decrement smbd counter in connections.tdb in smb_panic() * various Makefile hack to get things to link 'max smbd processes' looks like it might be broken. The counter KEY is not being set. Will look into that tomorrow. (This used to be commit 6e22c5da929b6d9a4e32dc704c83112b2ad8fcfd) --- source3/locking/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index c51a5a2aac..47001c8b89 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -246,8 +246,8 @@ void brl_init(int read_only) { if (tdb) return; - tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); + tdb = tdb_open_ex(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644, smbd_tdb_log); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); return; -- cgit From 386a11f49eff2ec60d75b9966ecdc5627b259f0d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Jun 2004 17:26:09 +0000 Subject: r1011: fix bad merge (from a few months ago) and ensure that we always use tdb_open_log() instead of tdb_open_ex() (This used to be commit e65564ab4aa1240e84b8d272510aa770cad0ed0e) --- source3/locking/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 47001c8b89..990a6a25d2 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -246,8 +246,8 @@ void brl_init(int read_only) { if (tdb) return; - tdb = tdb_open_ex(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644, smbd_tdb_log); + tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); return; -- cgit From b0202c7b851bb15f856ba526857e8b2f7cfabfec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 00:22:11 +0000 Subject: r3008: when checking for the existance of a lock we are only doing a single tdb call, so there is no need to get the chainlock. This reduces the number of tdb locking calls made on file IO (This used to be commit 78e904c27b31d7123b521c446247d6ff558c84cc) --- source3/locking/brlock.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 990a6a25d2..4c34bd7dfd 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -563,7 +563,6 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, dbuf.dptr = NULL; - tdb_chainlock(tdb, kbuf); dbuf = tdb_fetch(tdb, kbuf); lock.context.smbpid = smbpid; @@ -594,12 +593,10 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, /* no conflicts - we could have added it */ SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); return True; fail: SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); return False; } -- cgit From 8c1c918c94b443c7154d535b1f99201dc1767f97 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 18 Oct 2004 22:01:10 +0000 Subject: r3050: Steal from Samba4 :-). Make us pass most of the new lock tests (except for the cancel lock which I have to add). Jeremy. (This used to be commit cf7f89999e0c6becd4617c812400d1e71b9c0a30) --- source3/locking/brlock.c | 73 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 17 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 4c34bd7dfd..61144eb59a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -91,6 +91,28 @@ static BOOL brl_same_context(struct lock_context *ctx1, (ctx1->tid == ctx2->tid); } +/**************************************************************************** + 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. ****************************************************************************/ @@ -115,7 +137,7 @@ static BOOL brl_conflict(struct lock_struct *lck1, return False; } - return True; + return brl_overlap(lck1, lck2); } #if ZERO_ZERO @@ -175,9 +197,36 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck 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 lock_struct *lock) +{ + static struct lock_struct last_lock_failure; + + if (brl_same_context(&lock->context, &last_lock_failure.context) && + lock->fnum == last_lock_failure.fnum && + lock->start == last_lock_failure.start && + lock->size == last_lock_failure.size) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + last_lock_failure = *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 */ + return NT_STATUS_FILE_LOCK_CONFLICT; + } + return NT_STATUS_LOCK_NOT_GRANTED; +} #if DONT_DO_THIS /* doing this traversal could kill solaris machines under high load (tridge) */ @@ -313,8 +362,6 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, struct lock_struct lock, *locks; char *tp; NTSTATUS status = NT_STATUS_OK; - static int last_failed = -1; - static br_off last_failed_start; *my_lock_ctx = False; kbuf = locking_key(dev,ino); @@ -344,7 +391,7 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, count = dbuf.dsize / sizeof(*locks); for (i=0; i Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 61144eb59a..d92027e267 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -407,7 +407,7 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, } /* no conflicts - add it to the list of locks */ - tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); + tp = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(*locks)); if (!tp) { status = NT_STATUS_NO_MEMORY; goto fail; -- cgit From 695188cc262c08807760670c2b6d8c70deda2cdc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Dec 2004 01:07:06 +0000 Subject: r4108: As check_self is *always* False in every invokation, remove the logic for it. We still pass Samba4 RAW-LOCK test. Jeremy. (This used to be commit 596f23051363f8cc8896119b3eca0663a61a38c3) --- source3/locking/brlock.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index d92027e267..3451b0cc1a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -592,7 +592,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum brl_type lock_type, int check_self) + enum brl_type lock_type) { TDB_DATA kbuf, dbuf; int count, i; @@ -617,16 +617,11 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); for (i=0; i Date: Thu, 3 Mar 2005 02:07:00 +0000 Subject: r5634: Fix 64-bit overflow problems found by BlueArc torture tester. We still have a few strange bugs with 64-bit locking values. I will get traces. Jeremy. (This used to be commit ff4c201d93e1f59ce61e9341f7f94ce92389ed7b) --- source3/locking/brlock.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 3451b0cc1a..09c96b1286 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -132,11 +132,6 @@ 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 brl_overlap(lck1, lck2); } @@ -193,10 +188,6 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck return False; } - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) - return False; - return brl_overlap(lck1, lck2); } -- cgit From ed1f7121a39d863066ef47e985b77fe3dbedbc9b Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 27 Apr 2005 18:32:37 +0000 Subject: r6502: add LOCKING debug class - pull PRINTINGDB class definition from trunk so our numbers don't get out of sync (This used to be commit 58e307664e02ebf0415f19ed625d2f166d9cb1cc) --- source3/locking/brlock.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 09c96b1286..da7fc1e67d 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -27,6 +27,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_LOCKING + #define ZERO_ZERO 0 /* This contains elements that differentiate locks. The smbpid is a -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/locking/brlock.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index da7fc1e67d..25a1ed5e2f 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -39,7 +39,7 @@ struct lock_context { uint16 smbpid; uint16 tid; - pid_t pid; + struct process_id pid; }; /* The data in brlock records is an unsorted linear array of these @@ -89,9 +89,9 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) { - return (ctx1->pid == ctx2->pid) && + return (procid_equal(&ctx1->pid, &ctx2->pid) && (ctx1->smbpid == ctx2->smbpid) && - (ctx1->tid == ctx2->tid); + (ctx1->tid == ctx2->tid)); } /**************************************************************************** @@ -252,7 +252,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat DEBUG(0,("brlock : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", (unsigned int)lock->context.pid )); - } else if (process_exists(lock->context.pid)) { + } else if (process_exists(&lock->context.pid)) { DEBUG(10,("brlock : delete_fn. pid %u exists.\n", (unsigned int)lock->context.pid )); continue; @@ -347,7 +347,7 @@ static int lock_compare(struct lock_struct *lck1, ****************************************************************************/ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, pid_t pid, uint16 tid, + uint16 smbpid, struct process_id pid, uint16 tid, br_off start, br_off size, enum brl_type lock_type, BOOL *my_lock_ctx) { @@ -450,7 +450,7 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe ****************************************************************************/ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, pid_t pid, uint16 tid, + uint16 smbpid, struct process_id pid, uint16 tid, br_off start, br_off size, BOOL remove_pending_locks_only, void (*pre_unlock_fn)(void *), @@ -542,8 +542,8 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, /* We could send specific lock info here... */ if (brl_pending_overlap(lock, pend_lock)) { - DEBUG(10,("brl_unlock: sending unlock message to pid %u\n", - (unsigned int)pend_lock->context.pid )); + DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", + procid_str_static(&pend_lock->context.pid ))); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, @@ -584,7 +584,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, ****************************************************************************/ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, pid_t pid, uint16 tid, + uint16 smbpid, struct process_id pid, uint16 tid, br_off start, br_off size, enum brl_type lock_type) { @@ -632,7 +632,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, Remove any locks associated with a open file. ****************************************************************************/ -void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) +void brl_close(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, int tid, int fnum) { TDB_DATA kbuf, dbuf; int count, i, j, dcount=0; @@ -655,7 +655,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) struct lock_struct *lock = &locks[i]; if (lock->context.tid == tid && - lock->context.pid == pid && + procid_equal(&lock->context.pid, &pid) && lock->fnum == fnum) { /* Send unlock messages to any pending waiters that overlap. */ @@ -667,7 +667,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum) continue; if (pend_lock->context.tid == tid && - pend_lock->context.pid == pid && + procid_equal(&pend_lock->context.pid, &pid) && pend_lock->fnum == fnum) continue; -- cgit From 894358a8f3e338b339b6c37233edef794b312087 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Mar 2006 06:31:04 +0000 Subject: r13915: Fixed a very interesting class of realloc() bugs found by Coverity. realloc can return NULL in one of two cases - (1) the realloc failed, (2) realloc succeeded but the new size requested was zero, in which case this is identical to a free() call. The error paths dealing with these two cases should be different, but mostly weren't. Secondly the standard idiom for dealing with realloc when you know the new size is non-zero is the following : tmp = realloc(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } However, there were *many* *many* places in Samba where we were using the old (broken) idiom of : p = realloc(p, size) if (!p) { return error; } which will leak the memory pointed to by p on realloc fail. This commit (hopefully) fixes all these cases by moving to a standard idiom of : p = SMB_REALLOC(p, size) if (!p) { return error; } Where if the realloc returns null due to the realloc failing or size == 0 we *guarentee* that the storage pointed to by p has been freed. This allows me to remove a lot of code that was dealing with the standard (more verbose) method that required a tmp pointer. This is almost always what you want. When a realloc fails you never usually want the old memory, you want to free it and get into your error processing asap. For the 11 remaining cases where we really do need to keep the old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR, which can be used as follows : tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the pointer p, even on size == 0 or realloc fail. All this is done by a hidden extra argument to Realloc(), BOOL free_old_on_error which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR macros (and their array counterparts). It remains to be seen what this will do to our Coverity bug count :-). Jeremy. (This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0) --- source3/locking/brlock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 25a1ed5e2f..8af6effb19 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -354,7 +354,6 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; - char *tp; NTSTATUS status = NT_STATUS_OK; *my_lock_ctx = False; @@ -401,12 +400,10 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, } /* no conflicts - add it to the list of locks */ - tp = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(*locks)); - if (!tp) { + dbuf.dptr = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(*locks)); + if (!dbuf.dptr) { status = NT_STATUS_NO_MEMORY; goto fail; - } else { - dbuf.dptr = tp; } memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock)); dbuf.dsize += sizeof(lock); -- cgit From 81d4f40bbe202e5dae3d4d1070b02edf16a9f62e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Mar 2006 22:19:01 +0000 Subject: r14763: Add a new tuning parameter, open files database hash size, this allows us to experiment with ensuring the tdb hash size for our open files and locking db are appropriately sized. Make the hash size larger by default (10007 instead of 1049) and make the locking db hash size the same as the open file db hash size. Jeremy. (This used to be commit e7225f7e813423c3e2a94af6a9d7ce8a1b50a166) --- source3/locking/brlock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 8af6effb19..5078515b3e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -289,8 +289,10 @@ void brl_init(int read_only) { if (tdb) return; - tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); + tdb = tdb_open_log(lock_path("brlock.tdb"), + lp_open_files_db_hash_size(), + TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); return; -- cgit From 22dbd67708f1651a2341d70ce576fac360affccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 15:33:04 +0000 Subject: r15018: Merge Volker's ipc/trans2/nttrans changes over into 3.0. Also merge the new POSIX lock code - this is not enabled unless -DDEVELOPER is defined. This doesn't yet map onto underlying system POSIX locks. Updates vfs to allow lock queries. Jeremy. (This used to be commit 08e52ead03304ff04229e1bfe544ff40e2564fc7) --- source3/locking/brlock.c | 1300 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 985 insertions(+), 315 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 5078515b3e..b95bb895cc 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -52,6 +52,7 @@ struct lock_struct { br_off size; int fnum; enum brl_type lock_type; + enum brl_flavour lock_flav; }; /* The key used in the brlock database. */ @@ -65,6 +66,26 @@ struct lock_key { static TDB_CONTEXT *tdb; +/**************************************************************************** + Debug info at level 10 for lock struct. +****************************************************************************/ + +static void print_lock_struct(unsigned int i, struct lock_struct *pls) +{ + DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %u, ", + i, + (unsigned int)pls->context.smbpid, + (unsigned int)pls->context.tid, + (unsigned int)procid_to_pid(&pls->context.pid) )); + + DEBUG(10,("start = %.0f, size = %.0f, fnum = %d, %s %s\n", + (double)pls->start, + (double)pls->size, + pls->fnum, + lock_type_name(pls->lock_type), + lock_flav_name(pls->lock_flav) )); +} + /**************************************************************************** Create a locking key - ensuring zero filled for pad purposes. ****************************************************************************/ @@ -86,8 +107,8 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) See if two locking contexts are equal. ****************************************************************************/ -static BOOL brl_same_context(struct lock_context *ctx1, - struct lock_context *ctx2) +static BOOL brl_same_context(const struct lock_context *ctx1, + const struct lock_context *ctx2) { return (procid_equal(&ctx1->pid, &ctx2->pid) && (ctx1->smbpid == ctx2->smbpid) && @@ -98,8 +119,8 @@ static BOOL brl_same_context(struct lock_context *ctx1, See if lck1 and lck2 overlap. ****************************************************************************/ -static BOOL brl_overlap(struct lock_struct *lck1, - struct lock_struct *lck2) +static BOOL brl_overlap(const struct lock_struct *lck1, + const struct lock_struct *lck2) { /* this extra check is not redundent - it copes with locks that go beyond the end of 64 bit file space */ @@ -120,12 +141,14 @@ static BOOL brl_overlap(struct lock_struct *lck1, See if lock2 can be added when lock1 is in place. ****************************************************************************/ -static BOOL brl_conflict(struct lock_struct *lck1, - struct lock_struct *lck2) +static BOOL brl_conflict(const struct lock_struct *lck1, + const struct lock_struct *lck2) { + /* Ignore PENDING locks. */ if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) return False; + /* Read locks never conflict. */ if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { return False; } @@ -138,9 +161,42 @@ static BOOL brl_conflict(struct lock_struct *lck1, return brl_overlap(lck1, lck2); } +/**************************************************************************** + See if lock2 can be added when lock1 is in place - when both locks are POSIX + flavour. POSIX locks ignore fnum - they only care about dev/ino which we + know already match. +****************************************************************************/ + +static BOOL brl_conflict_posix(const struct lock_struct *lck1, + const struct lock_struct *lck2) +{ +#if defined(DEVELOPER) + SMB_ASSERT(lck1->lock_flav == POSIX_LOCK); + SMB_ASSERT(lck2->lock_flav == POSIX_LOCK); +#endif + + /* Ignore PENDING locks. */ + if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + return False; + + /* Read locks never conflict. */ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { + return False; + } + + /* Locks on the same context con't conflict. Ignore fnum. */ + if (brl_same_context(&lck1->context, &lck2->context)) { + return False; + } + + /* One is read, the other write, or the context is different, + do they overlap ? */ + return brl_overlap(lck1, lck2); +} + #if ZERO_ZERO -static BOOL brl_conflict1(struct lock_struct *lck1, - struct lock_struct *lck2) +static BOOL brl_conflict1(const struct lock_struct *lck1, + const struct lock_struct *lck2) { if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) return False; @@ -169,10 +225,11 @@ static BOOL brl_conflict1(struct lock_struct *lck1, /**************************************************************************** Check to see if this lock conflicts, but ignore our own locks on the - same fnum only. + same fnum only. This is the read/write lock check code path. + This is never used in the POSIX lock case. ****************************************************************************/ -static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2) { if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) return False; @@ -180,6 +237,12 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) return False; + /* POSIX flavour locks never conflict here - this is only called + in the read/write path. */ + + if (lck1->lock_flav == POSIX_LOCK && lck2->lock_flav == POSIX_LOCK) + return False; + /* * Incoming WRITE locks conflict with existing READ locks even * if the context is the same. JRA. See LOCKTEST7 in smbtorture. @@ -200,7 +263,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck app depends on this ? ****************************************************************************/ -static NTSTATUS brl_lock_failed(struct lock_struct *lock) +static NTSTATUS brl_lock_failed(const struct lock_struct *lock) { static struct lock_struct last_lock_failure; @@ -222,146 +285,432 @@ static NTSTATUS brl_lock_failed(struct lock_struct *lock) return NT_STATUS_LOCK_NOT_GRANTED; } -#if DONT_DO_THIS - /* doing this traversal could kill solaris machines under high load (tridge) */ - /* delete any dead locks */ - /**************************************************************************** - Delete a record if it is for a dead process, if check_self is true, then - delete any records belonging to this pid also (there shouldn't be any). + Open up the brlock.tdb database. ****************************************************************************/ -static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +void brl_init(int read_only) { - struct lock_struct *locks; - int count, i; - BOOL check_self = *(BOOL *)state; - pid_t mypid = sys_getpid(); - - tdb_chainlock(tdb, kbuf); + if (tdb) { + return; + } + tdb = tdb_open_log(lock_path("brlock.tdb"), + lp_open_files_db_hash_size(), + TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); + if (!tdb) { + DEBUG(0,("Failed to open byte range locking database %s\n", + lock_path("brlock.tdb"))); + return; + } +} - locks = (struct lock_struct *)dbuf.dptr; +/**************************************************************************** + Close down the brlock.tdb database. +****************************************************************************/ - count = dbuf.dsize / sizeof(*locks); - for (i=0; icontext.pid)) { +#if ZERO_ZERO +/**************************************************************************** + Compare two locks for sorting. +****************************************************************************/ - DEBUG(0,("brlock : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", - (unsigned int)lock->context.pid )); +static int lock_compare(const struct lock_struct *lck1, + const struct lock_struct *lck2) +{ + if (lck1->start != lck2->start) { + return (lck1->start - lck2->start); + } + if (lck2->size != lck1->size) { + return ((int)lck1->size - (int)lck2->size); + } + return 0; +} +#endif - } else if (process_exists(&lock->context.pid)) { +/**************************************************************************** + Lock a range of bytes - Windows lock semantics. +****************************************************************************/ - DEBUG(10,("brlock : delete_fn. pid %u exists.\n", (unsigned int)lock->context.pid )); - continue; +static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, + const struct lock_struct *plock, + BOOL *my_lock_ctx) +{ + unsigned int i; + files_struct *fsp = br_lck->fsp; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + + for (i=0; i < br_lck->num_locks; i++) { + /* Do any Windows or POSIX locks conflict ? */ + if (brl_conflict(&locks[i], plock)) { + NTSTATUS status = brl_lock_failed(plock);; + /* Did we block ourselves ? */ + if (brl_same_context(&locks[i].context, &plock->context)) { + *my_lock_ctx = True; + } + return status; + } +#if ZERO_ZERO + if (plock->start == 0 && plock->size == 0 && + locks[i].size == 0) { + break; } +#endif + } - DEBUG(10,("brlock : delete_fn. Deleting record for process %u\n", - (unsigned int)lock->context.pid )); + /* We can get the Windows lock, now see if it needs to + be mapped into a lower level POSIX one, and if so can + we get it ? We tell the lower lock layer about the + lock type so it can cope with the difference between + Windows "stacking" locks and POSIX "flat" ones. */ - if (count > 1 && i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); + if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { + if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, WINDOWS_LOCK)) { + if (errno == EACCES || errno == EAGAIN) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } else { + return map_nt_error_from_unix(errno); + } } - count--; - i--; } - if (count == 0) { - tdb_delete(tdb, kbuf); - } else if (count < (dbuf.dsize / sizeof(*locks))) { - dbuf.dsize = count * sizeof(*locks); - tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + /* no conflicts - add it to the list of locks */ + locks = (struct lock_struct *)SMB_REALLOC(locks, (br_lck->num_locks + 1) * sizeof(*locks)); + if (!locks) { + return NT_STATUS_NO_MEMORY; } - tdb_chainunlock(tdb, kbuf); - return 0; + memcpy(&locks[br_lck->num_locks], plock, sizeof(struct lock_struct)); + br_lck->num_locks += 1; + br_lck->lock_data = (void *)locks; + br_lck->modified = True; + + return NT_STATUS_OK; } -#endif /**************************************************************************** - Open up the brlock.tdb database. + Cope with POSIX range splits and merges. ****************************************************************************/ -void brl_init(int read_only) +static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, + const struct lock_struct *ex, + const struct lock_struct *plock, + BOOL *lock_was_added) { - if (tdb) - return; - tdb = tdb_open_log(lock_path("brlock.tdb"), - lp_open_files_db_hash_size(), - TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); - if (!tdb) { - DEBUG(0,("Failed to open byte range locking database\n")); - return; + BOOL lock_types_differ = (ex->lock_type != plock->lock_type); + + /* We can't merge non-conflicting locks on different context - ignore fnum. */ + + if (!brl_same_context(&ex->context, &plock->context)) { + /* Just copy. */ + memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); + return 1; } -#if DONT_DO_THIS - /* doing this traversal could kill solaris machines under high load (tridge) */ - /* delete any dead locks */ - if (!read_only) { - BOOL check_self = False; - tdb_traverse(tdb, delete_fn, &check_self); + /* We now know we have the same context. */ + + /* Did we overlap ? */ + +/********************************************* + +---------+ + | ex | + +---------+ + +-------+ + | plock | + +-------+ +OR.... + +---------+ + | ex | + +---------+ +**********************************************/ + + if ( (ex->start >= (plock->start + plock->size)) || + (plock->start >= (ex->start + ex->size))) { + /* No overlap with this lock - copy existing. */ + memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); + return 1; } -#endif + +/********************************************* + +---------+ + | ex | + +---------+ + +---------------------------+ + | plock | -> replace with plock. + +---------------------------+ +**********************************************/ + + if ( (ex->start >= plock->start) && + (ex->start + ex->size <= plock->start + plock->size) ) { + memcpy(&lck_arr[0], plock, sizeof(struct lock_struct)); + *lock_was_added = True; + return 1; + } + +/********************************************* + +---------------+ + | ex | + +---------------+ + +---------------+ + | plock | + +---------------+ +BECOMES.... + +---------------+-------+ + | plock | ex | - different lock types. + +---------------+-------+ +OR.... + +-----------------------+ + | ex | - same lock type. + +-----------------------+ +**********************************************/ + + if ( (ex->start >= plock->start) && + (ex->start < plock->start + plock->size) && + (ex->start + ex->size > plock->start + plock->size) ) { + + *lock_was_added = True; + + /* If the lock types are the same, we merge, if different, we + add the new lock before the old. */ + + if (lock_types_differ) { + /* Add new. */ + memcpy(&lck_arr[0], plock, sizeof(struct lock_struct)); + memcpy(&lck_arr[1], ex, sizeof(struct lock_struct)); + /* Adjust existing start and size. */ + lck_arr[1].start = plock->start + plock->size; + lck_arr[1].size = (ex->start + ex->size) - (plock->start + plock->size); + return 2; + } else { + /* Merge. */ + memcpy(&lck_arr[0], plock, sizeof(struct lock_struct)); + /* Set new start and size. */ + lck_arr[0].start = plock->start; + lck_arr[0].size = (ex->start + ex->size) - plock->start; + return 1; + } + } + +/********************************************* + +---------------+ + | ex | + +---------------+ + +---------------+ + | plock | + +---------------+ +BECOMES.... + +-------+---------------+ + | ex | plock | - different lock types + +-------+---------------+ + +OR + +-----------------------+ + | ex | - same lock type. + +-----------------------+ + +**********************************************/ + + if ( (ex->start < plock->start) && + (ex->start + ex->size > plock->start) && + (ex->start + ex->size <= plock->start + plock->size) ) { + + *lock_was_added = True; + + /* If the lock types are the same, we merge, if different, we + add the new lock after the old. */ + + if (lock_types_differ) { + memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); + memcpy(&lck_arr[1], plock, sizeof(struct lock_struct)); + /* Adjust existing size. */ + lck_arr[0].size = plock->start - ex->start; + return 2; + } else { + /* Merge. */ + memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); + /* Adjust existing size. */ + lck_arr[0].size = (plock->start + plock->size) - ex->start; + return 1; + } + } + +/********************************************* + +---------------------------+ + | ex | + +---------------------------+ + +---------+ + | plock | + +---------+ +BECOMES..... + +-------+---------+---------+ + | ex | plock | ex | - different lock types. + +-------+---------+---------+ +OR + +---------------------------+ + | ex | - same lock type. + +---------------------------+ +**********************************************/ + + if ( (ex->start < plock->start) && (ex->start + ex->size > plock->start + plock->size) ) { + *lock_was_added = True; + + if (lock_types_differ) { + + /* We have to split ex into two locks here. */ + + memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); + memcpy(&lck_arr[1], plock, sizeof(struct lock_struct)); + memcpy(&lck_arr[2], ex, sizeof(struct lock_struct)); + + /* Adjust first existing size. */ + lck_arr[0].size = plock->start - ex->start; + + /* Adjust second existing start and size. */ + lck_arr[2].start = plock->start + plock->size; + lck_arr[2].size = (ex->start + ex->size) - (plock->start + plock->size); + return 3; + } else { + /* Just eat plock. */ + memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); + return 1; + } + } + + /* Never get here. */ + smb_panic("brlock_posix_split_merge\n"); + /* Notreached. */ + abort(); } /**************************************************************************** - Close down the brlock.tdb database. + Lock a range of bytes - POSIX lock semantics. + We must cope with range splits and merges. ****************************************************************************/ -void brl_shutdown(int read_only) +static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, + const struct lock_struct *plock, + BOOL *my_lock_ctx) { - if (!tdb) - return; + unsigned int i, count; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *tp; + files_struct *fsp = br_lck->fsp; + BOOL lock_was_added = False; + + /* No zero-zero locks for POSIX. */ + if (plock->start == 0 && plock->size == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* Don't allow 64-bit lock wrap. */ + if (plock->start + plock->size < plock->start || + plock->start + plock->size < plock->size) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* The worst case scenario here is we have to split an + existing POSIX lock range into two, and add our lock, + so we need at most 2 more entries. */ + + tp = SMB_MALLOC_ARRAY(struct lock_struct, (br_lck->num_locks + 2)); + if (!tp) { + return NT_STATUS_NO_MEMORY; + } + + count = 0; + for (i=0; i < br_lck->num_locks; i++) { + if (locks[i].lock_flav == WINDOWS_LOCK) { + /* Do any Windows flavour locks conflict ? */ + if (brl_conflict(&locks[i], plock)) { + /* Did we block ourselves ? */ + if (brl_same_context(&locks[i].context, &plock->context)) { + *my_lock_ctx = True; + } + /* No games with error messages. */ + SAFE_FREE(tp); + return NT_STATUS_FILE_LOCK_CONFLICT; + } + /* Just copy the Windows lock into the new array. */ + memcpy(&tp[count], &locks[i], sizeof(struct lock_struct)); + count++; + } else { + /* POSIX conflict semantics are different. */ + if (brl_conflict_posix(&locks[i], plock)) { + /* Can't block ourselves with POSIX locks. */ + /* No games with error messages. */ + SAFE_FREE(tp); + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + /* Work out overlaps. */ + count += brlock_posix_split_merge(&tp[count], &locks[i], plock, &lock_was_added); + } + } + + /* We can get the POSIX lock, now see if it needs to + be mapped into a lower level POSIX one, and if so can + we get it ? We well the lower lock layer about the + lock type so it can cope with the difference between + Windows "stacking" locks and POSIX "flat" ones. */ + +#if 0 + /* FIXME - this call doesn't work correctly yet for POSIX locks... */ -#if DONT_DO_THIS - /* doing this traversal could kill solaris machines under high load (tridge) */ - /* delete any dead locks */ - if (!read_only) { - BOOL check_self = True; - tdb_traverse(tdb, delete_fn, &check_self); + if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { + + + if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, POSIX_LOCK)) { + if (errno == EACCES || errno == EAGAIN) { + SAFE_FREE(tp); + return NT_STATUS_FILE_LOCK_CONFLICT; + } else { + SAFE_FREE(tp); + return map_nt_error_from_unix(errno); + } + } } #endif - tdb_close(tdb); -} + if (!lock_was_added) { + memcpy(&tp[count], plock, sizeof(struct lock_struct)); + count++; + } -#if ZERO_ZERO -/**************************************************************************** -compare two locks for sorting -****************************************************************************/ -static int lock_compare(struct lock_struct *lck1, - struct lock_struct *lck2) -{ - if (lck1->start != lck2->start) return (lck1->start - lck2->start); - if (lck2->size != lck1->size) { - return ((int)lck1->size - (int)lck2->size); + /* Realloc so we don't leak entries per lock call. */ + tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks)); + if (!tp) { + return NT_STATUS_NO_MEMORY; } - return 0; + br_lck->num_locks = count; + br_lck->lock_data = (void *)tp; + br_lck->modified = True; + return NT_STATUS_OK; } -#endif /**************************************************************************** Lock a range of bytes. ****************************************************************************/ -NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, struct process_id pid, uint16 tid, - br_off start, br_off size, - enum brl_type lock_type, BOOL *my_lock_ctx) +NTSTATUS brl_lock(struct byte_range_lock *br_lck, + uint16 smbpid, + struct process_id pid, + br_off start, + br_off size, + enum brl_type lock_type, + enum brl_flavour lock_flav, + BOOL *my_lock_ctx) { - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct lock, *locks; - NTSTATUS status = NT_STATUS_OK; + NTSTATUS ret; + struct lock_struct lock; *my_lock_ctx = False; - kbuf = locking_key(dev,ino); - - dbuf.dptr = NULL; #if !ZERO_ZERO if (start == 0 && size == 0) { @@ -369,66 +718,27 @@ NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, } #endif - tdb_chainlock(tdb, kbuf); - dbuf = tdb_fetch(tdb, kbuf); - lock.context.smbpid = smbpid; lock.context.pid = pid; - lock.context.tid = tid; + lock.context.tid = br_lck->fsp->conn->cnum; lock.start = start; lock.size = size; - lock.fnum = fnum; + lock.fnum = br_lck->fsp->fnum; lock.lock_type = lock_type; + lock.lock_flav = lock_flav; - 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; ilock_data, (size_t)br_lck->num_locks, sizeof(lock), lock_compare); #endif - if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - - SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return NT_STATUS_OK; - - fail: - - SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return status; + return ret; } /**************************************************************************** @@ -445,260 +755,532 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe } /**************************************************************************** - Unlock a range of bytes. + Unlock a range of bytes - Windows semantics. ****************************************************************************/ -BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, struct process_id pid, uint16 tid, - br_off start, br_off size, - BOOL remove_pending_locks_only, - void (*pre_unlock_fn)(void *), - void *pre_unlock_data) +static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock_struct *plock) { - TDB_DATA kbuf, dbuf; - int count, i, j; - struct lock_struct *locks; - struct lock_context context; + unsigned int i, j; + struct lock_struct *lock = NULL; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; - kbuf = locking_key(dev,ino); +#if ZERO_ZERO + for (i = 0; i < br_lck->num_locks; i++) { + lock = &locks[i]; - dbuf.dptr = NULL; + if (lock->lock_type == WRITE_LOCK && + brl_same_context(&lock->context, &plock->context) && + lock->fnum == plock->fnum && + lock->lock_flav == WINDOWS_LOCK && + lock->start == plock->start && + lock->size == plock->size) { - tdb_chainlock(tdb, kbuf); - dbuf = tdb_fetch(tdb, kbuf); + /* found it - delete it */ + if (i < br_lck->num_locks - 1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((br_lck->num_locks-1) - i)); + } - if (!dbuf.dptr) { - DEBUG(10,("brl_unlock: tdb_fetch failed !\n")); - goto fail; + br_lck->num_locks -= 1; + br_lck->modified = True; + return True; + } } +#endif - context.smbpid = smbpid; - context.pid = pid; - context.tid = tid; + for (i = 0; i < br_lck->num_locks; i++) { + lock = &locks[i]; - /* there are existing locks - find a match */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); + /* Only remove our own locks that match in start, size, and flavour. */ + if (brl_same_context(&lock->context, &plock->context) && + lock->fnum == plock->fnum && + lock->lock_flav == WINDOWS_LOCK && + lock->start == plock->start && + lock->size == plock->size ) { + break; + } + } -#if ZERO_ZERO - for (i=0; inum_locks) { + /* we didn't find it */ + return False; + } - if (lock->lock_type == WRITE_LOCK && - brl_same_context(&lock->context, &context) && - lock->fnum == fnum && - lock->start == start && - lock->size == size) { + /* Unlock any POSIX regions. */ + if(lp_posix_locking(br_lck->fsp->conn->cnum)) { + release_posix_lock(br_lck->fsp, plock->start, plock->size); + } - if (pre_unlock_fn) - (*pre_unlock_fn)(pre_unlock_data); + /* Send unlock messages to any pending waiters that overlap. */ + for (j=0; j < br_lck->num_locks; j++) { + struct lock_struct *pend_lock = &locks[j]; - /* found it - delete it */ - if (count == 1) { - tdb_delete(tdb, kbuf); - } else { - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - dbuf.dsize -= sizeof(*locks); - tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); - } + /* Ignore non-pending locks. */ + if (pend_lock->lock_type != PENDING_LOCK) { + continue; + } - SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return True; + /* We could send specific lock info here... */ + if (brl_pending_overlap(lock, pend_lock)) { + DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", + procid_str_static(&pend_lock->context.pid ))); + + become_root(); + message_send_pid(pend_lock->context.pid, + MSG_SMB_UNLOCK, + NULL, 0, True); + unbecome_root(); } } -#endif - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - for (i=0; inum_locks - 1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((br_lck->num_locks-1) - i)); + } - if (brl_same_context(&lock->context, &context) && - lock->fnum == fnum && - lock->start == start && - lock->size == size) { + br_lck->num_locks -= 1; + br_lck->modified = True; + return True; +} + +/**************************************************************************** + Unlock a range of bytes - POSIX semantics. +****************************************************************************/ - if (remove_pending_locks_only && lock->lock_type != PENDING_LOCK) - continue; +static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_struct *plock) +{ + unsigned int i, j, count; + struct lock_struct *lock = NULL; + struct lock_struct *tp; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + BOOL overlap_found = False; + + /* No zero-zero locks for POSIX. */ + if (plock->start == 0 && plock->size == 0) { + return False; + } - if (lock->lock_type != PENDING_LOCK) { + /* Don't allow 64-bit lock wrap. */ + if (plock->start + plock->size < plock->start || + plock->start + plock->size < plock->size) { + DEBUG(10,("brl_unlock_posix: lock wrap\n")); + return False; + } - /* Do any POSIX unlocks needed. */ - if (pre_unlock_fn) - (*pre_unlock_fn)(pre_unlock_data); + /* The worst case scenario here is we have to split an + existing POSIX lock range into two, so we need at most + 1 more entry. */ - /* Send unlock messages to any pending waiters that overlap. */ - for (j=0; jnum_locks + 1)); + if (!tp) { + DEBUG(10,("brl_unlock_posix: malloc fail\n")); + return False; + } - /* Ignore non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) - continue; + count = 0; + for (i = 0; i < br_lck->num_locks; i++) { + struct lock_struct tmp_lock[3]; + BOOL lock_was_added = False; + unsigned int tmp_count; - /* We could send specific lock info here... */ - if (brl_pending_overlap(lock, pend_lock)) { - DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", - procid_str_static(&pend_lock->context.pid ))); + lock = &locks[i]; - message_send_pid(pend_lock->context.pid, - MSG_SMB_UNLOCK, - NULL, 0, True); - } - } - } + /* Only remove our own locks - ignore fnum. */ + if (lock->lock_type == PENDING_LOCK || + !brl_same_context(&lock->context, &plock->context)) { + memcpy(&tp[count], lock, sizeof(struct lock_struct)); + count++; + continue; + } - /* found it - delete it */ - if (count == 1) { - tdb_delete(tdb, kbuf); + /* Work out overlaps. */ + tmp_count = brlock_posix_split_merge(&tmp_lock[0], &locks[i], plock, &lock_was_added); + + if (tmp_count == 1) { + /* Ether the locks didn't overlap, or the unlock completely + overlapped this lock. If it didn't overlap, then there's + no change in the locks. */ + if (tmp_lock[0].lock_type != UNLOCK_LOCK) { + SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); + /* No change in this lock. */ + memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); + count++; } else { - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - dbuf.dsize -= sizeof(*locks); - tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK); + overlap_found = True; } + continue; + } else if (tmp_count == 2) { + /* The unlock overlapped an existing lock. Copy the truncated + lock into the lock array. */ + if (tmp_lock[0].lock_type != UNLOCK_LOCK) { + SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); + SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); + memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); + } else { + SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK); + SMB_ASSERT(tmp_lock[1].lock_type == locks[i].lock_type); + memcpy(&tp[count], &tmp_lock[1], sizeof(struct lock_struct)); + } + count++; + overlap_found = True; + continue; + } else { + /* tmp_count == 3 - (we split a lock range in two). */ + SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); + SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); + SMB_ASSERT(tmp_lock[2].lock_type != locks[i].lock_type); + + memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); + count++; + memcpy(&tp[count], &tmp_lock[2], sizeof(struct lock_struct)); + count++; + overlap_found = True; + /* Optimisation... */ + /* We know we're finished here as we can't overlap any + more POSIX locks. Copy the rest of the lock array. */ + if (i < br_lck->num_locks - 1) { + memcpy(&tp[count], &locks[i+1], + sizeof(*locks)*((br_lck->num_locks-1) - i)); + count += ((br_lck->num_locks-1) - i); + } + break; + } + } - SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return True; + if (!overlap_found) { + /* Just ignore - no change. */ + SAFE_FREE(tp); + DEBUG(10,("brl_unlock_posix: No overlap - unlocked.\n")); + return True; + } + +#if 0 + /* FIXME - this call doesn't work correctly yet for POSIX locks... */ + + /* Unlock any POSIX regions. */ + if(lp_posix_locking(br_lck->fsp->conn->cnum)) { + release_posix_lock(br_lck->fsp, plock->start, plock->size); + } +#endif + + /* Realloc so we don't leak entries per unlock call. */ + if (count) { + tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks)); + if (!tp) { + DEBUG(10,("brl_unlock_posix: realloc fail\n")); + return False; } + } else { + /* We deleted the last lock. */ + SAFE_FREE(tp); + tp = NULL; } - /* we didn't find it */ + br_lck->num_locks = count; + br_lck->lock_data = (void *)tp; + br_lck->modified = True; - fail: - SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); - return False; -} + /* Send unlock messages to any pending waiters that overlap. */ + locks = tp; + for (j=0; j < br_lck->num_locks; j++) { + struct lock_struct *pend_lock = &locks[j]; + + /* Ignore non-pending locks. */ + if (pend_lock->lock_type != PENDING_LOCK) { + continue; + } + + /* We could send specific lock info here... */ + if (brl_pending_overlap(lock, pend_lock)) { + DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", + procid_str_static(&pend_lock->context.pid ))); + + become_root(); + message_send_pid(pend_lock->context.pid, + MSG_SMB_UNLOCK, + NULL, 0, True); + unbecome_root(); + } + } + + return True; +} /**************************************************************************** - Test if we could add a lock if we wanted to. + Unlock a range of bytes. ****************************************************************************/ -BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, - uint16 smbpid, struct process_id pid, uint16 tid, - br_off start, br_off size, - enum brl_type lock_type) +BOOL brl_unlock(struct byte_range_lock *br_lck, + uint16 smbpid, + struct process_id pid, + br_off start, + br_off size, + enum brl_flavour lock_flav) { - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct lock, *locks; + struct lock_struct lock; - kbuf = locking_key(dev,ino); + lock.context.smbpid = smbpid; + lock.context.pid = pid; + lock.context.tid = br_lck->fsp->conn->cnum; + lock.start = start; + lock.size = size; + lock.fnum = br_lck->fsp->fnum; + lock.lock_type = UNLOCK_LOCK; + lock.lock_flav = lock_flav; + + if (lock_flav == WINDOWS_LOCK) { + return brl_unlock_windows(br_lck, &lock); + } else { + return brl_unlock_posix(br_lck, &lock); + } +} - dbuf.dptr = NULL; +/**************************************************************************** + Test if we could add a lock if we wanted to. + Returns True if the region required is currently unlocked, False if locked. +****************************************************************************/ - dbuf = tdb_fetch(tdb, kbuf); +BOOL brl_locktest(struct byte_range_lock *br_lck, + uint16 smbpid, + struct process_id pid, + br_off start, + br_off size, + enum brl_type lock_type, + enum brl_flavour lock_flav) +{ + BOOL ret = True; + unsigned int i; + struct lock_struct lock; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + files_struct *fsp = br_lck->fsp; lock.context.smbpid = smbpid; lock.context.pid = pid; - lock.context.tid = tid; + lock.context.tid = br_lck->fsp->conn->cnum; lock.start = start; lock.size = size; - lock.fnum = fnum; + lock.fnum = fsp->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; inum_locks; i++) { + /* + * Our own locks don't conflict. + */ + if (brl_conflict_other(&locks[i], &lock)) { + return False; } } + /* + * There is no lock held by an SMB daemon, check to + * see if there is a POSIX lock from a UNIX or NFS process. + * This only conflicts with Windows locks, not POSIX locks. + */ + + if(lp_posix_locking(fsp->conn->cnum) && (lock_flav == WINDOWS_LOCK)) { + ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK); + + DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n", + (double)start, (double)size, ret ? "locked" : "unlocked", + fsp->fnum, fsp->fsp_name )); + + /* We need to return the inverse of is_posix_locked. */ + ret = !ret; + } + /* no conflicts - we could have added it */ - SAFE_FREE(dbuf.dptr); - return True; + return ret; +} - fail: - SAFE_FREE(dbuf.dptr); - return False; +/**************************************************************************** + Query for existing locks. +****************************************************************************/ + +NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, + uint16 *psmbpid, + struct process_id pid, + br_off *pstart, + br_off *psize, + enum brl_type *plock_type, + enum brl_flavour lock_flav) +{ + unsigned int i; + struct lock_struct lock; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + files_struct *fsp = br_lck->fsp; + + lock.context.smbpid = *psmbpid; + lock.context.pid = pid; + lock.context.tid = br_lck->fsp->conn->cnum; + lock.start = *pstart; + lock.size = *psize; + lock.fnum = fsp->fnum; + lock.lock_type = *plock_type; + lock.lock_flav = lock_flav; + + /* Make sure existing locks don't conflict */ + for (i=0; i < br_lck->num_locks; i++) { + struct lock_struct *exlock = &locks[i]; + BOOL conflict = False; + + if (exlock->lock_flav == WINDOWS_LOCK) { + conflict = brl_conflict(exlock, &lock); + } else { + conflict = brl_conflict_posix(exlock, &lock); + } + + if (conflict) { + *psmbpid = exlock->context.smbpid; + *pstart = exlock->start; + *psize = exlock->size; + *plock_type = exlock->lock_type; + return NT_STATUS_LOCK_NOT_GRANTED; + } + } + + /* + * There is no lock held by an SMB daemon, check to + * see if there is a POSIX lock from a UNIX or NFS process. + */ + + if(lp_posix_locking(fsp->conn->cnum)) { + BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK); + + DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", + (double)*pstart, (double)*psize, ret ? "locked" : "unlocked", + fsp->fnum, fsp->fsp_name )); + + if (ret) { + /* Hmmm. No clue what to set smbpid to - use -1. */ + *psmbpid = 0xFFFF; + return NT_STATUS_LOCK_NOT_GRANTED; + } + } + + return NT_STATUS_OK; } + /**************************************************************************** - Remove any locks associated with a open file. + Remove a particular pending lock. ****************************************************************************/ -void brl_close(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, int tid, int fnum) +BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, + uint16 smbpid, + struct process_id pid, + br_off start, + br_off size, + enum brl_flavour lock_flav) { - TDB_DATA kbuf, dbuf; - int count, i, j, dcount=0; - struct lock_struct *locks; + unsigned int i; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_context context; + + context.smbpid = smbpid; + context.pid = pid; + context.tid = br_lck->fsp->conn->cnum; + + for (i = 0; i < br_lck->num_locks; i++) { + struct lock_struct *lock = &locks[i]; + + /* For pending locks we *always* care about the fnum. */ + if (brl_same_context(&lock->context, &context) && + lock->fnum == br_lck->fsp->fnum && + lock->lock_type == PENDING_LOCK && + lock->lock_flav == lock_flav && + lock->start == start && + lock->size == size) { + break; + } + } - kbuf = locking_key(dev,ino); + if (i == br_lck->num_locks) { + /* Didn't find it. */ + return False; + } - dbuf.dptr = NULL; + if (i < br_lck->num_locks - 1) { + /* Found this particular pending lock - delete it */ + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((br_lck->num_locks-1) - i)); + } - tdb_chainlock(tdb, kbuf); - dbuf = tdb_fetch(tdb, kbuf); + br_lck->num_locks -= 1; + br_lck->modified = True; + return True; +} - if (!dbuf.dptr) goto fail; - /* there are existing locks - remove any for this fnum */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); +/**************************************************************************** + Remove any locks associated with a open file. +****************************************************************************/ + +void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) +{ + files_struct *fsp = br_lck->fsp; + uint16 tid = fsp->conn->cnum; + int fnum = fsp->fnum; + unsigned int i, j, dcount=0; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + + /* Remove any existing locks for this fnum (or any fnum if they're POSIX). */ - for (i=0; inum_locks; i++) { struct lock_struct *lock = &locks[i]; + BOOL del_this_lock = False; - if (lock->context.tid == tid && - procid_equal(&lock->context.pid, &pid) && - lock->fnum == fnum) { + if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) { + if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) { + del_this_lock = True; + } else if (lock->lock_flav == POSIX_LOCK) { + del_this_lock = True; + } + } + if (del_this_lock) { /* Send unlock messages to any pending waiters that overlap. */ - for (j=0; jnum_locks; j++) { struct lock_struct *pend_lock = &locks[j]; /* Ignore our own or non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) + if (pend_lock->lock_type != PENDING_LOCK) { continue; + } + /* Optimisation - don't send to this fnum as we're + closing it. */ if (pend_lock->context.tid == tid && procid_equal(&pend_lock->context.pid, &pid) && - pend_lock->fnum == fnum) + pend_lock->fnum == fnum) { continue; + } /* We could send specific lock info here... */ - if (brl_pending_overlap(lock, pend_lock)) + if (brl_pending_overlap(lock, pend_lock)) { + become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); + unbecome_root(); + } } /* found it - delete it */ - if (count > 1 && i < count-1) { + if (br_lck->num_locks > 1 && i < br_lck->num_locks - 1) { memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); + sizeof(*locks)*((br_lck->num_locks-1) - i)); } - count--; + br_lck->num_locks--; + br_lck->modified = True; i--; dcount++; } } - - if (count == 0) { - tdb_delete(tdb, kbuf); - } else if (count < (dbuf.dsize / sizeof(*locks))) { - dbuf.dsize -= dcount * sizeof(*locks); - tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); - } - - /* we didn't find it */ - fail: - SAFE_FREE(dbuf.dptr); - tdb_chainunlock(tdb, kbuf); } /**************************************************************************** @@ -718,9 +1300,11 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st key = (struct lock_key *)kbuf.dptr; for (i=0;idevice, key->inode, + traverse_callback(key->device, + key->inode, locks[i].context.pid, locks[i].lock_type, + locks[i].lock_flav, locks[i].start, locks[i].size); } @@ -733,6 +1317,92 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st int brl_forall(BRLOCK_FN(fn)) { - if (!tdb) return 0; + if (!tdb) { + return 0; + } return tdb_traverse(tdb, traverse_fn, (void *)fn); } + +/******************************************************************* + Store a potentially modified set of byte range lock data back into + the database. + Unlock the record. +********************************************************************/ + +static int byte_range_lock_destructor(void *p) +{ + struct byte_range_lock *br_lck = + talloc_get_type_abort(p, struct byte_range_lock); + TDB_DATA key = locking_key(br_lck->fsp->dev, br_lck->fsp->inode); + + if (!br_lck->modified) { + goto done; + } + + if (br_lck->num_locks == 0) { + /* No locks - delete this entry. */ + if (tdb_delete(tdb, key) == -1) { + smb_panic("Could not delete byte range lock entry\n"); + } + } else { + TDB_DATA data; + data.dptr = br_lck->lock_data; + data.dsize = br_lck->num_locks * sizeof(struct lock_struct); + + if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { + smb_panic("Could not store byte range mode entry\n"); + } + } + + done: + + SAFE_FREE(br_lck->lock_data); + tdb_chainunlock(tdb, key); + return 0; +} + +/******************************************************************* + Fetch a set of byte range lock data from the database. + Leave the record locked. +********************************************************************/ + +struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, + files_struct *fsp) +{ + TDB_DATA key = locking_key(fsp->dev, fsp->inode); + TDB_DATA data; + struct byte_range_lock *br_lck; + + br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); + if (br_lck == NULL) { + return NULL; + } + + br_lck->fsp = fsp; + br_lck->num_locks = 0; + br_lck->modified = False; + + if (tdb_chainlock(tdb, key) != 0) { + DEBUG(3, ("Could not lock byte range lock entry\n")); + TALLOC_FREE(br_lck); + return NULL; + } + + talloc_set_destructor(br_lck, byte_range_lock_destructor); + + data = tdb_fetch(tdb, key); + br_lck->lock_data = (void *)data.dptr; + br_lck->num_locks = data.dsize / sizeof(struct lock_struct); + + if (DEBUGLEVEL >= 10) { + unsigned int i; + struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + DEBUG(10,("brl_get_locks: %u current locks on dev=%.0f, inode=%.0f\n", + br_lck->num_locks, + (double)fsp->dev, (double)fsp->inode )); + for( i = 0; i < br_lck->num_locks; i++) { + print_lock_struct(i, &locks[i]); + } + } + return br_lck; +} -- cgit From 423352b90e5e3bb89db96ae43798db395ef818ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 23:29:47 +0000 Subject: r15026: Fix warning until POSIX locking finished. Jeremy. (This used to be commit 15f39a4c720e9645f941742310b6c6d7d7fc96d5) --- source3/locking/brlock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index b95bb895cc..5d64e66448 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -601,7 +601,6 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, unsigned int i, count; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; struct lock_struct *tp; - files_struct *fsp = br_lck->fsp; BOOL lock_was_added = False; /* No zero-zero locks for POSIX. */ @@ -664,7 +663,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, /* FIXME - this call doesn't work correctly yet for POSIX locks... */ if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { - + files_struct *fsp = br_lck->fsp; if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, POSIX_LOCK)) { if (errno == EACCES || errno == EAGAIN) { -- cgit From fdd55885da4e3270c9bb5c4a682c1cd980a6040a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Apr 2006 23:00:58 +0000 Subject: r15060: The brlock code gets called a lot. Ensure we keep the key around while we're using it - saves many calls to locking_key() (now deleted). Jeremy. (This used to be commit 2f8b527dcf4a36fbb933ce79c720c0425de76b4a) --- source3/locking/brlock.c | 42 +++++++++++++----------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 5d64e66448..60c94c2b98 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -55,13 +55,6 @@ struct lock_struct { enum brl_flavour lock_flav; }; -/* The key used in the brlock database. */ - -struct lock_key { - SMB_DEV_T device; - SMB_INO_T inode; -}; - /* The open brlock.tdb database. */ static TDB_CONTEXT *tdb; @@ -86,23 +79,6 @@ static void print_lock_struct(unsigned int i, struct lock_struct *pls) lock_flav_name(pls->lock_flav) )); } -/**************************************************************************** - Create a locking key - ensuring zero filled for pad purposes. -****************************************************************************/ - -static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) -{ - static struct lock_key key; - TDB_DATA kbuf; - - memset(&key, '\0', sizeof(key)); - key.device = dev; - key.inode = inode; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); - return kbuf; -} - /**************************************************************************** See if two locking contexts are equal. ****************************************************************************/ @@ -1332,7 +1308,10 @@ static int byte_range_lock_destructor(void *p) { struct byte_range_lock *br_lck = talloc_get_type_abort(p, struct byte_range_lock); - TDB_DATA key = locking_key(br_lck->fsp->dev, br_lck->fsp->inode); + TDB_DATA key; + + key.dptr = (char *)&br_lck->key; + key.dsize = sizeof(struct lock_key); if (!br_lck->modified) { goto done; @@ -1355,8 +1334,8 @@ static int byte_range_lock_destructor(void *p) done: - SAFE_FREE(br_lck->lock_data); tdb_chainunlock(tdb, key); + SAFE_FREE(br_lck->lock_data); return 0; } @@ -1368,11 +1347,10 @@ static int byte_range_lock_destructor(void *p) struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, files_struct *fsp) { - TDB_DATA key = locking_key(fsp->dev, fsp->inode); + TDB_DATA key; TDB_DATA data; - struct byte_range_lock *br_lck; + struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); - br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); if (br_lck == NULL) { return NULL; } @@ -1380,6 +1358,12 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, br_lck->fsp = fsp; br_lck->num_locks = 0; br_lck->modified = False; + memset(&br_lck->key, '\0', sizeof(struct lock_key)); + br_lck->key.device = fsp->dev; + br_lck->key.inode = fsp->inode; + + key.dptr = (char *)&br_lck->key; + key.dsize = sizeof(struct lock_key); if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock byte range lock entry\n")); -- cgit From 713eaf1d67d9ef967fb4526113e2a3ba3dd5e229 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Apr 2006 22:22:54 +0000 Subject: r15083: Using talloc with destructors is nice and all, but in this case it's in a performace critical path and it *hurts* us. Go back to plain malloc/free with an explicit destructor call. Jeremy. (This used to be commit 1c99aed563c29e1b3d70939878af747a0660bfec) --- source3/locking/brlock.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 60c94c2b98..e6f0dd1c72 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1304,10 +1304,8 @@ int brl_forall(BRLOCK_FN(fn)) Unlock the record. ********************************************************************/ -static int byte_range_lock_destructor(void *p) +int byte_range_lock_destructor(struct byte_range_lock *br_lck) { - struct byte_range_lock *br_lck = - talloc_get_type_abort(p, struct byte_range_lock); TDB_DATA key; key.dptr = (char *)&br_lck->key; @@ -1336,6 +1334,7 @@ static int byte_range_lock_destructor(void *p) tdb_chainunlock(tdb, key); SAFE_FREE(br_lck->lock_data); + SAFE_FREE(br_lck); return 0; } @@ -1344,12 +1343,11 @@ static int byte_range_lock_destructor(void *p) Leave the record locked. ********************************************************************/ -struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, - files_struct *fsp) +struct byte_range_lock *brl_get_locks(files_struct *fsp) { TDB_DATA key; TDB_DATA data; - struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); + struct byte_range_lock *br_lck = SMB_MALLOC_P(struct byte_range_lock); if (br_lck == NULL) { return NULL; @@ -1367,12 +1365,10 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock byte range lock entry\n")); - TALLOC_FREE(br_lck); + SAFE_FREE(br_lck); return NULL; } - talloc_set_destructor(br_lck, byte_range_lock_destructor); - data = tdb_fetch(tdb, key); br_lck->lock_data = (void *)data.dptr; br_lck->num_locks = data.dsize / sizeof(struct lock_struct); -- cgit From f353704bbf6240d0c402fc4166119a5016eb640c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 25 Apr 2006 21:36:35 +0000 Subject: r15255: Add return statement after abort to placate fussy compilers. Closes #3721. (This used to be commit ab5a55ec8b27146fccba97f320d649bb19bc6f11) --- source3/locking/brlock.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index e6f0dd1c72..0b7aeb1c00 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -563,6 +563,8 @@ OR smb_panic("brlock_posix_split_merge\n"); /* Notreached. */ abort(); + /* Keep some compilers happy. */ + return 0; } /**************************************************************************** -- cgit From f93da6d684312994a10827b36de7a72c7288ed7e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Apr 2006 11:02:46 +0000 Subject: r15269: Fix incorrect boolean in assert to make POSIX lock tests pass with CIFSFS. Jeremy. (This used to be commit 89b604285ebe77b7cc2e0d5593117c0c5dc5ed1c) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 0b7aeb1c00..0233d60df6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -907,7 +907,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s /* tmp_count == 3 - (we split a lock range in two). */ SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); - SMB_ASSERT(tmp_lock[2].lock_type != locks[i].lock_type); + SMB_ASSERT(tmp_lock[2].lock_type == locks[i].lock_type); memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); count++; -- cgit From 6eb1187765b617128c3e698d02127f2690779580 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 May 2006 02:14:09 +0000 Subject: r15402: Fix for bug #3587. Dead entries can be left in the locking db. Make this db self-cleaning on first read of entry after open, and also on smbstatus -b call. Needs more testing when I get back from Boston but passes valgrind at first look. Jeremy. (This used to be commit c66531096325848d1476054df5d53ad05c2ffc83) --- source3/locking/brlock.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 0233d60df6..b9d401cad6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1269,13 +1269,62 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st { struct lock_struct *locks; struct lock_key *key; - int i; + unsigned int i; + unsigned int num_locks = 0; + unsigned int num_valid_entries = 0; BRLOCK_FN(traverse_callback) = (BRLOCK_FN_CAST())state; locks = (struct lock_struct *)dbuf.dptr; key = (struct lock_key *)kbuf.dptr; + num_locks = dbuf.dsize/sizeof(*locks); + + /* Ensure the lock db is clean of invalid processes. */ + + for (i = 0; i < num_locks; i++) { + struct lock_struct *lock_data = &locks[i]; + if (!process_exists(lock_data->context.pid)) { + /* This process no longer exists - mark this + entry as invalid by zeroing it. */ + ZERO_STRUCTP(lock_data); + } else { + num_valid_entries++; + } + } + + if (num_valid_entries != num_locks) { + struct lock_struct *new_lock_data = NULL; + + if (num_valid_entries) { + new_lock_data = SMB_MALLOC_ARRAY(struct lock_struct, num_valid_entries); + if (!new_lock_data) { + DEBUG(3, ("malloc fail\n")); + return 0; + } + num_valid_entries = 0; + for (i = 0; i < num_locks; i++) { + struct lock_struct *lock_data = &locks[i]; + if (lock_data->context.smbpid && + lock_data->context.tid) { + /* Valid (nonzero) entry - copy it. */ + memcpy(&new_lock_data[num_valid_entries], + lock_data, sizeof(struct lock_struct)); + num_valid_entries++; + } + } + } + SAFE_FREE(dbuf.dptr); + dbuf.dptr = (void *)new_lock_data; + dbuf.dsize = (num_valid_entries) * sizeof(*locks); + + if (dbuf.dsize) { + tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE); + } else { + tdb_delete(ttdb, kbuf); + } + } + for (i=0;idevice, key->inode, @@ -1375,6 +1424,58 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) br_lck->lock_data = (void *)data.dptr; br_lck->num_locks = data.dsize / sizeof(struct lock_struct); + if (!fsp->lockdb_clean) { + + /* This is the first time we've accessed this. */ + /* Go through and ensure all entries exist - remove any that don't. */ + /* Makes the lockdb self cleaning at low cost. */ + unsigned int num_valid_entries = 0; + unsigned int i; + + for (i = 0; i < br_lck->num_locks; i++) { + struct lock_struct *lock_data = &((struct lock_struct *)br_lck->lock_data)[i]; + if (!process_exists(lock_data->context.pid)) { + /* This process no longer exists - mark this + entry as invalid by zeroing it. */ + ZERO_STRUCTP(lock_data); + } else { + num_valid_entries++; + } + } + + if (num_valid_entries != br_lck->num_locks) { + struct lock_struct *new_lock_data = NULL; + + if (num_valid_entries) { + new_lock_data = SMB_MALLOC_ARRAY(struct lock_struct, num_valid_entries); + if (!new_lock_data) { + DEBUG(3, ("malloc fail\n")); + tdb_chainunlock(tdb, key); + SAFE_FREE(br_lck->lock_data); + SAFE_FREE(br_lck); + return NULL; + } + num_valid_entries = 0; + for (i = 0; i < br_lck->num_locks; i++) { + struct lock_struct *lock_data = &((struct lock_struct *)br_lck->lock_data)[i]; + if (lock_data->context.smbpid && + lock_data->context.tid) { + /* Valid (nonzero) entry - copy it. */ + memcpy(&new_lock_data[num_valid_entries], + lock_data, sizeof(struct lock_struct)); + num_valid_entries++; + } + } + } + SAFE_FREE(br_lck->lock_data); + br_lck->lock_data = (void *)new_lock_data; + br_lck->num_locks = num_valid_entries; + } + + /* Mark the lockdb as "clean" as seen from this open file. */ + fsp->lockdb_clean = True; + } + if (DEBUGLEVEL >= 10) { unsigned int i; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; -- cgit From fca8766ee18b812e95203810b6a2a5b6c9de5f30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 May 2006 16:07:21 +0000 Subject: r15419: Never write the same function twice :-). In a traversal function we must copy the data before modifying. Jeremy. (This used to be commit ef4c70f58edf15dc93b22f2c80e15113ee2a46df) --- source3/locking/brlock.c | 122 +++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 62 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index b9d401cad6..574552e9e2 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1261,28 +1261,16 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) } /**************************************************************************** - Traverse the whole database with this function, calling traverse_callback - on each lock. + Ensure this set of lock entries is valid. ****************************************************************************/ -static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +static BOOL validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks) { - struct lock_struct *locks; - struct lock_key *key; unsigned int i; - unsigned int num_locks = 0; unsigned int num_valid_entries = 0; + struct lock_struct *locks = *pplocks; - BRLOCK_FN(traverse_callback) = (BRLOCK_FN_CAST())state; - - locks = (struct lock_struct *)dbuf.dptr; - key = (struct lock_key *)kbuf.dptr; - - num_locks = dbuf.dsize/sizeof(*locks); - - /* Ensure the lock db is clean of invalid processes. */ - - for (i = 0; i < num_locks; i++) { + for (i = 0; i < *pnum_entries; i++) { struct lock_struct *lock_data = &locks[i]; if (!process_exists(lock_data->context.pid)) { /* This process no longer exists - mark this @@ -1293,17 +1281,18 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } } - if (num_valid_entries != num_locks) { + if (num_valid_entries != *pnum_entries) { struct lock_struct *new_lock_data = NULL; if (num_valid_entries) { new_lock_data = SMB_MALLOC_ARRAY(struct lock_struct, num_valid_entries); if (!new_lock_data) { DEBUG(3, ("malloc fail\n")); - return 0; + return False; } + num_valid_entries = 0; - for (i = 0; i < num_locks; i++) { + for (i = 0; i < *pnum_entries; i++) { struct lock_struct *lock_data = &locks[i]; if (lock_data->context.smbpid && lock_data->context.tid) { @@ -1314,9 +1303,51 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } } } - SAFE_FREE(dbuf.dptr); - dbuf.dptr = (void *)new_lock_data; - dbuf.dsize = (num_valid_entries) * sizeof(*locks); + + SAFE_FREE(*pplocks); + *pplocks = new_lock_data; + *pnum_entries = num_valid_entries; + } + + return True; +} + +/**************************************************************************** + Traverse the whole database with this function, calling traverse_callback + on each lock. +****************************************************************************/ + +static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct lock_struct *locks; + struct lock_key *key; + unsigned int i; + unsigned int num_locks = 0; + unsigned int orig_num_locks = 0; + + BRLOCK_FN(traverse_callback) = (BRLOCK_FN_CAST())state; + + /* In a traverse function we must make a copy of + dbuf before modifying it. */ + + locks = (struct lock_struct *)memdup(dbuf.dptr, dbuf.dsize); + if (!locks) { + return -1; /* Terminate traversal. */ + } + + key = (struct lock_key *)kbuf.dptr; + orig_num_locks = num_locks = dbuf.dsize/sizeof(*locks); + + /* Ensure the lock db is clean of entries from invalid processes. */ + + if (!validate_lock_entries(&num_locks, &locks)) { + SAFE_FREE(locks); + return -1; /* Terminate traversal */ + } + + if (orig_num_locks != num_locks) { + dbuf.dptr = (void *)locks; + dbuf.dsize = num_locks * sizeof(*locks); if (dbuf.dsize) { tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE); @@ -1325,7 +1356,7 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } } - for (i=0;idevice, key->inode, locks[i].context.pid, @@ -1334,6 +1365,8 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st locks[i].start, locks[i].size); } + + SAFE_FREE(locks); return 0; } @@ -1429,47 +1462,12 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) /* This is the first time we've accessed this. */ /* Go through and ensure all entries exist - remove any that don't. */ /* Makes the lockdb self cleaning at low cost. */ - unsigned int num_valid_entries = 0; - unsigned int i; - - for (i = 0; i < br_lck->num_locks; i++) { - struct lock_struct *lock_data = &((struct lock_struct *)br_lck->lock_data)[i]; - if (!process_exists(lock_data->context.pid)) { - /* This process no longer exists - mark this - entry as invalid by zeroing it. */ - ZERO_STRUCTP(lock_data); - } else { - num_valid_entries++; - } - } - if (num_valid_entries != br_lck->num_locks) { - struct lock_struct *new_lock_data = NULL; - - if (num_valid_entries) { - new_lock_data = SMB_MALLOC_ARRAY(struct lock_struct, num_valid_entries); - if (!new_lock_data) { - DEBUG(3, ("malloc fail\n")); - tdb_chainunlock(tdb, key); - SAFE_FREE(br_lck->lock_data); - SAFE_FREE(br_lck); - return NULL; - } - num_valid_entries = 0; - for (i = 0; i < br_lck->num_locks; i++) { - struct lock_struct *lock_data = &((struct lock_struct *)br_lck->lock_data)[i]; - if (lock_data->context.smbpid && - lock_data->context.tid) { - /* Valid (nonzero) entry - copy it. */ - memcpy(&new_lock_data[num_valid_entries], - lock_data, sizeof(struct lock_struct)); - num_valid_entries++; - } - } - } + if (!validate_lock_entries(&br_lck->num_locks, (struct lock_struct **)&br_lck->lock_data)) { + tdb_chainunlock(tdb, key); SAFE_FREE(br_lck->lock_data); - br_lck->lock_data = (void *)new_lock_data; - br_lck->num_locks = num_valid_entries; + SAFE_FREE(br_lck); + return NULL; } /* Mark the lockdb as "clean" as seen from this open file. */ -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/locking/brlock.c | 304 ++++++++++++++++++++++++++++++----------------- 1 file changed, 198 insertions(+), 106 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 574552e9e2..9c8a7a17ee 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -32,29 +32,6 @@ #define ZERO_ZERO 0 -/* This contains elements that differentiate locks. The smbpid is a - client supplied pid, and is essentially the locking context for - this client */ - -struct lock_context { - uint16 smbpid; - uint16 tid; - struct process_id pid; -}; - -/* 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; - br_off start; - br_off size; - int fnum; - enum brl_type lock_type; - enum brl_flavour lock_flav; -}; - /* The open brlock.tdb database. */ static TDB_CONTEXT *tdb; @@ -83,7 +60,7 @@ static void print_lock_struct(unsigned int i, struct lock_struct *pls) See if two locking contexts are equal. ****************************************************************************/ -static BOOL brl_same_context(const struct lock_context *ctx1, +BOOL brl_same_context(const struct lock_context *ctx1, const struct lock_context *ctx2) { return (procid_equal(&ctx1->pid, &ctx2->pid) && @@ -343,13 +320,19 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, /* We can get the Windows lock, now see if it needs to be mapped into a lower level POSIX one, and if so can - we get it ? We tell the lower lock layer about the - lock type so it can cope with the difference between - Windows "stacking" locks and POSIX "flat" ones. */ + we get it ? */ if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { - if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, WINDOWS_LOCK)) { - if (errno == EACCES || errno == EAGAIN) { + int errno_ret; + if (!set_posix_lock_windows_flavour(fsp, + plock->start, + plock->size, + plock->lock_type, + &plock->context, + locks, + br_lck->num_locks, + &errno_ret)) { + if (errno_ret == EACCES || errno_ret == EAGAIN) { return NT_STATUS_FILE_LOCK_CONFLICT; } else { return map_nt_error_from_unix(errno); @@ -375,9 +358,9 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, Cope with POSIX range splits and merges. ****************************************************************************/ -static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, - const struct lock_struct *ex, - const struct lock_struct *plock, +static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, /* Output array. */ + const struct lock_struct *ex, /* existing lock. */ + const struct lock_struct *plock, /* proposed lock. */ BOOL *lock_was_added) { BOOL lock_types_differ = (ex->lock_type != plock->lock_type); @@ -398,26 +381,26 @@ static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, +---------+ | ex | +---------+ - +-------+ - | plock | - +-------+ + +-------+ + | plock | + +-------+ OR.... +---------+ | ex | +---------+ **********************************************/ - if ( (ex->start >= (plock->start + plock->size)) || - (plock->start >= (ex->start + ex->size))) { + if ( (ex->start > (plock->start + plock->size)) || + (plock->start > (ex->start + ex->size))) { /* No overlap with this lock - copy existing. */ memcpy(&lck_arr[0], ex, sizeof(struct lock_struct)); return 1; } /********************************************* - +---------+ - | ex | - +---------+ + +---------------------------+ + | ex | + +---------------------------+ +---------------------------+ | plock | -> replace with plock. +---------------------------+ @@ -431,24 +414,32 @@ OR.... } /********************************************* - +---------------+ - | ex | - +---------------+ + +-----------------------+ + | ex | + +-----------------------+ +---------------+ | plock | +---------------+ +OR.... + +-------+ + | ex | + +-------+ + +---------------+ + | plock | + +---------------+ + BECOMES.... +---------------+-------+ | plock | ex | - different lock types. +---------------+-------+ -OR.... +OR.... (merge) +-----------------------+ | ex | - same lock type. +-----------------------+ **********************************************/ if ( (ex->start >= plock->start) && - (ex->start < plock->start + plock->size) && + (ex->start <= plock->start + plock->size) && (ex->start + ex->size > plock->start + plock->size) ) { *lock_was_added = True; @@ -475,9 +466,16 @@ OR.... } /********************************************* - +---------------+ - | ex | - +---------------+ + +-----------------------+ + | ex | + +-----------------------+ + +---------------+ + | plock | + +---------------+ +OR.... + +-------+ + | ex | + +-------+ +---------------+ | plock | +---------------+ @@ -486,7 +484,7 @@ BECOMES.... | ex | plock | - different lock types +-------+---------------+ -OR +OR.... (merge) +-----------------------+ | ex | - same lock type. +-----------------------+ @@ -494,7 +492,7 @@ OR **********************************************/ if ( (ex->start < plock->start) && - (ex->start + ex->size > plock->start) && + (ex->start + ex->size >= plock->start) && (ex->start + ex->size <= plock->start + plock->size) ) { *lock_was_added = True; @@ -631,20 +629,28 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, } } + if (!lock_was_added) { + memcpy(&tp[count], plock, sizeof(struct lock_struct)); + count++; + } + /* We can get the POSIX lock, now see if it needs to be mapped into a lower level POSIX one, and if so can - we get it ? We well the lower lock layer about the - lock type so it can cope with the difference between - Windows "stacking" locks and POSIX "flat" ones. */ + we get it ? */ -#if 0 - /* FIXME - this call doesn't work correctly yet for POSIX locks... */ + if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(br_lck->fsp->conn))) { + int errno_ret; - if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { - files_struct *fsp = br_lck->fsp; + /* The lower layer just needs to attempt to + get the system POSIX lock. We've weeded out + any conflicts above. */ - if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, POSIX_LOCK)) { - if (errno == EACCES || errno == EAGAIN) { + if (!set_posix_lock_posix_flavour(br_lck->fsp, + plock->start, + plock->size, + plock->lock_type, + &errno_ret)) { + if (errno_ret == EACCES || errno_ret == EAGAIN) { SAFE_FREE(tp); return NT_STATUS_FILE_LOCK_CONFLICT; } else { @@ -653,12 +659,6 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, } } } -#endif - - if (!lock_was_added) { - memcpy(&tp[count], plock, sizeof(struct lock_struct)); - count++; - } /* Realloc so we don't leak entries per lock call. */ tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks)); @@ -676,7 +676,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, ****************************************************************************/ NTSTATUS brl_lock(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -740,8 +740,12 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock unsigned int i, j; struct lock_struct *lock = NULL; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + enum brl_type deleted_lock_type = READ_LOCK; /* shut the compiler up.... */ #if ZERO_ZERO + /* Delete write locks by preference... The lock list + is sorted in the zero zero case. */ + for (i = 0; i < br_lck->num_locks; i++) { lock = &locks[i]; @@ -753,16 +757,15 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock lock->size == plock->size) { /* found it - delete it */ - if (i < br_lck->num_locks - 1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((br_lck->num_locks-1) - i)); - } - - br_lck->num_locks -= 1; - br_lck->modified = True; - return True; + deleted_lock_type = lock->lock_type; + break; } } + + if (i != br_lck->num_locks) { + /* We found it - don't search again. */ + goto unlock_continue; + } #endif for (i = 0; i < br_lck->num_locks; i++) { @@ -774,6 +777,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock lock->lock_flav == WINDOWS_LOCK && lock->start == plock->start && lock->size == plock->size ) { + deleted_lock_type = lock->lock_type; break; } } @@ -783,9 +787,28 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock return False; } - /* Unlock any POSIX regions. */ +#if ZERO_ZERO + unlock_continue: +#endif + + /* Actually delete the lock. */ + if (i < br_lck->num_locks - 1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((br_lck->num_locks-1) - i)); + } + + br_lck->num_locks -= 1; + br_lck->modified = True; + + /* Unlock the underlying POSIX regions. */ if(lp_posix_locking(br_lck->fsp->conn->cnum)) { - release_posix_lock(br_lck->fsp, plock->start, plock->size); + release_posix_lock_windows_flavour(br_lck->fsp, + plock->start, + plock->size, + deleted_lock_type, + &plock->context, + locks, + br_lck->num_locks); } /* Send unlock messages to any pending waiters that overlap. */ @@ -810,14 +833,6 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock } } - /* Actually delete the lock. */ - if (i < br_lck->num_locks - 1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((br_lck->num_locks-1) - i)); - } - - br_lck->num_locks -= 1; - br_lck->modified = True; return True; } @@ -895,13 +910,18 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type); SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK); memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct)); + if (tmp_lock[0].size != locks[i].size) { + overlap_found = True; + } } else { SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK); SMB_ASSERT(tmp_lock[1].lock_type == locks[i].lock_type); memcpy(&tp[count], &tmp_lock[1], sizeof(struct lock_struct)); + if (tmp_lock[1].start != locks[i].start) { + overlap_found = True; + } } count++; - overlap_found = True; continue; } else { /* tmp_count == 3 - (we split a lock range in two). */ @@ -933,14 +953,15 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s return True; } -#if 0 - /* FIXME - this call doesn't work correctly yet for POSIX locks... */ - /* Unlock any POSIX regions. */ if(lp_posix_locking(br_lck->fsp->conn->cnum)) { - release_posix_lock(br_lck->fsp, plock->start, plock->size); + release_posix_lock_posix_flavour(br_lck->fsp, + plock->start, + plock->size, + &plock->context, + tp, + count); } -#endif /* Realloc so we don't leak entries per unlock call. */ if (count) { @@ -991,7 +1012,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s ****************************************************************************/ BOOL brl_unlock(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -1021,7 +1042,7 @@ BOOL brl_unlock(struct byte_range_lock *br_lck, ****************************************************************************/ BOOL brl_locktest(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -1079,7 +1100,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, ****************************************************************************/ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, - uint16 *psmbpid, + uint32 *psmbpid, struct process_id pid, br_off *pstart, br_off *psize, @@ -1148,7 +1169,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, ****************************************************************************/ BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, - uint16 smbpid, + uint32 smbpid, struct process_id pid, br_off start, br_off size, @@ -1192,18 +1213,75 @@ BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, return True; } - /**************************************************************************** Remove any locks associated with a open file. + We return True if this process owns any other Windows locks on this + fd and so we should not immediately close the fd. ****************************************************************************/ -void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid) +void brl_close_fnum(struct byte_range_lock *br_lck) { files_struct *fsp = br_lck->fsp; uint16 tid = fsp->conn->cnum; int fnum = fsp->fnum; unsigned int i, j, dcount=0; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct process_id pid = procid_self(); + BOOL unlock_individually = False; + + if(lp_posix_locking(fsp->conn->cnum) && !lp_posix_cifsu_locktype()) { + + /* Check if there are any Windows locks associated with this dev/ino + pair that are not this fnum. If so we need to call unlock on each + one in order to release the system POSIX locks correctly. */ + + for (i=0; i < br_lck->num_locks; i++) { + struct lock_struct *lock = &locks[i]; + + if (!procid_equal(&lock->context.pid, &pid)) { + continue; + } + + if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) { + continue; /* Ignore pending. */ + } + + if (lock->context.tid != tid || lock->fnum != fnum) { + unlock_individually = True; + break; + } + } + + if (unlock_individually) { + struct lock_struct *locks_copy; + + /* Copy the current lock array. */ + locks_copy = TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); + if (!locks_copy) { + DEBUG(0,("brl_close_fnum: talloc fail.\n")); + } + + for (i=0; i < br_lck->num_locks; i++) { + struct lock_struct *lock = &locks_copy[i]; + + if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && + (lock->fnum == fnum)) { + brl_unlock(br_lck, + lock->context.smbpid, + pid, + lock->start, + lock->size, + lock->lock_flav); + } + } + return; + } + } + + /* We can bulk delete - any POSIX locks will be removed when the fd closes. */ + + /* Zero any lock reference count on this dev/ino pair. */ + zero_windows_lock_ref_count(fsp); /* Remove any existing locks for this fnum (or any fnum if they're POSIX). */ @@ -1346,7 +1424,7 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } if (orig_num_locks != num_locks) { - dbuf.dptr = (void *)locks; + dbuf.dptr = (char *)locks; dbuf.dsize = num_locks * sizeof(*locks); if (dbuf.dsize) { @@ -1388,8 +1466,10 @@ int brl_forall(BRLOCK_FN(fn)) Unlock the record. ********************************************************************/ -int byte_range_lock_destructor(struct byte_range_lock *br_lck) +static int byte_range_lock_destructor(void *p) { + struct byte_range_lock *br_lck = + talloc_get_type_abort(p, struct byte_range_lock); TDB_DATA key; key.dptr = (char *)&br_lck->key; @@ -1406,7 +1486,7 @@ int byte_range_lock_destructor(struct byte_range_lock *br_lck) } } else { TDB_DATA data; - data.dptr = br_lck->lock_data; + data.dptr = (char *)br_lck->lock_data; data.dsize = br_lck->num_locks * sizeof(struct lock_struct); if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { @@ -1418,20 +1498,21 @@ int byte_range_lock_destructor(struct byte_range_lock *br_lck) tdb_chainunlock(tdb, key); SAFE_FREE(br_lck->lock_data); - SAFE_FREE(br_lck); return 0; } /******************************************************************* Fetch a set of byte range lock data from the database. Leave the record locked. + TALLOC_FREE(brl) will release the lock in the destructor. ********************************************************************/ -struct byte_range_lock *brl_get_locks(files_struct *fsp) +struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, + files_struct *fsp) { TDB_DATA key; TDB_DATA data; - struct byte_range_lock *br_lck = SMB_MALLOC_P(struct byte_range_lock); + struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); if (br_lck == NULL) { return NULL; @@ -1449,10 +1530,12 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock byte range lock entry\n")); - SAFE_FREE(br_lck); + TALLOC_FREE(br_lck); return NULL; } + talloc_set_destructor(br_lck, byte_range_lock_destructor); + data = tdb_fetch(tdb, key); br_lck->lock_data = (void *)data.dptr; br_lck->num_locks = data.dsize / sizeof(struct lock_struct); @@ -1463,13 +1546,22 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp) /* Go through and ensure all entries exist - remove any that don't. */ /* Makes the lockdb self cleaning at low cost. */ - if (!validate_lock_entries(&br_lck->num_locks, (struct lock_struct **)&br_lck->lock_data)) { - tdb_chainunlock(tdb, key); + struct lock_struct *locks = + (struct lock_struct *)br_lck->lock_data; + + if (!validate_lock_entries(&br_lck->num_locks, &locks)) { SAFE_FREE(br_lck->lock_data); - SAFE_FREE(br_lck); + TALLOC_FREE(br_lck); return NULL; } + /* + * validate_lock_entries might have changed locks. We can't + * use a direct pointer here because otherwise gcc warnes + * about strict aliasing rules being violated. + */ + br_lck->lock_data = locks; + /* Mark the lockdb as "clean" as seen from this open file. */ fsp->lockdb_clean = True; } -- cgit From 297df32751fbc64a053700241dae2ac9c0fc4968 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Jul 2006 06:56:43 +0000 Subject: r16973: Fix subtle logic error in lock ref counting found by cifsfs client code. Jeremy. (This used to be commit 53094435d89088124041d57078c21a12e761e2bf) --- source3/locking/brlock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9c8a7a17ee..eb325fe053 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1229,7 +1229,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) struct process_id pid = procid_self(); BOOL unlock_individually = False; - if(lp_posix_locking(fsp->conn->cnum) && !lp_posix_cifsu_locktype()) { + if(lp_posix_locking(fsp->conn->cnum)) { /* Check if there are any Windows locks associated with this dev/ino pair that are not this fnum. If so we need to call unlock on each @@ -1280,9 +1280,6 @@ void brl_close_fnum(struct byte_range_lock *br_lck) /* We can bulk delete - any POSIX locks will be removed when the fd closes. */ - /* Zero any lock reference count on this dev/ino pair. */ - zero_windows_lock_ref_count(fsp); - /* Remove any existing locks for this fnum (or any fnum if they're POSIX). */ for (i=0; i < br_lck->num_locks; i++) { @@ -1336,6 +1333,9 @@ void brl_close_fnum(struct byte_range_lock *br_lck) dcount++; } } + + /* Reduce the lock reference count on this dev/ino pair. */ + reduce_windows_lock_ref_count(fsp, dcount); } /**************************************************************************** -- cgit From 17222261895b8c82eb5458bc66dab6712930d5a3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Jul 2006 16:32:02 +0000 Subject: r16987: Fix the logic errors in ref-counting Windows locks. Hopefully will fix the build farm. Still a few errors in RAW-LOCK to look at though... Jeremy. (This used to be commit edd72d37de570fdad09f7ee983b5b22a1613e558) --- source3/locking/brlock.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index eb325fe053..e99d4ab900 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1225,6 +1225,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) uint16 tid = fsp->conn->cnum; int fnum = fsp->fnum; unsigned int i, j, dcount=0; + int num_deleted_windows_locks = 0; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; struct process_id pid = procid_self(); BOOL unlock_individually = False; @@ -1289,6 +1290,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) { if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) { del_this_lock = True; + num_deleted_windows_locks++; } else if (lock->lock_flav == POSIX_LOCK) { del_this_lock = True; } @@ -1334,8 +1336,10 @@ void brl_close_fnum(struct byte_range_lock *br_lck) } } - /* Reduce the lock reference count on this dev/ino pair. */ - reduce_windows_lock_ref_count(fsp, dcount); + if (num_deleted_windows_locks) { + /* Reduce the Windows lock reference count on this dev/ino pair. */ + reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks); + } } /**************************************************************************** -- cgit From d22d540c326f4964566f1c3dcb72df7986782215 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jul 2006 23:23:39 +0000 Subject: r17041: Trying to track down a *big* memory leak in the new lock code. Fix a small one first.... (easy to valgrind). Jeremy (This used to be commit 43d24fbd41ed745a5b21514b526e655663c509ee) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index e99d4ab900..376c2e30ba 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1259,7 +1259,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) /* Copy the current lock array. */ locks_copy = TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); if (!locks_copy) { - DEBUG(0,("brl_close_fnum: talloc fail.\n")); + smb_panic("brl_close_fnum: talloc fail.\n"); } for (i=0; i < br_lck->num_locks; i++) { -- cgit From ad673ea988cdfe2b596f128e616f7cd57fedf33d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Jul 2006 00:05:47 +0000 Subject: r17043: Fix memleak when processing CIFS POSIX lock/unlock requests. Maybe the Linux kernel OOM killer will be kinder to smbd now :-). Back to tdbtorture tests on cifsfs. Jeremy. (This used to be commit 1201383e7ab2413795a395491af0a4d3877b1c8b) --- source3/locking/brlock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 376c2e30ba..c048ef3005 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -666,6 +666,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, return NT_STATUS_NO_MEMORY; } br_lck->num_locks = count; + SAFE_FREE(br_lck->lock_data); br_lck->lock_data = (void *)tp; br_lck->modified = True; return NT_STATUS_OK; @@ -977,6 +978,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s } br_lck->num_locks = count; + SAFE_FREE(br_lck->lock_data); br_lck->lock_data = (void *)tp; br_lck->modified = True; @@ -1052,7 +1054,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, BOOL ret = True; unsigned int i; struct lock_struct lock; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; files_struct *fsp = br_lck->fsp; lock.context.smbpid = smbpid; @@ -1109,7 +1111,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, { unsigned int i; struct lock_struct lock; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; files_struct *fsp = br_lck->fsp; lock.context.smbpid = *psmbpid; @@ -1123,7 +1125,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, /* Make sure existing locks don't conflict */ for (i=0; i < br_lck->num_locks; i++) { - struct lock_struct *exlock = &locks[i]; + const struct lock_struct *exlock = &locks[i]; BOOL conflict = False; if (exlock->lock_flav == WINDOWS_LOCK) { @@ -1163,7 +1165,6 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, return NT_STATUS_OK; } - /**************************************************************************** Remove a particular pending lock. ****************************************************************************/ -- cgit From 354e444ee3dcd5745d94d299edef4726941efb8f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Jul 2006 00:34:08 +0000 Subject: r17046: Ensure we're using the right pointers ... Jeremy. (This used to be commit a8df1863bf2817a82a55c816ba1f685828c5b6ec) --- source3/locking/brlock.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index c048ef3005..9edac7203b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -723,7 +723,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, Check if an unlock overlaps a pending lock. ****************************************************************************/ -static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pend_lock) +static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) { if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) return True; @@ -739,7 +739,6 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock_struct *plock) { unsigned int i, j; - struct lock_struct *lock = NULL; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; enum brl_type deleted_lock_type = READ_LOCK; /* shut the compiler up.... */ @@ -748,7 +747,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock is sorted in the zero zero case. */ for (i = 0; i < br_lck->num_locks; i++) { - lock = &locks[i]; + struct lock_struct *lock = &locks[i]; if (lock->lock_type == WRITE_LOCK && brl_same_context(&lock->context, &plock->context) && @@ -770,7 +769,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock #endif for (i = 0; i < br_lck->num_locks; i++) { - lock = &locks[i]; + struct lock_struct *lock = &locks[i]; /* Only remove our own locks that match in start, size, and flavour. */ if (brl_same_context(&lock->context, &plock->context) && @@ -822,7 +821,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock } /* We could send specific lock info here... */ - if (brl_pending_overlap(lock, pend_lock)) { + if (brl_pending_overlap(plock, pend_lock)) { DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); @@ -844,7 +843,6 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_struct *plock) { unsigned int i, j, count; - struct lock_struct *lock = NULL; struct lock_struct *tp; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; BOOL overlap_found = False; @@ -873,12 +871,11 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s count = 0; for (i = 0; i < br_lck->num_locks; i++) { + struct lock_struct *lock = &locks[i]; struct lock_struct tmp_lock[3]; BOOL lock_was_added = False; unsigned int tmp_count; - lock = &locks[i]; - /* Only remove our own locks - ignore fnum. */ if (lock->lock_type == PENDING_LOCK || !brl_same_context(&lock->context, &plock->context)) { @@ -979,11 +976,10 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); - br_lck->lock_data = (void *)tp; + locks = br_lck->lock_data = (void *)tp; br_lck->modified = True; /* Send unlock messages to any pending waiters that overlap. */ - locks = tp; for (j=0; j < br_lck->num_locks; j++) { struct lock_struct *pend_lock = &locks[j]; @@ -994,7 +990,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s } /* We could send specific lock info here... */ - if (brl_pending_overlap(lock, pend_lock)) { + if (brl_pending_overlap(plock, pend_lock)) { DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); -- cgit From e1da1fcf12164f50f3462c90f0bb785d18c59b0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Jul 2006 21:09:02 +0000 Subject: r17098: Samba3 now cleanly passes Samba4 RAW-LOCK torture test. Phew - that was painful :-). But what it means is that we now implement lock cancels and I can add lock cancels into POSIX lock handling which will fix the fast/slow system call issue with cifsfs ! Jeremy. (This used to be commit f1a9cf075b87c76c032d19da0168424c90f6cb3c) --- source3/locking/brlock.c | 57 ++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9edac7203b..f251ff57ec 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -211,30 +211,34 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock } /**************************************************************************** - Amazingly enough, w2k3 "remembers" whether the last lock failure + Amazingly enough, w2k3 "remembers" whether the last lock failure on a fnum is the same as this one and changes its error code. I wonder if any app depends on this ? ****************************************************************************/ -static NTSTATUS brl_lock_failed(const struct lock_struct *lock) +static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, int32 lock_timeout) { - static struct lock_struct last_lock_failure; - - if (brl_same_context(&lock->context, &last_lock_failure.context) && - lock->fnum == last_lock_failure.fnum && - lock->start == last_lock_failure.start && - lock->size == last_lock_failure.size) { - return NT_STATUS_FILE_LOCK_CONFLICT; - } - last_lock_failure = *lock; - if (lock->start >= 0xEF000000 && - (lock->start >> 63) == 0) { + 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 */ + if (lock_timeout == 0) { + fsp->last_lock_failure = *lock; + } + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + if (procid_equal(&lock->context.pid, &fsp->last_lock_failure.context.pid) && + lock->context.tid == fsp->last_lock_failure.context.tid && + lock->fnum == fsp->last_lock_failure.fnum && + lock->start == fsp->last_lock_failure.start) { return NT_STATUS_FILE_LOCK_CONFLICT; } + + if (lock_timeout == 0) { + fsp->last_lock_failure = *lock; + } return NT_STATUS_LOCK_NOT_GRANTED; } @@ -293,8 +297,7 @@ static int lock_compare(const struct lock_struct *lck1, ****************************************************************************/ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, - const struct lock_struct *plock, - BOOL *my_lock_ctx) + const struct lock_struct *plock, int32 lock_timeout) { unsigned int i; files_struct *fsp = br_lck->fsp; @@ -303,12 +306,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, for (i=0; i < br_lck->num_locks; i++) { /* Do any Windows or POSIX locks conflict ? */ if (brl_conflict(&locks[i], plock)) { - NTSTATUS status = brl_lock_failed(plock);; - /* Did we block ourselves ? */ - if (brl_same_context(&locks[i].context, &plock->context)) { - *my_lock_ctx = True; - } - return status; + return brl_lock_failed(fsp,plock,lock_timeout); } #if ZERO_ZERO if (plock->start == 0 && plock->size == 0 && @@ -571,8 +569,7 @@ OR ****************************************************************************/ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, - const struct lock_struct *plock, - BOOL *my_lock_ctx) + const struct lock_struct *plock) { unsigned int i, count; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; @@ -604,10 +601,6 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, if (locks[i].lock_flav == WINDOWS_LOCK) { /* Do any Windows flavour locks conflict ? */ if (brl_conflict(&locks[i], plock)) { - /* Did we block ourselves ? */ - if (brl_same_context(&locks[i].context, &plock->context)) { - *my_lock_ctx = True; - } /* No games with error messages. */ SAFE_FREE(tp); return NT_STATUS_FILE_LOCK_CONFLICT; @@ -683,13 +676,11 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, br_off size, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL *my_lock_ctx) + int32 lock_timeout) { NTSTATUS ret; struct lock_struct lock; - *my_lock_ctx = False; - #if !ZERO_ZERO if (start == 0 && size == 0) { DEBUG(0,("client sent 0/0 lock - please report this\n")); @@ -706,9 +697,9 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, lock.lock_flav = lock_flav; if (lock_flav == WINDOWS_LOCK) { - ret = brl_lock_windows(br_lck, &lock, my_lock_ctx); + ret = brl_lock_windows(br_lck, &lock, lock_timeout); } else { - ret = brl_lock_posix(br_lck, &lock, my_lock_ctx); + ret = brl_lock_posix(br_lck, &lock); } #if ZERO_ZERO @@ -1165,7 +1156,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, Remove a particular pending lock. ****************************************************************************/ -BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck, +BOOL brl_lock_cancel(struct byte_range_lock *br_lck, uint32 smbpid, struct process_id pid, br_off start, -- cgit From b737f26764cce935d9482335ece11c71a96720f4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Jul 2006 01:05:51 +0000 Subject: r17105: Fix the race Volker found - we had a non-locked region between detecting a pending lock was needed and when we added the blocking lock record. Make sure that we hold the lock over all this period. Removed the old code for doing blocking locks on SMB requests that never block (the old SMBlock and friends). Discovered something interesting about the strange NT_STATUS_FILE_LOCK_CONFLICT return. If we asked for a lock with zero timeout, and we got an error of NT_STATUS_FILE_LOCK_CONFLICT, treat it as though it was a blocking lock with a timeout of 150 - 300ms. This only happens when timeout is sent as zero and can be seen quite clearly in ethereal. This is the real replacement for old do_lock_spin() code. Re-worked the blocking lock select timeout to correctly use milliseconds instead of the old second level resolution (far too coarse for this work). Jeremy. (This used to be commit b81d6d1ae95a3d3e449dde629884b565eac289d9) --- source3/locking/brlock.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index f251ff57ec..20bb4314b6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -216,14 +216,14 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock app depends on this ? ****************************************************************************/ -static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, int32 lock_timeout) +static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, BOOL blocking_lock) { if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { /* amazing the little things you learn with a test suite. Locks beyond this offset (as a 64 bit number!) always generate the conflict error code, unless the top bit is set */ - if (lock_timeout == 0) { + if (!blocking_lock) { fsp->last_lock_failure = *lock; } return NT_STATUS_FILE_LOCK_CONFLICT; @@ -236,7 +236,7 @@ static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *loc return NT_STATUS_FILE_LOCK_CONFLICT; } - if (lock_timeout == 0) { + if (!blocking_lock) { fsp->last_lock_failure = *lock; } return NT_STATUS_LOCK_NOT_GRANTED; @@ -297,7 +297,7 @@ static int lock_compare(const struct lock_struct *lck1, ****************************************************************************/ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, - const struct lock_struct *plock, int32 lock_timeout) + const struct lock_struct *plock, BOOL blocking_lock) { unsigned int i; files_struct *fsp = br_lck->fsp; @@ -306,7 +306,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, for (i=0; i < br_lck->num_locks; i++) { /* Do any Windows or POSIX locks conflict ? */ if (brl_conflict(&locks[i], plock)) { - return brl_lock_failed(fsp,plock,lock_timeout); + return brl_lock_failed(fsp,plock,blocking_lock); } #if ZERO_ZERO if (plock->start == 0 && plock->size == 0 && @@ -676,7 +676,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, br_off size, enum brl_type lock_type, enum brl_flavour lock_flav, - int32 lock_timeout) + BOOL blocking_lock) { NTSTATUS ret; struct lock_struct lock; @@ -697,7 +697,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, lock.lock_flav = lock_flav; if (lock_flav == WINDOWS_LOCK) { - ret = brl_lock_windows(br_lck, &lock, lock_timeout); + ret = brl_lock_windows(br_lck, &lock, blocking_lock); } else { ret = brl_lock_posix(br_lck, &lock); } -- cgit From 7f5f781fe90c16f5d6b70962d45ed2a8e8c641d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Jul 2006 22:02:54 +0000 Subject: r17181: Fix the build farm RAW-READ bug. When making a copy of the lock array in order to delete them individually it's also important to make a copy of the *size* of this array. Otherwise the unlock decrements the termination index of your for loop :-). Doh ! Big thanks to Volker for showing me how to set up the build farm to track this one down. This is not a 3.0.23a issue. Jeremy. (This used to be commit 2c82a159ae6a4cc83989f2b453508358db516d67) --- source3/locking/brlock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 20bb4314b6..07e4b4c16b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1243,14 +1243,16 @@ void brl_close_fnum(struct byte_range_lock *br_lck) if (unlock_individually) { struct lock_struct *locks_copy; + unsigned int num_locks_copy; /* Copy the current lock array. */ locks_copy = TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); if (!locks_copy) { smb_panic("brl_close_fnum: talloc fail.\n"); } + num_locks_copy = br_lck->num_locks; - for (i=0; i < br_lck->num_locks; i++) { + for (i=0; i < num_locks_copy; i++) { struct lock_struct *lock = &locks_copy[i]; if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && -- cgit From 54cdd1dfe23219c3cc9c772b78fbd40e144957c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Jul 2006 15:23:46 +0000 Subject: r17276: Don't change the POSIX lock ref count if posix locking = no. Jeremy. (This used to be commit 42dec2192c1261090f2fac7a123c384f5c133587) --- source3/locking/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 07e4b4c16b..5ce8a3730b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1326,8 +1326,8 @@ void brl_close_fnum(struct byte_range_lock *br_lck) } } - if (num_deleted_windows_locks) { - /* Reduce the Windows lock reference count on this dev/ino pair. */ + if(lp_posix_locking(fsp->conn->cnum) && num_deleted_windows_locks) { + /* Reduce the Windows lock POSIX reference count on this dev/ino pair. */ reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks); } } -- cgit From d30bcf9c485eb0447cbae56318c4134e490693c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 27 Jul 2006 17:23:57 +0000 Subject: r17279: conn->cnum is the tid we've given to the client. This has nothing to do with our internal share number. Funny that it worked at all :-) Volker (This used to be commit afa6e9094604afe1ef929cd936fbfa07b5473fd2) --- source3/locking/brlock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 5ce8a3730b..031836ecdf 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -792,7 +792,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock br_lck->modified = True; /* Unlock the underlying POSIX regions. */ - if(lp_posix_locking(br_lck->fsp->conn->cnum)) { + if(lp_posix_locking(SNUM(br_lck->fsp->conn))) { release_posix_lock_windows_flavour(br_lck->fsp, plock->start, plock->size, @@ -943,7 +943,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s } /* Unlock any POSIX regions. */ - if(lp_posix_locking(br_lck->fsp->conn->cnum)) { + if(lp_posix_locking(SNUM(br_lck->fsp->conn))) { release_posix_lock_posix_flavour(br_lck->fsp, plock->start, plock->size, @@ -1069,7 +1069,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, * This only conflicts with Windows locks, not POSIX locks. */ - if(lp_posix_locking(fsp->conn->cnum) && (lock_flav == WINDOWS_LOCK)) { + if(lp_posix_locking(SNUM(fsp->conn)) && (lock_flav == WINDOWS_LOCK)) { ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK); DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -1135,7 +1135,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, * see if there is a POSIX lock from a UNIX or NFS process. */ - if(lp_posix_locking(fsp->conn->cnum)) { + if(lp_posix_locking(SNUM(fsp->conn))) { BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK); DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -1218,7 +1218,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) struct process_id pid = procid_self(); BOOL unlock_individually = False; - if(lp_posix_locking(fsp->conn->cnum)) { + if(lp_posix_locking(SNUM(fsp->conn))) { /* Check if there are any Windows locks associated with this dev/ino pair that are not this fnum. If so we need to call unlock on each @@ -1326,7 +1326,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) } } - if(lp_posix_locking(fsp->conn->cnum) && num_deleted_windows_locks) { + if(lp_posix_locking(SNUM(fsp->conn)) && num_deleted_windows_locks) { /* Reduce the Windows lock POSIX reference count on this dev/ino pair. */ reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks); } -- cgit From a093a76dc14303fd1c42fb2c0b87faf3748815e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 22:42:39 +0000 Subject: r17293: After the results from the cluster tests in Germany, fix the messaging code to call the efficient calls : save_re_uid() set_effective_uid(0); messaging_op restore_re_uid(); instead of using heavyweight become_root()/unbecome_root() pairs around all messaging code. Fixup the messaging code to ensure sec_init() is called (only once) so that non-root processes still work when sending messages. This is a lighter weight solution to become_root()/unbecome_root() (which swaps all the supplemental groups) and should be more efficient. I will migrate all server code over to using this (a similar technique should be used in the passdb backend where needed). Jeremy. (This used to be commit 4ace291278d9a44f5c577bdd3b282c1231e543df) --- source3/locking/brlock.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 031836ecdf..4a36d938ad 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -816,11 +816,9 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } @@ -985,11 +983,9 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } @@ -1306,11 +1302,9 @@ void brl_close_fnum(struct byte_range_lock *br_lck) /* We could send specific lock info here... */ if (brl_pending_overlap(lock, pend_lock)) { - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } -- cgit From 2c6030415e0b1f421ea6e85fe6ffe7389ee7a941 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 29 Jul 2006 19:14:24 +0000 Subject: r17314: Optimisation for POSIX locking. If we're downgrading a POSIX lock (applying a read-lock) and we overlap pending read locks then send them an unlock message, we may have allowed them to proceed. Jeremy. (This used to be commit a7a0b6ba50f4cf7c5a0a29809fdff9e1266a29e7) --- source3/locking/brlock.c | 95 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 29 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 4a36d938ad..568c80f3ee 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -98,7 +98,7 @@ static BOOL brl_conflict(const struct lock_struct *lck1, const struct lock_struct *lck2) { /* Ignore PENDING locks. */ - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; /* Read locks never conflict. */ @@ -129,7 +129,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1, #endif /* Ignore PENDING locks. */ - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; /* Read locks never conflict. */ @@ -151,7 +151,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1, static BOOL brl_conflict1(const struct lock_struct *lck1, const struct lock_struct *lck2) { - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { @@ -184,7 +184,7 @@ static BOOL brl_conflict1(const struct lock_struct *lck1, static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2) { - if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK ) + if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) @@ -210,6 +210,19 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock return brl_overlap(lck1, lck2); } +/**************************************************************************** + Check if an unlock overlaps a pending lock. +****************************************************************************/ + +static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) +{ + if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) + return True; + if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size)) + return True; + return False; +} + /**************************************************************************** Amazingly enough, w2k3 "remembers" whether the last lock failure on a fnum is the same as this one and changes its error code. I wonder if any @@ -320,7 +333,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, be mapped into a lower level POSIX one, and if so can we get it ? */ - if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) { + if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(SNUM(fsp->conn))) { int errno_ret; if (!set_posix_lock_windows_flavour(fsp, plock->start, @@ -575,6 +588,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; struct lock_struct *tp; BOOL lock_was_added = False; + BOOL signal_pending_read = False; /* No zero-zero locks for POSIX. */ if (plock->start == 0 && plock->size == 0) { @@ -598,19 +612,28 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, count = 0; for (i=0; i < br_lck->num_locks; i++) { - if (locks[i].lock_flav == WINDOWS_LOCK) { + struct lock_struct *curr_lock = &locks[i]; + + /* If we have a pending read lock, a lock downgrade should + trigger a lock re-evaluation. */ + if (curr_lock->lock_type == PENDING_READ_LOCK && + brl_pending_overlap(plock, curr_lock)) { + signal_pending_read = True; + } + + if (curr_lock->lock_flav == WINDOWS_LOCK) { /* Do any Windows flavour locks conflict ? */ - if (brl_conflict(&locks[i], plock)) { + if (brl_conflict(curr_lock, plock)) { /* No games with error messages. */ SAFE_FREE(tp); return NT_STATUS_FILE_LOCK_CONFLICT; } /* Just copy the Windows lock into the new array. */ - memcpy(&tp[count], &locks[i], sizeof(struct lock_struct)); + memcpy(&tp[count], curr_lock, sizeof(struct lock_struct)); count++; } else { /* POSIX conflict semantics are different. */ - if (brl_conflict_posix(&locks[i], plock)) { + if (brl_conflict_posix(curr_lock, plock)) { /* Can't block ourselves with POSIX locks. */ /* No games with error messages. */ SAFE_FREE(tp); @@ -618,7 +641,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, } /* Work out overlaps. */ - count += brlock_posix_split_merge(&tp[count], &locks[i], plock, &lock_was_added); + count += brlock_posix_split_merge(&tp[count], curr_lock, plock, &lock_was_added); } } @@ -631,7 +654,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, be mapped into a lower level POSIX one, and if so can we get it ? */ - if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(br_lck->fsp->conn))) { + if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(SNUM(br_lck->fsp->conn))) { int errno_ret; /* The lower layer just needs to attempt to @@ -661,7 +684,34 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); br_lck->lock_data = (void *)tp; + locks = tp; br_lck->modified = True; + + /* A successful downgrade from write to read lock can trigger a lock + re-evalutation where waiting readers can now proceed. */ + + if (signal_pending_read) { + /* Send unlock messages to any pending read waiters that overlap. */ + for (i=0; i < br_lck->num_locks; i++) { + struct lock_struct *pend_lock = &locks[i]; + + /* Ignore non-pending locks. */ + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { + continue; + } + + if (pend_lock->lock_type == PENDING_READ_LOCK && + brl_pending_overlap(plock, pend_lock)) { + DEBUG(10,("brl_lock_posix: sending unlock message to pid %s\n", + procid_str_static(&pend_lock->context.pid ))); + + message_send_pid(pend_lock->context.pid, + MSG_SMB_UNLOCK, + NULL, 0, True); + } + } + } + return NT_STATUS_OK; } @@ -710,19 +760,6 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, return ret; } -/**************************************************************************** - Check if an unlock overlaps a pending lock. -****************************************************************************/ - -static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) -{ - if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) - return True; - if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size)) - return True; - return False; -} - /**************************************************************************** Unlock a range of bytes - Windows semantics. ****************************************************************************/ @@ -807,7 +844,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock struct lock_struct *pend_lock = &locks[j]; /* Ignore non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) { + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { continue; } @@ -866,7 +903,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s unsigned int tmp_count; /* Only remove our own locks - ignore fnum. */ - if (lock->lock_type == PENDING_LOCK || + if (IS_PENDING_LOCK(lock->lock_type) || !brl_same_context(&lock->context, &plock->context)) { memcpy(&tp[count], lock, sizeof(struct lock_struct)); count++; @@ -974,7 +1011,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s struct lock_struct *pend_lock = &locks[j]; /* Ignore non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) { + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { continue; } @@ -1173,7 +1210,7 @@ BOOL brl_lock_cancel(struct byte_range_lock *br_lck, /* For pending locks we *always* care about the fnum. */ if (brl_same_context(&lock->context, &context) && lock->fnum == br_lck->fsp->fnum && - lock->lock_type == PENDING_LOCK && + IS_PENDING_LOCK(lock->lock_type) && lock->lock_flav == lock_flav && lock->start == start && lock->size == size) { @@ -1288,7 +1325,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) struct lock_struct *pend_lock = &locks[j]; /* Ignore our own or non-pending locks. */ - if (pend_lock->lock_type != PENDING_LOCK) { + if (!IS_PENDING_LOCK(pend_lock->lock_type)) { continue; } -- cgit From 49001a5b1b07e9a24e5f7efa0dfd880772bdb435 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 31 Jul 2006 20:58:02 +0000 Subject: r17346: Add optimisation vl needs for the cluster code where we don't get the chainlock when getting the byte range lock record read-only. Jeremy. (This used to be commit fcd798ca0c1b76adb2bcda4a99c40c7aacb0addb) --- source3/locking/brlock.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 568c80f3ee..fd41f75e62 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1500,6 +1500,10 @@ static int byte_range_lock_destructor(void *p) key.dptr = (char *)&br_lck->key; key.dsize = sizeof(struct lock_key); + if (br_lck->read_only) { + SMB_ASSERT(!br_lck->modified); + } + if (!br_lck->modified) { goto done; } @@ -1521,7 +1525,9 @@ static int byte_range_lock_destructor(void *p) done: - tdb_chainunlock(tdb, key); + if (!br_lck->read_only) { + tdb_chainunlock(tdb, key); + } SAFE_FREE(br_lck->lock_data); return 0; } @@ -1532,8 +1538,8 @@ static int byte_range_lock_destructor(void *p) TALLOC_FREE(brl) will release the lock in the destructor. ********************************************************************/ -struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, - files_struct *fsp) +static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, + files_struct *fsp, BOOL read_only) { TDB_DATA key; TDB_DATA data; @@ -1553,10 +1559,21 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, key.dptr = (char *)&br_lck->key; key.dsize = sizeof(struct lock_key); - if (tdb_chainlock(tdb, key) != 0) { - DEBUG(3, ("Could not lock byte range lock entry\n")); - TALLOC_FREE(br_lck); - return NULL; + if (!fsp->lockdb_clean) { + /* We must be read/write to clean + the dead entries. */ + read_only = False; + } + + if (read_only) { + br_lck->read_only = True; + } else { + if (tdb_chainlock(tdb, key) != 0) { + DEBUG(3, ("Could not lock byte range lock entry\n")); + TALLOC_FREE(br_lck); + return NULL; + } + br_lck->read_only = False; } talloc_set_destructor(br_lck, byte_range_lock_destructor); @@ -1594,7 +1611,7 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, if (DEBUGLEVEL >= 10) { unsigned int i; struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; - DEBUG(10,("brl_get_locks: %u current locks on dev=%.0f, inode=%.0f\n", + DEBUG(10,("brl_get_locks_internal: %u current locks on dev=%.0f, inode=%.0f\n", br_lck->num_locks, (double)fsp->dev, (double)fsp->inode )); for( i = 0; i < br_lck->num_locks; i++) { @@ -1603,3 +1620,15 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, } return br_lck; } + +struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, + files_struct *fsp) +{ + return brl_get_locks_internal(mem_ctx, fsp, False); +} + +struct byte_range_lock *brl_get_locks_readonly(TALLOC_CTX *mem_ctx, + files_struct *fsp) +{ + return brl_get_locks_internal(mem_ctx, fsp, True); +} -- cgit From 70660495b349cde6245731870d6337eb2800a8ed Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 8 Aug 2006 09:56:38 +0000 Subject: r17452: Some C++ warnings (This used to be commit e4b8c79a9d6f7323953121887af4f482d04a9228) --- source3/locking/brlock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index fd41f75e62..9229d6e6e8 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1002,7 +1002,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); - locks = br_lck->lock_data = (void *)tp; + locks = tp; + br_lck->lock_data = (void *)tp; br_lck->modified = True; /* Send unlock messages to any pending waiters that overlap. */ @@ -1279,7 +1280,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) unsigned int num_locks_copy; /* Copy the current lock array. */ - locks_copy = TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); + locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); if (!locks_copy) { smb_panic("brl_close_fnum: talloc fail.\n"); } -- cgit From 3bc4fd1bb9bfbd0e0efd89d47c50bf798e5a1481 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Aug 2006 19:14:25 +0000 Subject: r17924: Get rid of warnings now that talloc is merged. Destructors now take a pointer to the "real" destroyed object as an argument. Volker (This used to be commit 70edd716ef0ccb218fe18d1233bd30abe46b62bf) --- source3/locking/brlock.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9229d6e6e8..00cbed6b84 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1492,10 +1492,8 @@ int brl_forall(BRLOCK_FN(fn)) Unlock the record. ********************************************************************/ -static int byte_range_lock_destructor(void *p) +static int byte_range_lock_destructor(struct byte_range_lock *br_lck) { - struct byte_range_lock *br_lck = - talloc_get_type_abort(p, struct byte_range_lock); TDB_DATA key; key.dptr = (char *)&br_lck->key; -- cgit From b6b84f98c0420f45c498b025d9edbeb7f830205a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 11 Nov 2006 17:05:11 +0000 Subject: r19668: Convert the locking params to use struct share_param instead of snum (This used to be commit 609dbec600048718b86cd1ecdc2ce49bbdeb803c) --- source3/locking/brlock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 00cbed6b84..872ed2bbea 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -333,7 +333,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, be mapped into a lower level POSIX one, and if so can we get it ? */ - if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(SNUM(fsp->conn))) { + if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(fsp->conn->params)) { int errno_ret; if (!set_posix_lock_windows_flavour(fsp, plock->start, @@ -654,7 +654,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, be mapped into a lower level POSIX one, and if so can we get it ? */ - if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(SNUM(br_lck->fsp->conn))) { + if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(br_lck->fsp->conn->params)) { int errno_ret; /* The lower layer just needs to attempt to @@ -829,7 +829,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock br_lck->modified = True; /* Unlock the underlying POSIX regions. */ - if(lp_posix_locking(SNUM(br_lck->fsp->conn))) { + if(lp_posix_locking(br_lck->fsp->conn->params)) { release_posix_lock_windows_flavour(br_lck->fsp, plock->start, plock->size, @@ -978,7 +978,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s } /* Unlock any POSIX regions. */ - if(lp_posix_locking(SNUM(br_lck->fsp->conn))) { + if(lp_posix_locking(br_lck->fsp->conn->params)) { release_posix_lock_posix_flavour(br_lck->fsp, plock->start, plock->size, @@ -1103,7 +1103,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, * This only conflicts with Windows locks, not POSIX locks. */ - if(lp_posix_locking(SNUM(fsp->conn)) && (lock_flav == WINDOWS_LOCK)) { + if(lp_posix_locking(fsp->conn->params) && (lock_flav == WINDOWS_LOCK)) { ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK); DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -1169,7 +1169,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, * see if there is a POSIX lock from a UNIX or NFS process. */ - if(lp_posix_locking(SNUM(fsp->conn))) { + if(lp_posix_locking(fsp->conn->params)) { BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK); DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -1252,7 +1252,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) struct process_id pid = procid_self(); BOOL unlock_individually = False; - if(lp_posix_locking(SNUM(fsp->conn))) { + if(lp_posix_locking(fsp->conn->params)) { /* Check if there are any Windows locks associated with this dev/ino pair that are not this fnum. If so we need to call unlock on each @@ -1358,7 +1358,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) } } - if(lp_posix_locking(SNUM(fsp->conn)) && num_deleted_windows_locks) { + if(lp_posix_locking(fsp->conn->params) && num_deleted_windows_locks) { /* Reduce the Windows lock POSIX reference count on this dev/ino pair. */ reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks); } -- cgit From 94a1b230f3323e55fa23f20b464964eaac643882 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 Mar 2007 10:40:18 +0000 Subject: r21723: Make use of the per-hashchain "freelists" (This used to be commit f3421ae4cfa263c0e7a8e934b40342ee9885d239) --- source3/locking/brlock.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 872ed2bbea..76a4039d82 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -273,6 +273,9 @@ void brl_init(int read_only) lock_path("brlock.tdb"))); return; } + + /* Activate the per-hashchain freelist */ + tdb_set_max_dead(tdb, 5); } /**************************************************************************** -- cgit From bc2b6436d0f5f3e9ffdfaeb7f1b32996a83d5478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Mar 2007 09:35:51 +0000 Subject: r22009: change TDB_DATA from char * to unsigned char * and fix all compiler warnings in the users metze (This used to be commit 3a28443079c141a6ce8182c65b56ca210e34f37f) --- source3/locking/brlock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 76a4039d82..899e211ffc 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1453,7 +1453,7 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } if (orig_num_locks != num_locks) { - dbuf.dptr = (char *)locks; + dbuf.dptr = (uint8 *)locks; dbuf.dsize = num_locks * sizeof(*locks); if (dbuf.dsize) { @@ -1499,7 +1499,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) { TDB_DATA key; - key.dptr = (char *)&br_lck->key; + key.dptr = (uint8 *)&br_lck->key; key.dsize = sizeof(struct lock_key); if (br_lck->read_only) { @@ -1517,7 +1517,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) } } else { TDB_DATA data; - data.dptr = (char *)br_lck->lock_data; + data.dptr = (uint8 *)br_lck->lock_data; data.dsize = br_lck->num_locks * sizeof(struct lock_struct); if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { @@ -1558,7 +1558,7 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, br_lck->key.device = fsp->dev; br_lck->key.inode = fsp->inode; - key.dptr = (char *)&br_lck->key; + key.dptr = (uint8 *)&br_lck->key; key.dsize = sizeof(struct lock_key); if (!fsp->lockdb_clean) { -- cgit From 79de0ad9463a5cd64978beae37df79fbb4f74632 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2007 01:34:28 +0000 Subject: r22588: Make all uses of TALLOC_MEMDUP consistent. Jeremy. (This used to be commit 8ad13718af0ba1fcb10a6f1631b1ed3cb8d11175) --- source3/locking/brlock.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 899e211ffc..6dd3ac6ea1 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1283,10 +1283,15 @@ void brl_close_fnum(struct byte_range_lock *br_lck) unsigned int num_locks_copy; /* Copy the current lock array. */ - locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); - if (!locks_copy) { - smb_panic("brl_close_fnum: talloc fail.\n"); + if (br_lck->num_locks) { + locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); + if (!locks_copy) { + smb_panic("brl_close_fnum: talloc fail.\n"); + } + } else { + locks_copy = NULL; } + num_locks_copy = br_lck->num_locks; for (i=0; i < num_locks_copy; i++) { -- cgit From 1bcee2679d66f98932d800d6c88b70aeb7691b82 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 5 May 2007 20:43:06 +0000 Subject: r22688: Change lock_data in struct byte_range_lock from void * to struct lock_struct * (This used to be commit 8e0e278961ebf2fa4301874d522636699ace1b9b) --- source3/locking/brlock.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 6dd3ac6ea1..88f993e14b 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -317,7 +317,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, { unsigned int i; files_struct *fsp = br_lck->fsp; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; for (i=0; i < br_lck->num_locks; i++) { /* Do any Windows or POSIX locks conflict ? */ @@ -362,7 +362,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, memcpy(&locks[br_lck->num_locks], plock, sizeof(struct lock_struct)); br_lck->num_locks += 1; - br_lck->lock_data = (void *)locks; + br_lck->lock_data = locks; br_lck->modified = True; return NT_STATUS_OK; @@ -588,7 +588,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, const struct lock_struct *plock) { unsigned int i, count; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; struct lock_struct *tp; BOOL lock_was_added = False; BOOL signal_pending_read = False; @@ -686,7 +686,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, } br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); - br_lck->lock_data = (void *)tp; + br_lck->lock_data = tp; locks = tp; br_lck->modified = True; @@ -770,7 +770,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock_struct *plock) { unsigned int i, j; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; enum brl_type deleted_lock_type = READ_LOCK; /* shut the compiler up.... */ #if ZERO_ZERO @@ -873,7 +873,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s { unsigned int i, j, count; struct lock_struct *tp; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; BOOL overlap_found = False; /* No zero-zero locks for POSIX. */ @@ -1006,7 +1006,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s br_lck->num_locks = count; SAFE_FREE(br_lck->lock_data); locks = tp; - br_lck->lock_data = (void *)tp; + br_lck->lock_data = tp; br_lck->modified = True; /* Send unlock messages to any pending waiters that overlap. */ @@ -1078,7 +1078,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, BOOL ret = True; unsigned int i; struct lock_struct lock; - const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + const struct lock_struct *locks = br_lck->lock_data; files_struct *fsp = br_lck->fsp; lock.context.smbpid = smbpid; @@ -1135,7 +1135,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, { unsigned int i; struct lock_struct lock; - const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + const struct lock_struct *locks = br_lck->lock_data; files_struct *fsp = br_lck->fsp; lock.context.smbpid = *psmbpid; @@ -1201,7 +1201,7 @@ BOOL brl_lock_cancel(struct byte_range_lock *br_lck, enum brl_flavour lock_flav) { unsigned int i; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; struct lock_context context; context.smbpid = smbpid; @@ -1251,7 +1251,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) int fnum = fsp->fnum; unsigned int i, j, dcount=0; int num_deleted_windows_locks = 0; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; struct process_id pid = procid_self(); BOOL unlock_individually = False; @@ -1586,7 +1586,7 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, talloc_set_destructor(br_lck, byte_range_lock_destructor); data = tdb_fetch(tdb, key); - br_lck->lock_data = (void *)data.dptr; + br_lck->lock_data = (struct lock_struct *)data.dptr; br_lck->num_locks = data.dsize / sizeof(struct lock_struct); if (!fsp->lockdb_clean) { @@ -1595,29 +1595,20 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, /* Go through and ensure all entries exist - remove any that don't. */ /* Makes the lockdb self cleaning at low cost. */ - struct lock_struct *locks = - (struct lock_struct *)br_lck->lock_data; - - if (!validate_lock_entries(&br_lck->num_locks, &locks)) { + if (!validate_lock_entries(&br_lck->num_locks, + &br_lck->lock_data)) { SAFE_FREE(br_lck->lock_data); TALLOC_FREE(br_lck); return NULL; } - /* - * validate_lock_entries might have changed locks. We can't - * use a direct pointer here because otherwise gcc warnes - * about strict aliasing rules being violated. - */ - br_lck->lock_data = locks; - /* Mark the lockdb as "clean" as seen from this open file. */ fsp->lockdb_clean = True; } if (DEBUGLEVEL >= 10) { unsigned int i; - struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data; + struct lock_struct *locks = br_lck->lock_data; DEBUG(10,("brl_get_locks_internal: %u current locks on dev=%.0f, inode=%.0f\n", br_lck->num_locks, (double)fsp->dev, (double)fsp->inode )); -- cgit From e6383f47629368d9dd4e803f17566a24e9d7359e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 09:35:35 +0000 Subject: r22736: Start to merge the low-hanging fruit from the now 7000-line cluster patch. This changes "struct process_id" to "struct server_id", keeping both is just too much hassle. No functional change (I hope ;-)) Volker (This used to be commit 0ad4b1226c9d91b72136310d3bbb640d2c5d67b8) --- source3/locking/brlock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 88f993e14b..c3a3ce1cb6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -724,7 +724,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, NTSTATUS brl_lock(struct byte_range_lock *br_lck, uint32 smbpid, - struct process_id pid, + struct server_id pid, br_off start, br_off size, enum brl_type lock_type, @@ -1039,7 +1039,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s BOOL brl_unlock(struct byte_range_lock *br_lck, uint32 smbpid, - struct process_id pid, + struct server_id pid, br_off start, br_off size, enum brl_flavour lock_flav) @@ -1069,7 +1069,7 @@ BOOL brl_unlock(struct byte_range_lock *br_lck, BOOL brl_locktest(struct byte_range_lock *br_lck, uint32 smbpid, - struct process_id pid, + struct server_id pid, br_off start, br_off size, enum brl_type lock_type, @@ -1127,7 +1127,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, uint32 *psmbpid, - struct process_id pid, + struct server_id pid, br_off *pstart, br_off *psize, enum brl_type *plock_type, @@ -1195,7 +1195,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, BOOL brl_lock_cancel(struct byte_range_lock *br_lck, uint32 smbpid, - struct process_id pid, + struct server_id pid, br_off start, br_off size, enum brl_flavour lock_flav) @@ -1252,7 +1252,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck) unsigned int i, j, dcount=0; int num_deleted_windows_locks = 0; struct lock_struct *locks = br_lck->lock_data; - struct process_id pid = procid_self(); + struct server_id pid = procid_self(); BOOL unlock_individually = False; if(lp_posix_locking(fsp->conn->params)) { -- cgit From b92064fcfd804b861e2f5125078812d83b9120a6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 13:01:28 +0000 Subject: r22846: Chunk one to replace message_send_pid with messaging_send: Deep inside locking/locking.c we have to send retry messages to timed lock holders. The majority of this patch passes a "struct messaging_context" down there. No functional change, survives make test. (This used to be commit bbb508414683eeddd2ee0d2d36fe620118180bbb) --- source3/locking/brlock.c | 51 ++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index c3a3ce1cb6..d48c746161 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -584,8 +584,9 @@ OR We must cope with range splits and merges. ****************************************************************************/ -static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, - const struct lock_struct *plock) +static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx, + struct byte_range_lock *br_lck, + const struct lock_struct *plock) { unsigned int i, count; struct lock_struct *locks = br_lck->lock_data; @@ -708,9 +709,8 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, DEBUG(10,("brl_lock_posix: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - message_send_pid(pend_lock->context.pid, - MSG_SMB_UNLOCK, - NULL, 0, True); + messaging_send(msg_ctx, pend_lock->context.pid, + MSG_SMB_UNLOCK, &data_blob_null); } } } @@ -722,7 +722,8 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, Lock a range of bytes. ****************************************************************************/ -NTSTATUS brl_lock(struct byte_range_lock *br_lck, +NTSTATUS brl_lock(struct messaging_context *msg_ctx, + struct byte_range_lock *br_lck, uint32 smbpid, struct server_id pid, br_off start, @@ -752,7 +753,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, if (lock_flav == WINDOWS_LOCK) { ret = brl_lock_windows(br_lck, &lock, blocking_lock); } else { - ret = brl_lock_posix(br_lck, &lock); + ret = brl_lock_posix(msg_ctx, br_lck, &lock); } #if ZERO_ZERO @@ -767,7 +768,9 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck, Unlock a range of bytes - Windows semantics. ****************************************************************************/ -static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock_struct *plock) +static BOOL brl_unlock_windows(struct messaging_context *msg_ctx, + struct byte_range_lock *br_lck, + const struct lock_struct *plock) { unsigned int i, j; struct lock_struct *locks = br_lck->lock_data; @@ -856,9 +859,8 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - message_send_pid(pend_lock->context.pid, - MSG_SMB_UNLOCK, - NULL, 0, True); + messaging_send(msg_ctx, pend_lock->context.pid, + MSG_SMB_UNLOCK, &data_blob_null); } } @@ -869,7 +871,9 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock Unlock a range of bytes - POSIX semantics. ****************************************************************************/ -static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_struct *plock) +static BOOL brl_unlock_posix(struct messaging_context *msg_ctx, + struct byte_range_lock *br_lck, + const struct lock_struct *plock) { unsigned int i, j, count; struct lock_struct *tp; @@ -1024,9 +1028,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - message_send_pid(pend_lock->context.pid, - MSG_SMB_UNLOCK, - NULL, 0, True); + messaging_send(msg_ctx, pend_lock->context.pid, + MSG_SMB_UNLOCK, &data_blob_null); } } @@ -1037,7 +1040,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s Unlock a range of bytes. ****************************************************************************/ -BOOL brl_unlock(struct byte_range_lock *br_lck, +BOOL brl_unlock(struct messaging_context *msg_ctx, + struct byte_range_lock *br_lck, uint32 smbpid, struct server_id pid, br_off start, @@ -1056,9 +1060,9 @@ BOOL brl_unlock(struct byte_range_lock *br_lck, lock.lock_flav = lock_flav; if (lock_flav == WINDOWS_LOCK) { - return brl_unlock_windows(br_lck, &lock); + return brl_unlock_windows(msg_ctx, br_lck, &lock); } else { - return brl_unlock_posix(br_lck, &lock); + return brl_unlock_posix(msg_ctx, br_lck, &lock); } } @@ -1244,7 +1248,8 @@ BOOL brl_lock_cancel(struct byte_range_lock *br_lck, fd and so we should not immediately close the fd. ****************************************************************************/ -void brl_close_fnum(struct byte_range_lock *br_lck) +void brl_close_fnum(struct messaging_context *msg_ctx, + struct byte_range_lock *br_lck) { files_struct *fsp = br_lck->fsp; uint16 tid = fsp->conn->cnum; @@ -1299,7 +1304,8 @@ void brl_close_fnum(struct byte_range_lock *br_lck) if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && (lock->fnum == fnum)) { - brl_unlock(br_lck, + brl_unlock(msg_ctx, + br_lck, lock->context.smbpid, pid, lock->start, @@ -1348,9 +1354,8 @@ void brl_close_fnum(struct byte_range_lock *br_lck) /* We could send specific lock info here... */ if (brl_pending_overlap(lock, pend_lock)) { - message_send_pid(pend_lock->context.pid, - MSG_SMB_UNLOCK, - NULL, 0, True); + messaging_send(msg_ctx, pend_lock->context.pid, + MSG_SMB_UNLOCK, &data_blob_null); } } -- cgit From 01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 May 2007 20:57:12 +0000 Subject: r23014: For all branches, ensure that if we're blocked on a POSIX lock we know nothing about that we retry the lock every 10 seconds instead of waiting for the standard select timeout. This is how we used to (and are supposed to) work. Jeremy. (This used to be commit fa18fc25a50cf13c687ae88e7e5e2dda1120e017) --- source3/locking/brlock.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index d48c746161..f3e4042d8a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -313,7 +313,7 @@ static int lock_compare(const struct lock_struct *lck1, ****************************************************************************/ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, - const struct lock_struct *plock, BOOL blocking_lock) + struct lock_struct *plock, BOOL blocking_lock) { unsigned int i; files_struct *fsp = br_lck->fsp; @@ -322,6 +322,8 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, for (i=0; i < br_lck->num_locks; i++) { /* Do any Windows or POSIX locks conflict ? */ if (brl_conflict(&locks[i], plock)) { + /* Remember who blocked us. */ + plock->context.smbpid = locks[i].context.smbpid; return brl_lock_failed(fsp,plock,blocking_lock); } #if ZERO_ZERO @@ -346,6 +348,10 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, locks, br_lck->num_locks, &errno_ret)) { + + /* We don't know who blocked us. */ + plock->context.smbpid = 0xFFFFFFFF; + if (errno_ret == EACCES || errno_ret == EAGAIN) { return NT_STATUS_FILE_LOCK_CONFLICT; } else { @@ -586,7 +592,7 @@ OR static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx, struct byte_range_lock *br_lck, - const struct lock_struct *plock) + struct lock_struct *plock) { unsigned int i, count; struct lock_struct *locks = br_lck->lock_data; @@ -630,6 +636,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx, if (brl_conflict(curr_lock, plock)) { /* No games with error messages. */ SAFE_FREE(tp); + /* Remember who blocked us. */ + plock->context.smbpid = curr_lock->context.smbpid; return NT_STATUS_FILE_LOCK_CONFLICT; } /* Just copy the Windows lock into the new array. */ @@ -641,6 +649,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx, /* Can't block ourselves with POSIX locks. */ /* No games with error messages. */ SAFE_FREE(tp); + /* Remember who blocked us. */ + plock->context.smbpid = curr_lock->context.smbpid; return NT_STATUS_FILE_LOCK_CONFLICT; } @@ -670,6 +680,10 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx, plock->size, plock->lock_type, &errno_ret)) { + + /* We don't know who blocked us. */ + plock->context.smbpid = 0xFFFFFFFF; + if (errno_ret == EACCES || errno_ret == EAGAIN) { SAFE_FREE(tp); return NT_STATUS_FILE_LOCK_CONFLICT; @@ -730,7 +744,8 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, br_off size, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL blocking_lock) + BOOL blocking_lock, + uint32 *psmbpid) { NTSTATUS ret; struct lock_struct lock; @@ -761,6 +776,10 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, qsort(br_lck->lock_data, (size_t)br_lck->num_locks, sizeof(lock), lock_compare); #endif + /* If we're returning an error, return who blocked us. */ + if (!NT_STATUS_IS_OK(ret) && psmbpid) { + *psmbpid = lock.context.smbpid; + } return ret; } -- cgit From 40a3b796ceac468b887b981422680a8139142a07 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 10:35:14 +0000 Subject: r23165: Convert brlock.tdb to dbwrap (This used to be commit 84f9885cf8cc57dcf3c2738d6b245de314890a41) --- source3/locking/brlock.c | 89 +++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 38 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index f3e4042d8a..d8dcc6f642 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -34,7 +34,7 @@ /* The open brlock.tdb database. */ -static TDB_CONTEXT *tdb; +static struct db_context *brlock_db; /**************************************************************************** Debug info at level 10 for lock struct. @@ -261,21 +261,20 @@ static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *loc void brl_init(int read_only) { - if (tdb) { + if (brlock_db) { return; } - tdb = tdb_open_log(lock_path("brlock.tdb"), - lp_open_files_db_hash_size(), - TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); - if (!tdb) { + brlock_db = db_open(NULL, lock_path("brlock.tdb"), + lp_open_files_db_hash_size(), + TDB_DEFAULT + |TDB_VOLATILE + |(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); + if (!brlock_db) { DEBUG(0,("Failed to open byte range locking database %s\n", lock_path("brlock.tdb"))); return; } - - /* Activate the per-hashchain freelist */ - tdb_set_max_dead(tdb, 5); } /**************************************************************************** @@ -284,10 +283,10 @@ void brl_init(int read_only) void brl_shutdown(int read_only) { - if (!tdb) { + if (!brlock_db) { return; } - tdb_close(tdb); + TALLOC_FREE(brlock_db); } #if ZERO_ZERO @@ -1453,7 +1452,7 @@ static BOOL validate_lock_entries(unsigned int *pnum_entries, struct lock_struct on each lock. ****************************************************************************/ -static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +static int traverse_fn(struct db_record *rec, void *state) { struct lock_struct *locks; struct lock_key *key; @@ -1466,13 +1465,14 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st /* In a traverse function we must make a copy of dbuf before modifying it. */ - locks = (struct lock_struct *)memdup(dbuf.dptr, dbuf.dsize); + locks = (struct lock_struct *)memdup(rec->value.dptr, + rec->value.dsize); if (!locks) { return -1; /* Terminate traversal. */ } - key = (struct lock_key *)kbuf.dptr; - orig_num_locks = num_locks = dbuf.dsize/sizeof(*locks); + key = (struct lock_key *)rec->key.dptr; + orig_num_locks = num_locks = rec->value.dsize/sizeof(*locks); /* Ensure the lock db is clean of entries from invalid processes. */ @@ -1482,13 +1482,10 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st } if (orig_num_locks != num_locks) { - dbuf.dptr = (uint8 *)locks; - dbuf.dsize = num_locks * sizeof(*locks); - - if (dbuf.dsize) { - tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE); + if (rec->value.dsize) { + rec->store(rec, rec->value, TDB_REPLACE); } else { - tdb_delete(ttdb, kbuf); + rec->delete_rec(rec); } } @@ -1512,10 +1509,10 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st int brl_forall(BRLOCK_FN(fn)) { - if (!tdb) { + if (!brlock_db) { return 0; } - return tdb_traverse(tdb, traverse_fn, (void *)fn); + return brlock_db->traverse(brlock_db, traverse_fn, (void *)fn); } /******************************************************************* @@ -1541,25 +1538,31 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) if (br_lck->num_locks == 0) { /* No locks - delete this entry. */ - if (tdb_delete(tdb, key) == -1) { + NTSTATUS status = br_lck->record->delete_rec(br_lck->record); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("delete_rec returned %s\n", + nt_errstr(status))); smb_panic("Could not delete byte range lock entry\n"); } } else { TDB_DATA data; + NTSTATUS status; + data.dptr = (uint8 *)br_lck->lock_data; data.dsize = br_lck->num_locks * sizeof(struct lock_struct); - if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { + status = br_lck->record->store(br_lck->record, data, + TDB_REPLACE); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("store returned %s\n", nt_errstr(status))); smb_panic("Could not store byte range mode entry\n"); } } done: - if (!br_lck->read_only) { - tdb_chainunlock(tdb, key); - } SAFE_FREE(br_lck->lock_data); + TALLOC_FREE(br_lck->record); return 0; } @@ -1572,8 +1575,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, files_struct *fsp, BOOL read_only) { - TDB_DATA key; - TDB_DATA data; + TDB_DATA key, data; struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); if (br_lck == NULL) { @@ -1597,22 +1599,33 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, } if (read_only) { - br_lck->read_only = True; - } else { - if (tdb_chainlock(tdb, key) != 0) { + if (brlock_db->fetch(brlock_db, br_lck, key, &data) == -1) { + DEBUG(3, ("Could not fetch byte range lock record\n")); + TALLOC_FREE(br_lck); + return NULL; + } + br_lck->record = NULL; + } + else { + br_lck->record = brlock_db->fetch_locked(brlock_db, br_lck, key); + + if (br_lck->record == NULL) { DEBUG(3, ("Could not lock byte range lock entry\n")); TALLOC_FREE(br_lck); return NULL; } - br_lck->read_only = False; + + data = br_lck->record->value; } + br_lck->read_only = read_only; + talloc_set_destructor(br_lck, byte_range_lock_destructor); - data = tdb_fetch(tdb, key); - br_lck->lock_data = (struct lock_struct *)data.dptr; br_lck->num_locks = data.dsize / sizeof(struct lock_struct); - + br_lck->lock_data = SMB_MALLOC_ARRAY(struct lock_struct, br_lck->num_locks); + memcpy(br_lck->lock_data, data.dptr, data.dsize); + if (!fsp->lockdb_clean) { /* This is the first time we've accessed this. */ -- cgit From 8c57860cc79f37296785b4f7ae67fd5a8a543e39 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 17:12:08 +0000 Subject: r23169: Merge 535 of Tridge's bzr tree: store the right data after cleaning lock records. This fixes RAW-BENCH-LOCK after a recovery on a cluster (This used to be commit 3da3086dbf594fbdc4cfabf78f8d3ea1df4dc8ce) --- source3/locking/brlock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index d8dcc6f642..8e2f7ce41a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1482,8 +1482,11 @@ static int traverse_fn(struct db_record *rec, void *state) } if (orig_num_locks != num_locks) { - if (rec->value.dsize) { - rec->store(rec, rec->value, TDB_REPLACE); + if (num_locks) { + TDB_DATA data; + data.dptr = (uint8_t *)locks; + data.dsize = num_locks*sizeof(struct lock_struct); + rec->store(rec, data, TDB_REPLACE); } else { rec->delete_rec(rec); } -- cgit From e8156439f24137b5418baad20a7f00f6949cfe29 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 09:30:34 +0000 Subject: r23183: Check in a change made by Tridge: This replaces the internal explicit dev/ino file id representation by a "struct file_id". This is necessary as cluster file systems and NFS don't necessarily assign the same device number to the shared file system. With this structure in place we can now easily add different schemes to map a file to a unique 64-bit device node. Jeremy, you might note that I did not change the external interface of smb_share_modes.c. Volker (This used to be commit 9b10dbbd5de8813fc15ebbb6be9b18010ffe8139) --- source3/locking/brlock.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 8e2f7ce41a..a37afbddd5 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1455,7 +1455,7 @@ static BOOL validate_lock_entries(unsigned int *pnum_entries, struct lock_struct static int traverse_fn(struct db_record *rec, void *state) { struct lock_struct *locks; - struct lock_key *key; + struct file_id *key; unsigned int i; unsigned int num_locks = 0; unsigned int orig_num_locks = 0; @@ -1471,7 +1471,7 @@ static int traverse_fn(struct db_record *rec, void *state) return -1; /* Terminate traversal. */ } - key = (struct lock_key *)rec->key.dptr; + key = (struct file_id *)rec->key.dptr; orig_num_locks = num_locks = rec->value.dsize/sizeof(*locks); /* Ensure the lock db is clean of entries from invalid processes. */ @@ -1493,8 +1493,7 @@ static int traverse_fn(struct db_record *rec, void *state) } for ( i=0; idevice, - key->inode, + traverse_callback(*key, locks[i].context.pid, locks[i].lock_type, locks[i].lock_flav, @@ -1529,7 +1528,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) TDB_DATA key; key.dptr = (uint8 *)&br_lck->key; - key.dsize = sizeof(struct lock_key); + key.dsize = sizeof(struct file_id); if (br_lck->read_only) { SMB_ASSERT(!br_lck->modified); @@ -1588,12 +1587,11 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, br_lck->fsp = fsp; br_lck->num_locks = 0; br_lck->modified = False; - memset(&br_lck->key, '\0', sizeof(struct lock_key)); - br_lck->key.device = fsp->dev; - br_lck->key.inode = fsp->inode; + memset(&br_lck->key, '\0', sizeof(struct file_id)); + br_lck->key = fsp->file_id; key.dptr = (uint8 *)&br_lck->key; - key.dsize = sizeof(struct lock_key); + key.dsize = sizeof(struct file_id); if (!fsp->lockdb_clean) { /* We must be read/write to clean @@ -1649,9 +1647,9 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, if (DEBUGLEVEL >= 10) { unsigned int i; struct lock_struct *locks = br_lck->lock_data; - DEBUG(10,("brl_get_locks_internal: %u current locks on dev=%.0f, inode=%.0f\n", + DEBUG(10,("brl_get_locks_internal: %u current locks on file_id %s\n", br_lck->num_locks, - (double)fsp->dev, (double)fsp->inode )); + file_id_static_string(&fsp->file_id))); for( i = 0; i < br_lck->num_locks; i++) { print_lock_struct(i, &locks[i]); } -- cgit From d3ed91d9e1f3ba9f3d5093b3607dd563b37c27ed Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 13:26:44 +0000 Subject: r23195: Add void *private_data to brl_forall (This used to be commit c91b2bdc160d76bf0b0770fe7f92cbc7124d6c3c) --- source3/locking/brlock.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index a37afbddd5..b51076bf43 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1447,6 +1447,15 @@ static BOOL validate_lock_entries(unsigned int *pnum_entries, struct lock_struct return True; } +struct brl_forall_cb { + void (*fn)(struct file_id id, struct server_id pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + br_off start, br_off size, + void *private_data); + void *private_data; +}; + /**************************************************************************** Traverse the whole database with this function, calling traverse_callback on each lock. @@ -1454,14 +1463,13 @@ static BOOL validate_lock_entries(unsigned int *pnum_entries, struct lock_struct static int traverse_fn(struct db_record *rec, void *state) { + struct brl_forall_cb *cb = (struct brl_forall_cb *)state; struct lock_struct *locks; struct file_id *key; unsigned int i; unsigned int num_locks = 0; unsigned int orig_num_locks = 0; - BRLOCK_FN(traverse_callback) = (BRLOCK_FN_CAST())state; - /* In a traverse function we must make a copy of dbuf before modifying it. */ @@ -1493,12 +1501,13 @@ static int traverse_fn(struct db_record *rec, void *state) } for ( i=0; ifn(*key, + locks[i].context.pid, + locks[i].lock_type, + locks[i].lock_flav, + locks[i].start, + locks[i].size, + cb->private_data); } SAFE_FREE(locks); @@ -1509,12 +1518,21 @@ static int traverse_fn(struct db_record *rec, void *state) Call the specified function on each lock in the database. ********************************************************************/ -int brl_forall(BRLOCK_FN(fn)) +int brl_forall(void (*fn)(struct file_id id, struct server_id pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + br_off start, br_off size, + void *private_data), + void *private_data) { + struct brl_forall_cb cb; + if (!brlock_db) { return 0; } - return brlock_db->traverse(brlock_db, traverse_fn, (void *)fn); + cb.fn = fn; + cb.private_data = private_data; + return brlock_db->traverse(brlock_db, traverse_fn, &cb); } /******************************************************************* -- cgit From 3f5742e20b30010ef88e19b6ee41c6b071258aee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 14:49:19 +0000 Subject: r23204: Add MSG_SMB_BRL_VALIDATE. Tridge, this is a bit different from your bzr branch, please check if it fulfils your needs. Two changes: The validation is not done inside the brlock.c traverse_fn, it's done as a separate routine. Secondly, this patch does not call the checker routines in smbcontrol directly but depends on a running smbd. (This used to be commit 7e39d77c1f90d9025cab08918385d140e20ca25b) --- source3/locking/brlock.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index b51076bf43..a50d4faa52 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1686,3 +1686,109 @@ struct byte_range_lock *brl_get_locks_readonly(TALLOC_CTX *mem_ctx, { return brl_get_locks_internal(mem_ctx, fsp, True); } + +struct brl_revalidate_state { + ssize_t array_size; + uint32 num_pids; + struct server_id *pids; +}; + +/* + * Collect PIDs of all processes with pending entries + */ + +static void brl_revalidate_collect(struct file_id id, struct server_id pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + br_off start, br_off size, + void *private_data) +{ + struct brl_revalidate_state *state = + (struct brl_revalidate_state *)private_data; + + if (!IS_PENDING_LOCK(lock_type)) { + return; + } + + add_to_large_array(state, sizeof(pid), (void *)&pid, + &state->pids, &state->num_pids, + &state->array_size); +} + +/* + * qsort callback to sort the processes + */ + +static int compare_procids(const void *p1, const void *p2) +{ + const struct server_id *i1 = (struct server_id *)i1; + const struct server_id *i2 = (struct server_id *)i2; + + if (i1->pid < i2->pid) return -1; + if (i2->pid > i2->pid) return 1; + return 0; +} + +/* + * Send a MSG_SMB_UNLOCK message to all processes with pending byte range + * locks so that they retry. Mainly used in the cluster code after a node has + * died. + * + * Done in two steps to avoid double-sends: First we collect all entries in an + * array, then qsort that array and only send to non-dupes. + */ + +static void brl_revalidate(struct messaging_context *msg_ctx, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct brl_revalidate_state *state; + uint32 i; + struct server_id last_pid; + + if (!(state = TALLOC_ZERO_P(NULL, struct brl_revalidate_state))) { + DEBUG(0, ("talloc failed\n")); + return; + } + + brl_forall(brl_revalidate_collect, state); + + if (state->array_size == -1) { + DEBUG(0, ("talloc failed\n")); + goto done; + } + + if (state->num_pids == 0) { + goto done; + } + + qsort(state->pids, state->num_pids, sizeof(state->pids[0]), + compare_procids); + + ZERO_STRUCT(last_pid); + + for (i=0; inum_pids; i++) { + if (procid_equal(&last_pid, &state->pids[i])) { + /* + * We've seen that one already + */ + continue; + } + + messaging_send(msg_ctx, state->pids[i], MSG_SMB_UNLOCK, + &data_blob_null); + last_pid = state->pids[i]; + } + + done: + TALLOC_FREE(state); + return; +} + +void brl_register_msgs(struct messaging_context *msg_ctx) +{ + messaging_register(msg_ctx, NULL, MSG_SMB_BRL_VALIDATE, + brl_revalidate); +} -- cgit From 86f0e0b3de0f5a32f44bef614f6859209d81f1a1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Jun 2007 19:56:41 +0000 Subject: r23316: Ouch... This would not have run in production without cluster code anyway. (This used to be commit ca1d0ff03d038372d5886ff1aa409494721142f4) --- source3/locking/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index a50d4faa52..6713530738 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1721,8 +1721,8 @@ static void brl_revalidate_collect(struct file_id id, struct server_id pid, static int compare_procids(const void *p1, const void *p2) { - const struct server_id *i1 = (struct server_id *)i1; - const struct server_id *i2 = (struct server_id *)i2; + const struct server_id *i1 = (struct server_id *)p1; + const struct server_id *i2 = (struct server_id *)p2; if (i1->pid < i2->pid) return -1; if (i2->pid > i2->pid) return 1; -- cgit From b1ce226af8b61ad7e3c37860a59c6715012e738b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 15 Jun 2007 21:58:49 +0000 Subject: r23510: Tidy calls to smb_panic by removing trailing newlines. Print the failed expression in SMB_ASSERT. (This used to be commit 171dc060e2a576d724eed1ca65636bdafffd7713) --- source3/locking/brlock.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 6713530738..e0cc4eec1e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -577,9 +577,9 @@ OR } /* Never get here. */ - smb_panic("brlock_posix_split_merge\n"); + smb_panic("brlock_posix_split_merge"); /* Notreached. */ - abort(); + /* Keep some compilers happy. */ return 0; } @@ -1309,7 +1309,7 @@ void brl_close_fnum(struct messaging_context *msg_ctx, if (br_lck->num_locks) { locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); if (!locks_copy) { - smb_panic("brl_close_fnum: talloc fail.\n"); + smb_panic("brl_close_fnum: talloc failed"); } } else { locks_copy = NULL; @@ -1562,7 +1562,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("delete_rec returned %s\n", nt_errstr(status))); - smb_panic("Could not delete byte range lock entry\n"); + smb_panic("Could not delete byte range lock entry"); } } else { TDB_DATA data; @@ -1575,7 +1575,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("store returned %s\n", nt_errstr(status))); - smb_panic("Could not store byte range mode entry\n"); + smb_panic("Could not store byte range mode entry"); } } -- cgit From 9dee722b09b86622513f5d1b7ecab4dbf0787645 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 16 Jun 2007 01:04:22 +0000 Subject: r23516: Fix bug found & fixed by Doug Rudoff (doug_rudoff@isilon.com) - when cleaning up invalid locks make sure we mark the lck struct as modified so it'll get saved back correctly (that was the original intent). Jeremy. (This used to be commit cbf0829abcc3689edd7ab225054dfc79d43c6309) --- source3/locking/brlock.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index e0cc4eec1e..202fab36cc 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1646,6 +1646,7 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, memcpy(br_lck->lock_data, data.dptr, data.dsize); if (!fsp->lockdb_clean) { + int orig_num_locks = br_lck->num_locks; /* This is the first time we've accessed this. */ /* Go through and ensure all entries exist - remove any that don't. */ @@ -1658,6 +1659,11 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, return NULL; } + /* Ensure invalid locks are cleaned up in the destructor. */ + if (orig_num_locks != br_lck->num_locks) { + br_lck->modified = True; + } + /* Mark the lockdb as "clean" as seen from this open file. */ fsp->lockdb_clean = True; } -- cgit From 4ff7e6dbc92d77ccaa1805d03486e19b72ec7d26 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 9 Jul 2007 07:51:39 +0000 Subject: r23755: Fix Coverity id 384 (This used to be commit ebb410ca1e08d6f062154c9f8b3970682c6eeebd) --- source3/locking/brlock.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 202fab36cc..9b8dcfd15e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1642,7 +1642,13 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, talloc_set_destructor(br_lck, byte_range_lock_destructor); br_lck->num_locks = data.dsize / sizeof(struct lock_struct); - br_lck->lock_data = SMB_MALLOC_ARRAY(struct lock_struct, br_lck->num_locks); + if (!(br_lck->lock_data = SMB_MALLOC_ARRAY( + struct lock_struct, br_lck->num_locks))) { + DEBUG(0, ("malloc failed\n")); + TALLOC_FREE(br_lck); + return NULL; + } + memcpy(br_lck->lock_data, data.dptr, data.dsize); if (!fsp->lockdb_clean) { -- cgit From 014a596f426721fcf15014a735051d951b186208 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 9 Jul 2007 08:45:14 +0000 Subject: r23759: Fix make test -- sorry (This used to be commit cbbc70604e815f4ffd25d040ca0a4ef58e651523) --- source3/locking/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9b8dcfd15e..9b90d87ff0 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1642,8 +1642,8 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, talloc_set_destructor(br_lck, byte_range_lock_destructor); br_lck->num_locks = data.dsize / sizeof(struct lock_struct); - if (!(br_lck->lock_data = SMB_MALLOC_ARRAY( - struct lock_struct, br_lck->num_locks))) { + br_lck->lock_data = SMB_MALLOC_ARRAY(struct lock_struct, br_lck->num_locks); + if ((br_lck->num_locks != 0) && (br_lck->lock_data == NULL)) { DEBUG(0, ("malloc failed\n")); TALLOC_FREE(br_lck); return NULL; -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9b90d87ff0..2a6299a563 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/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, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/locking/brlock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 2a6299a563..228a30b7af 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -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 c9da49790e67b6840c4cfa6daddfffbbe643d140 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 16 Jul 2007 07:40:30 +0000 Subject: r23882: Fix Coverity id 389 -- finally (I hope) (This used to be commit 9b8f2d8bd144700306819480bcb260d2c20969ae) --- source3/locking/brlock.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 228a30b7af..252728ced3 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1641,14 +1641,18 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, talloc_set_destructor(br_lck, byte_range_lock_destructor); br_lck->num_locks = data.dsize / sizeof(struct lock_struct); - br_lck->lock_data = SMB_MALLOC_ARRAY(struct lock_struct, br_lck->num_locks); - if ((br_lck->num_locks != 0) && (br_lck->lock_data == NULL)) { - DEBUG(0, ("malloc failed\n")); - TALLOC_FREE(br_lck); - return NULL; - } - memcpy(br_lck->lock_data, data.dptr, data.dsize); + if (br_lck->num_locks != 0) { + br_lck->lock_data = SMB_MALLOC_ARRAY(struct lock_struct, + br_lck->num_locks); + if (br_lck->lock_data == NULL) { + DEBUG(0, ("malloc failed\n")); + TALLOC_FREE(br_lck); + return NULL; + } + + memcpy(br_lck->lock_data, data.dptr, data.dsize); + } if (!fsp->lockdb_clean) { int orig_num_locks = br_lck->num_locks; -- cgit From 476c30b9ce38eec8985447fdcd1d3ece97370704 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 16 Jul 2007 08:23:20 +0000 Subject: r23885: Fix make test on opi. (This used to be commit b2adb28808fe25d420bc12834ca8bc70779bb653) --- source3/locking/brlock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 252728ced3..41a7b9ea4a 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1637,6 +1637,7 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, } br_lck->read_only = read_only; + br_lck->lock_data = NULL; talloc_set_destructor(br_lck, byte_range_lock_destructor); -- cgit From 63fcb7a2fd0064121ec71c913d32102b7de6dc6f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Jul 2007 11:50:54 +0000 Subject: r24034: Print the full cluster pid in print_lock_struct (This used to be commit ff1996ce4b0edfee90758c85ea0ac653877a1b9f) --- source3/locking/brlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 41a7b9ea4a..e79b531776 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -41,11 +41,11 @@ static struct db_context *brlock_db; static void print_lock_struct(unsigned int i, struct lock_struct *pls) { - DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %u, ", + DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %s, ", i, (unsigned int)pls->context.smbpid, (unsigned int)pls->context.tid, - (unsigned int)procid_to_pid(&pls->context.pid) )); + procid_str_static(&pls->context.pid) )); DEBUG(10,("start = %.0f, size = %.0f, fnum = %d, %s %s\n", (double)pls->start, -- cgit From 28210588edc39eb2b6cd237f11b488fa4d6b6985 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Aug 2007 11:28:04 +0000 Subject: r24266: Remove the "open files database hash size" parameter This has been superseded by the "tdb_hashsize:" parameter (This used to be commit df40d336afd256f05a0ec3724cc2096fb7114d81) --- source3/locking/brlock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index e79b531776..4e15670b04 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -263,8 +263,7 @@ void brl_init(int read_only) if (brlock_db) { return; } - brlock_db = db_open(NULL, lock_path("brlock.tdb"), - lp_open_files_db_hash_size(), + brlock_db = db_open(NULL, lock_path("brlock.tdb"), 0, TDB_DEFAULT |TDB_VOLATILE |(read_only?0x0:TDB_CLEAR_IF_FIRST), -- cgit From 4ee8b2937d48308c6089fb539fdbd8625dfde360 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Sep 2007 10:56:07 +0000 Subject: r25055: Add file_id_string_tos This removes file_id_string_static and file_id_string_static2 (This used to be commit 638c848c9afe374feb30e34c494f89b2a6c64f7b) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 4e15670b04..c148fa33f3 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1682,7 +1682,7 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, struct lock_struct *locks = br_lck->lock_data; DEBUG(10,("brl_get_locks_internal: %u current locks on file_id %s\n", br_lck->num_locks, - file_id_static_string(&fsp->file_id))); + file_id_string_tos(&fsp->file_id))); for( i = 0; i < br_lck->num_locks; i++) { print_lock_struct(i, &locks[i]); } -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/locking/brlock.c | 56 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index c148fa33f3..f821761cd7 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -59,7 +59,7 @@ static void print_lock_struct(unsigned int i, struct lock_struct *pls) See if two locking contexts are equal. ****************************************************************************/ -BOOL brl_same_context(const struct lock_context *ctx1, +bool brl_same_context(const struct lock_context *ctx1, const struct lock_context *ctx2) { return (procid_equal(&ctx1->pid, &ctx2->pid) && @@ -71,7 +71,7 @@ BOOL brl_same_context(const struct lock_context *ctx1, See if lck1 and lck2 overlap. ****************************************************************************/ -static BOOL brl_overlap(const struct lock_struct *lck1, +static bool brl_overlap(const struct lock_struct *lck1, const struct lock_struct *lck2) { /* this extra check is not redundent - it copes with locks @@ -93,7 +93,7 @@ static BOOL brl_overlap(const struct lock_struct *lck1, See if lock2 can be added when lock1 is in place. ****************************************************************************/ -static BOOL brl_conflict(const struct lock_struct *lck1, +static bool brl_conflict(const struct lock_struct *lck1, const struct lock_struct *lck2) { /* Ignore PENDING locks. */ @@ -119,7 +119,7 @@ static BOOL brl_conflict(const struct lock_struct *lck1, know already match. ****************************************************************************/ -static BOOL brl_conflict_posix(const struct lock_struct *lck1, +static bool brl_conflict_posix(const struct lock_struct *lck1, const struct lock_struct *lck2) { #if defined(DEVELOPER) @@ -147,7 +147,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1, } #if ZERO_ZERO -static BOOL brl_conflict1(const struct lock_struct *lck1, +static bool brl_conflict1(const struct lock_struct *lck1, const struct lock_struct *lck2) { if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) @@ -181,7 +181,7 @@ static BOOL brl_conflict1(const struct lock_struct *lck1, This is never used in the POSIX lock case. ****************************************************************************/ -static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2) +static bool brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2) { if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type)) return False; @@ -213,7 +213,7 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock Check if an unlock overlaps a pending lock. ****************************************************************************/ -static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) +static bool brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock) { if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start)) return True; @@ -228,7 +228,7 @@ static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct loc app depends on this ? ****************************************************************************/ -static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, BOOL blocking_lock) +static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, bool blocking_lock) { if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { /* amazing the little things you learn with a test @@ -310,7 +310,7 @@ static int lock_compare(const struct lock_struct *lck1, ****************************************************************************/ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, - struct lock_struct *plock, BOOL blocking_lock) + struct lock_struct *plock, bool blocking_lock) { unsigned int i; files_struct *fsp = br_lck->fsp; @@ -378,9 +378,9 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck, static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, /* Output array. */ const struct lock_struct *ex, /* existing lock. */ const struct lock_struct *plock, /* proposed lock. */ - BOOL *lock_was_added) + bool *lock_was_added) { - BOOL lock_types_differ = (ex->lock_type != plock->lock_type); + bool lock_types_differ = (ex->lock_type != plock->lock_type); /* We can't merge non-conflicting locks on different context - ignore fnum. */ @@ -594,8 +594,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx, unsigned int i, count; struct lock_struct *locks = br_lck->lock_data; struct lock_struct *tp; - BOOL lock_was_added = False; - BOOL signal_pending_read = False; + bool lock_was_added = False; + bool signal_pending_read = False; /* No zero-zero locks for POSIX. */ if (plock->start == 0 && plock->size == 0) { @@ -741,7 +741,7 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, br_off size, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL blocking_lock, + bool blocking_lock, uint32 *psmbpid) { NTSTATUS ret; @@ -784,7 +784,7 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, Unlock a range of bytes - Windows semantics. ****************************************************************************/ -static BOOL brl_unlock_windows(struct messaging_context *msg_ctx, +static bool brl_unlock_windows(struct messaging_context *msg_ctx, struct byte_range_lock *br_lck, const struct lock_struct *plock) { @@ -887,14 +887,14 @@ static BOOL brl_unlock_windows(struct messaging_context *msg_ctx, Unlock a range of bytes - POSIX semantics. ****************************************************************************/ -static BOOL brl_unlock_posix(struct messaging_context *msg_ctx, +static bool brl_unlock_posix(struct messaging_context *msg_ctx, struct byte_range_lock *br_lck, const struct lock_struct *plock) { unsigned int i, j, count; struct lock_struct *tp; struct lock_struct *locks = br_lck->lock_data; - BOOL overlap_found = False; + bool overlap_found = False; /* No zero-zero locks for POSIX. */ if (plock->start == 0 && plock->size == 0) { @@ -922,7 +922,7 @@ static BOOL brl_unlock_posix(struct messaging_context *msg_ctx, for (i = 0; i < br_lck->num_locks; i++) { struct lock_struct *lock = &locks[i]; struct lock_struct tmp_lock[3]; - BOOL lock_was_added = False; + bool lock_was_added = False; unsigned int tmp_count; /* Only remove our own locks - ignore fnum. */ @@ -1056,7 +1056,7 @@ static BOOL brl_unlock_posix(struct messaging_context *msg_ctx, Unlock a range of bytes. ****************************************************************************/ -BOOL brl_unlock(struct messaging_context *msg_ctx, +bool brl_unlock(struct messaging_context *msg_ctx, struct byte_range_lock *br_lck, uint32 smbpid, struct server_id pid, @@ -1087,7 +1087,7 @@ BOOL brl_unlock(struct messaging_context *msg_ctx, Returns True if the region required is currently unlocked, False if locked. ****************************************************************************/ -BOOL brl_locktest(struct byte_range_lock *br_lck, +bool brl_locktest(struct byte_range_lock *br_lck, uint32 smbpid, struct server_id pid, br_off start, @@ -1095,7 +1095,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck, enum brl_type lock_type, enum brl_flavour lock_flav) { - BOOL ret = True; + bool ret = True; unsigned int i; struct lock_struct lock; const struct lock_struct *locks = br_lck->lock_data; @@ -1170,7 +1170,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, /* Make sure existing locks don't conflict */ for (i=0; i < br_lck->num_locks; i++) { const struct lock_struct *exlock = &locks[i]; - BOOL conflict = False; + bool conflict = False; if (exlock->lock_flav == WINDOWS_LOCK) { conflict = brl_conflict(exlock, &lock); @@ -1193,7 +1193,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, */ if(lp_posix_locking(fsp->conn->params)) { - BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK); + bool ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK); DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n", (double)*pstart, (double)*psize, ret ? "locked" : "unlocked", @@ -1213,7 +1213,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, Remove a particular pending lock. ****************************************************************************/ -BOOL brl_lock_cancel(struct byte_range_lock *br_lck, +bool brl_lock_cancel(struct byte_range_lock *br_lck, uint32 smbpid, struct server_id pid, br_off start, @@ -1274,7 +1274,7 @@ void brl_close_fnum(struct messaging_context *msg_ctx, int num_deleted_windows_locks = 0; struct lock_struct *locks = br_lck->lock_data; struct server_id pid = procid_self(); - BOOL unlock_individually = False; + bool unlock_individually = False; if(lp_posix_locking(fsp->conn->params)) { @@ -1339,7 +1339,7 @@ void brl_close_fnum(struct messaging_context *msg_ctx, for (i=0; i < br_lck->num_locks; i++) { struct lock_struct *lock = &locks[i]; - BOOL del_this_lock = False; + bool del_this_lock = False; if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) { if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) { @@ -1397,7 +1397,7 @@ void brl_close_fnum(struct messaging_context *msg_ctx, Ensure this set of lock entries is valid. ****************************************************************************/ -static BOOL validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks) +static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks) { unsigned int i; unsigned int num_valid_entries = 0; @@ -1591,7 +1591,7 @@ static int byte_range_lock_destructor(struct byte_range_lock *br_lck) ********************************************************************/ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, - files_struct *fsp, BOOL read_only) + files_struct *fsp, bool read_only) { TDB_DATA key, data; struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); -- cgit From d60fac2a5a789680b6dd9f05ab15a3033ec2887c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 5 Dec 2007 20:53:22 +0100 Subject: Tiny simplifications locking.c:open_read_only was unused don't export the silly boolean flag locking_init(bool read_only) (This used to be commit 2f3c865707010bc7c463a02782dbee3dc2479da1) --- source3/locking/brlock.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index f821761cd7..eb42d081fe 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -258,7 +258,7 @@ static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *loc Open up the brlock.tdb database. ****************************************************************************/ -void brl_init(int read_only) +void brl_init(bool read_only) { if (brlock_db) { return; @@ -279,11 +279,8 @@ void brl_init(int read_only) Close down the brlock.tdb database. ****************************************************************************/ -void brl_shutdown(int read_only) +void brl_shutdown(void) { - if (!brlock_db) { - return; - } TALLOC_FREE(brlock_db); } -- cgit From 68694369fc96354452979b07425f3f48c4f73bbe Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:09:48 +0300 Subject: Merge CTDB-related fixes from samba-ctdb 3.0 branch (http://samba.org/~tridge/3_0-ctdb) Signed-off-by: Alexander Bokovoy (This used to be commit 0c8e23afbbb2d081fc23908bafcad04650bfacea) --- source3/locking/brlock.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index eb42d081fe..4191871bb1 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -41,11 +41,11 @@ static struct db_context *brlock_db; static void print_lock_struct(unsigned int i, struct lock_struct *pls) { - DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %s, ", + DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %u, ", i, (unsigned int)pls->context.smbpid, (unsigned int)pls->context.tid, - procid_str_static(&pls->context.pid) )); + (unsigned int)procid_to_pid(&pls->context.pid) )); DEBUG(10,("start = %.0f, size = %.0f, fnum = %d, %s %s\n", (double)pls->start, @@ -263,10 +263,9 @@ void brl_init(bool read_only) if (brlock_db) { return; } - brlock_db = db_open(NULL, lock_path("brlock.tdb"), 0, - TDB_DEFAULT - |TDB_VOLATILE - |(read_only?0x0:TDB_CLEAR_IF_FIRST), + brlock_db = db_open(NULL, lock_path("brlock.tdb"), + lp_open_files_db_hash_size(), + TDB_DEFAULT | TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); if (!brlock_db) { DEBUG(0,("Failed to open byte range locking database %s\n", @@ -1495,14 +1494,16 @@ static int traverse_fn(struct db_record *rec, void *state) } } - for ( i=0; ifn(*key, - locks[i].context.pid, - locks[i].lock_type, - locks[i].lock_flav, - locks[i].start, - locks[i].size, - cb->private_data); + if (cb->fn) { + for ( i=0; ifn(*key, + locks[i].context.pid, + locks[i].lock_type, + locks[i].lock_flav, + locks[i].start, + locks[i].size, + cb->private_data); + } } SAFE_FREE(locks); -- cgit From 33f3eeaa00974860dfc45962d5fd34cf05396c76 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 17:35:25 +0100 Subject: Fix some "set but never used" warnings (This used to be commit 4a6dadc5178f4861e9c032321939db3b639734b5) --- source3/locking/brlock.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 4191871bb1..341d00f3fe 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -1539,11 +1539,6 @@ int brl_forall(void (*fn)(struct file_id id, struct server_id pid, static int byte_range_lock_destructor(struct byte_range_lock *br_lck) { - TDB_DATA key; - - key.dptr = (uint8 *)&br_lck->key; - key.dsize = sizeof(struct file_id); - if (br_lck->read_only) { SMB_ASSERT(!br_lck->modified); } -- cgit From 170995493376e926b7b30791286598ad6b7af4a4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Mar 2008 14:40:07 +0100 Subject: Merge leftovers of 0e1a86bc845 in 3-0-ctdb (This used to be commit 64b1625f8e3bca43504871747bef6631e1b18f44) --- source3/locking/brlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 341d00f3fe..940dfbff8f 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -265,7 +265,7 @@ void brl_init(bool read_only) } brlock_db = db_open(NULL, lock_path("brlock.tdb"), lp_open_files_db_hash_size(), - TDB_DEFAULT | TDB_CLEAR_IF_FIRST, + TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 ); if (!brlock_db) { DEBUG(0,("Failed to open byte range locking database %s\n", -- cgit From e76ec752be503338c0a26be34f8d0fb4fbeb5fe6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Apr 2008 17:23:48 -0700 Subject: Quieten valgrind message on make valgrindtest. This doesn't seem to be valid (vl - feel free to confirm). Jeremy. (This used to be commit 43b0254d93540eeaddaa32d76dd9271f4dc2ebff) --- source3/locking/brlock.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/locking/brlock.c') diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 940dfbff8f..032aaa56b6 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -749,6 +749,11 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx, } #endif +#ifdef DEVELOPER + /* Quieten valgrind on test. */ + memset(&lock, '\0', sizeof(lock)); +#endif + lock.context.smbpid = smbpid; lock.context.pid = pid; lock.context.tid = br_lck->fsp->conn->cnum; -- cgit