diff options
Diffstat (limited to 'source3/locking/brlock.c')
-rw-r--r-- | source3/locking/brlock.c | 296 |
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. ****************************************************************************/ |