mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
merge some recent tdb changed from samba3
This commit is contained in:
parent
b881b72cb9
commit
0e845ecd49
@ -149,6 +149,47 @@ static inline int __spin_is_locked(spinlock_t *lock)
|
||||
return (*lock != 1);
|
||||
}
|
||||
|
||||
#elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730)
|
||||
|
||||
/* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See
|
||||
* sync(3) for the details of the intrinsic operations.
|
||||
*
|
||||
* "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro.
|
||||
*/
|
||||
|
||||
#if defined(STANDALONE)
|
||||
|
||||
/* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */
|
||||
#define inline __inline
|
||||
|
||||
#endif /* STANDALONE */
|
||||
|
||||
/* Returns 0 if the lock is acquired, EBUSY otherwise. */
|
||||
static inline int __spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
unsigned int val;
|
||||
val = __lock_test_and_set(lock, 1);
|
||||
return val == 0 ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
static inline void __spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
__lock_release(lock);
|
||||
}
|
||||
|
||||
static inline void __spin_lock_init(spinlock_t *lock)
|
||||
{
|
||||
__lock_release(lock);
|
||||
}
|
||||
|
||||
/* Returns 1 if the lock is held, 0 otherwise. */
|
||||
static inline int __spin_is_locked(spinlock_t *lock)
|
||||
{
|
||||
unsigned int val;
|
||||
val = __add_and_fetch(lock, 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
#elif defined(MIPS_SPINLOCKS)
|
||||
|
||||
static inline unsigned int load_linked(unsigned long addr)
|
||||
@ -227,7 +268,11 @@ static void yield_cpu(void)
|
||||
|
||||
static int this_is_smp(void)
|
||||
{
|
||||
#if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN)
|
||||
return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -247,10 +247,14 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
|
||||
tdb->fd, offset, rw_type, lck_type));
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
|
||||
}
|
||||
/* Otherwise - generic lock error. */
|
||||
/* errno set by fcntl */
|
||||
/* Otherwise - generic lock error. errno set by fcntl.
|
||||
* EAGAIN is an expected return from non-blocking
|
||||
* locks. */
|
||||
if (errno != EAGAIN) {
|
||||
TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n",
|
||||
tdb->fd, offset, rw_type, lck_type, strerror(errno)));
|
||||
tdb->fd, offset, rw_type, lck_type,
|
||||
strerror(errno)));
|
||||
}
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
|
||||
}
|
||||
return 0;
|
||||
@ -858,6 +862,8 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
|
||||
tdb_off rec_ptr, last_ptr, newrec_ptr;
|
||||
struct list_struct newrec;
|
||||
|
||||
memset(&newrec, '\0', sizeof(newrec));
|
||||
|
||||
if (tdb_lock(tdb, -1, F_WRLCK) == -1)
|
||||
return 0;
|
||||
|
||||
@ -1706,7 +1712,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
|
||||
{
|
||||
TDB_CONTEXT *tdb;
|
||||
struct stat st;
|
||||
int rev = 0, locked;
|
||||
int rev = 0, locked = 0;
|
||||
unsigned char *vp;
|
||||
u32 vertest;
|
||||
|
||||
@ -1764,8 +1770,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
|
||||
}
|
||||
|
||||
/* we need to zero database if we are the only one with it open */
|
||||
if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
|
||||
&& (tdb_flags & TDB_CLEAR_IF_FIRST)) {
|
||||
if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
|
||||
(locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) {
|
||||
open_flags |= O_CREAT;
|
||||
if (ftruncate(tdb->fd, 0) == -1) {
|
||||
TDB_LOG((tdb, 0, "tdb_open_ex: "
|
||||
@ -1838,10 +1844,19 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
|
||||
name, strerror(errno)));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
|
||||
we didn't get the initial exclusive lock as we need to let all other
|
||||
users know we're using it. */
|
||||
|
||||
if (tdb_flags & TDB_CLEAR_IF_FIRST) {
|
||||
/* leave this lock in place to indicate it's in use */
|
||||
if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
internal:
|
||||
/* Internal (memory-only) databases skip all the code above to
|
||||
@ -2019,12 +2034,14 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons
|
||||
}
|
||||
|
||||
|
||||
/* reopen a tdb - this is used after a fork to ensure that we have an independent
|
||||
/* reopen a tdb - this can be used after a fork to ensure that we have an independent
|
||||
seek pointer from our parent and to re-establish locks */
|
||||
int tdb_reopen(TDB_CONTEXT *tdb)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (tdb->flags & TDB_INTERNAL)
|
||||
return 0; /* Nothing to do. */
|
||||
if (tdb_munmap(tdb) != 0) {
|
||||
TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
|
||||
goto fail;
|
||||
@ -2045,7 +2062,7 @@ int tdb_reopen(TDB_CONTEXT *tdb)
|
||||
goto fail;
|
||||
}
|
||||
tdb_mmap(tdb);
|
||||
if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) {
|
||||
if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) {
|
||||
TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n"));
|
||||
goto fail;
|
||||
}
|
||||
@ -2063,7 +2080,10 @@ int tdb_reopen_all(void)
|
||||
TDB_CONTEXT *tdb;
|
||||
|
||||
for (tdb=tdbs; tdb; tdb = tdb->next) {
|
||||
if (tdb_reopen(tdb) != 0) return -1;
|
||||
/* Ensure no clear-if-first. */
|
||||
tdb->flags &= ~TDB_CLEAR_IF_FIRST;
|
||||
if (tdb_reopen(tdb) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user