X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fback-ldbm%2Fid2entry.c;h=00b3a9977408484437ac4ef4de13844e2d5e1f2f;hb=aa3b69eb32f3292340b1af8c7733aafaf6f2f6e5;hp=38522cb54ac392dba04f87fecc86bf6d7748eba1;hpb=4a5d740e2ee4e700e76b2eac6f079e39f0134c94;p=openldap diff --git a/servers/slapd/back-ldbm/id2entry.c b/servers/slapd/back-ldbm/id2entry.c index 38522cb54a..00b3a99774 100644 --- a/servers/slapd/back-ldbm/id2entry.c +++ b/servers/slapd/back-ldbm/id2entry.c @@ -1,61 +1,86 @@ /* id2entry.c - routines to deal with the id2entry index */ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ + +#include "portable.h" #include -#include -#include + +#include + #include "slap.h" #include "back-ldbm.h" -extern struct dbcache *ldbm_cache_open(); -extern Datum ldbm_cache_fetch(); -extern char *dn_parent(); -extern Entry *str2entry(); -extern char *entry2str(); -extern pthread_mutex_t entry2str_mutex; +/* + * This routine adds (or updates) an entry on disk. + * The cache should already be updated. + */ int id2entry_add( Backend *be, Entry *e ) { - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - struct dbcache *db; + DBCache *db; Datum key, data; int len, rc, flags; - -#ifdef LDBM_USE_DB2 - memset( &key, 0, sizeof( key ) ); - memset( &data, 0, sizeof( data ) ); +#ifndef WORDS_BIGENDIAN + ID id; #endif - Debug( LDAP_DEBUG_TRACE, "=> id2entry_add( %d, \"%s\" )\n", e->e_id, + ldbm_datum_init( key ); + ldbm_datum_init( data ); + +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ENTRY, "id2entry_add: (%s)%ld\n", e->e_dn, e->e_id, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "=> id2entry_add( %ld, \"%s\" )\n", e->e_id, e->e_dn, 0 ); +#endif + if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_add: could not open/create id2entry%s\n", + LDBM_SUFFIX, 0,0 ); +#else Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n", LDBM_SUFFIX, 0, 0 ); +#endif + return( -1 ); } +#ifdef WORDS_BIGENDIAN key.dptr = (char *) &e->e_id; +#else + id = htonl(e->e_id); + key.dptr = (char *) &id; +#endif key.dsize = sizeof(ID); - pthread_mutex_lock( &entry2str_mutex ); - data.dptr = entry2str( e, &len, 1 ); + ldap_pvt_thread_mutex_lock( &entry2str_mutex ); + data.dptr = entry2str( e, &len ); data.dsize = len + 1; /* store it */ flags = LDBM_REPLACE; - if ( li->li_flush_wrt ) flags != LDBM_SYNC; rc = ldbm_cache_store( db, key, data, flags ); - pthread_mutex_unlock( &entry2str_mutex ); + ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); ldbm_cache_close( be, db ); - (void) cache_add_entry_lock( &li->li_cache, e, 0 ); +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ENTRY, "id2entry_add: return %d\n", rc, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "<= id2entry_add %d\n", rc, 0, 0 ); +#endif + - /* XXX should entries be born locked, i.e. apply writer lock here? */ return( rc ); } @@ -63,125 +88,212 @@ int id2entry_delete( Backend *be, Entry *e ) { struct ldbminfo *li = (struct ldbminfo *) be->be_private; - struct dbcache *db; + DBCache *db; Datum key; int rc; +#ifndef WORDS_BIGENDIAN + ID id; +#endif - Debug( LDAP_DEBUG_TRACE, "=> id2entry_delete( %d, \"%s\" )\n", e->e_id, +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ENTRY, "id2entry_delete: (%s)%ld\n", e->e_dn, e->e_id, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, "=> id2entry_delete( %ld, \"%s\" )\n", e->e_id, e->e_dn, 0 ); +#endif - /* XXX - check for writer lock - should also check no reader pending */ - assert(pthread_rdwr_wchk_np(&e->e_rdwr)); -#ifdef LDBM_USE_DB2 - memset( &key, 0, sizeof( key ) ); +#ifdef notdef +#ifdef LDAP_RDWR_DEBUG + /* check for writer lock */ + assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1); #endif +#endif + + ldbm_datum_init( key ); - /* XXX - check for writer lock - should also check no reader pending */ - Debug (LDAP_DEBUG_TRACE, - "rdwr_Xchk: readers_reading: %d writer_writing: %d\n", - e->e_rdwr.readers_reading, e->e_rdwr.writer_writing, 0); - if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_delete: could not open/create id2entry%s\n", + LDBM_SUFFIX, 0, 0 ); +#else Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n", LDBM_SUFFIX, 0, 0 ); +#endif + return( -1 ); } if ( cache_delete_entry( &li->li_cache, e ) != 0 ) { - Debug( LDAP_DEBUG_ANY, "could not delete %d (%s) from cache\n", +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_delete: Could not delete (%s)%ld from cache\n", + e->e_dn, e->e_id, 0 ); +#else + Debug(LDAP_DEBUG_ANY, "could not delete %ld (%s) from cache\n", e->e_id, e->e_dn, 0 ); +#endif + } +#ifdef WORDS_BIGENDIAN key.dptr = (char *) &e->e_id; +#else + id = htonl(e->e_id); + key.dptr = (char *) &id; +#endif key.dsize = sizeof(ID); rc = ldbm_cache_delete( db, key ); ldbm_cache_close( be, db ); +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ENTRY, "id2entry_delete: return %d\n", rc, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "<= id2entry_delete %d\n", rc, 0, 0 ); +#endif + return( rc ); } -/* XXX returns entry with reader/writer lock */ +/* returns entry with reader/writer lock */ Entry * -id2entry( Backend *be, ID id, int rw ) +id2entry_rw( Backend *be, ID id, int rw ) { struct ldbminfo *li = (struct ldbminfo *) be->be_private; - struct dbcache *db; + DBCache *db; Datum key, data; Entry *e; - -#ifdef LDBM_USE_DB2 - memset( &key, 0, sizeof( key ) ); - memset( &data, 0, sizeof( data ) ); +#ifndef WORDS_BIGENDIAN + ID id2; #endif + ldbm_datum_init( key ); + ldbm_datum_init( data ); + +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ENTRY, + "id2entry_rw: %s (%ld)\n", rw ? "write" : "read", id, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "=> id2entry_%s( %ld )\n", rw ? "w" : "r", id, 0 ); +#endif + if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s 0x%x (cache)\n", - rw ? "w" : "r", e, 0 ); +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, DETAIL1, + "id2entry_rw: %s (%ld) 0x%lx (cache).\n", + rw ? "write" : "read", id, (unsigned long)e ); +#else + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", + rw ? "w" : "r", id, (unsigned long) e ); +#endif + return( e ); } if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_rw: could not open id2entry%s\n", LDBM_SUFFIX, 0, 0 ); +#else Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n", LDBM_SUFFIX, 0, 0 ); +#endif + return( NULL ); } +#ifdef WORDS_BIGENDIAN key.dptr = (char *) &id; +#else + id2 = htonl(id); + key.dptr = (char *) &id2; +#endif key.dsize = sizeof(ID); data = ldbm_cache_fetch( db, key ); if ( data.dptr == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_rw: (%ld) not found\n", id, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) not found\n", rw ? "w" : "r", id, 0 ); +#endif + ldbm_cache_close( be, db ); return( NULL ); } e = str2entry( data.dptr ); - ldbm_datum_free( db->dbc_db, data ); ldbm_cache_close( be, db ); if ( e == NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (failed)\n", +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_rw: %s of %ld failed\n", rw ? "write" : "read", id, 0); +#else + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (failed)\n", rw ? "w" : "r", id, 0 ); - return( NULL ); - } +#endif - /* acquire required reader/writer lock */ - if (entry_rdwr_lock(e, rw)) { - /* XXX set DELETE flag?? */ - entry_free(e); - return(NULL); + return( NULL ); } e->e_id = id; - (void) cache_add_entry_lock( &li->li_cache, e, 0 ); - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (disk)\n", - rw ? "w" : "r", id, 0 ); - return( e ); -} + if( cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) { + entry_free( e ); + + /* XXX this is a kludge. + * maybe the entry got added underneath us + * There are many underlying race condtions in the cache/disk code. + */ + if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, DETAIL1, + "id2entry_rw: %s of %ld 0x%lx (cache)\n", + rw ? "write" : "read", id, (unsigned long)e ); +#else + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", + rw ? "w" : "r", id, (unsigned long) e ); +#endif -Entry * -id2entry_r( Backend *be, ID id ) -{ - return( id2entry( be, id, 0 ) ); -} + return( e ); + } -Entry * -id2entry_2( Backend *be, ID id ) -{ - return( id2entry( be, id, 1 ) ); -} +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ERR, + "id2entry_rw: %s of %ld (cache add failed)\n", + rw ? "write" : "read", id, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (cache add failed)\n", + rw ? "w" : "r", id, 0 ); +#endif + return NULL; + } + +#ifdef NEW_LOGGING + LDAP_LOG( INDEX, ENTRY, + "id2entry_rw: %s of %ld 0x%lx (disk)\n", + rw ? "write" : "read", id, (unsigned long)e ); +#else + Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (disk)\n", + rw ? "w" : "r", id, (unsigned long) e ); +#endif + + /* marks the entry as committed, so it will get added to the cache + * when the lock is released */ + cache_entry_commit( e ); + + return( e ); +}