summaryrefslogtreecommitdiff
path: root/source3/locking/brlock.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-04-28 20:54:23 +0000
committerJeremy Allison <jra@samba.org>2000-04-28 20:54:23 +0000
commit9a5eb068ab32418e793d482db1f078f147f9ee08 (patch)
tree9939206f1f8220e16f168cba1f19f18ee25dacc6 /source3/locking/brlock.c
parent46e84a0090516e3ae67b3ceb06b3d9a546e8e71e (diff)
downloadsamba-9a5eb068ab32418e793d482db1f078f147f9ee08.tar.gz
samba-9a5eb068ab32418e793d482db1f078f147f9ee08.tar.bz2
samba-9a5eb068ab32418e793d482db1f078f147f9ee08.zip
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)
Diffstat (limited to 'source3/locking/brlock.c')
-rw-r--r--source3/locking/brlock.c296
1 files changed, 1 insertions, 295 deletions
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
@@ -171,237 +171,6 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
}
/****************************************************************************
- 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; i<num_locks && ulhead; i++) {
-
- struct lock_struct *lock = &locks[i];
- struct unlock_list *ul_curr;
-
- /* If it's not this process, ignore it. */
- if (lock->context.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; i<num_locks && ul_head; i++) */
-
- tdb_unlockchain(tdb, kbuf);
-
- if (dbuf.dptr)
- free(dbuf.dptr);
-
- return ulhead;
-}
-
-/****************************************************************************
Unlock a range of bytes.
****************************************************************************/
@@ -426,7 +195,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
dbuf = tdb_fetch(tdb, kbuf);
if (!dbuf.dptr) {
- DEBUG(0,("brl_unlock: tdb_fetch failed !\n"));
+ DEBUG(10,("brl_unlock: tdb_fetch failed !\n"));
goto fail;
}
@@ -591,69 +360,6 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
}
/****************************************************************************
- 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; i<count; i++) {
- struct lock_struct *lock = &locks[i];
-
- if (lock->context.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.
****************************************************************************/