X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fback-ldbm%2Fid2entry.c;h=00b3a9977408484437ac4ef4de13844e2d5e1f2f;hb=aa3b69eb32f3292340b1af8c7733aafaf6f2f6e5;hp=2aee65d523b745b0279badce13f31ab2acb01ba3;hpb=72ba4cfb715001d30a6e48a2d7012f060f29d684;p=openldap diff --git a/servers/slapd/back-ldbm/id2entry.c b/servers/slapd/back-ldbm/id2entry.c index 2aee65d523..00b3a99774 100644 --- a/servers/slapd/back-ldbm/id2entry.c +++ b/servers/slapd/back-ldbm/id2entry.c @@ -1,4 +1,9 @@ /* 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" @@ -9,47 +14,73 @@ #include "slap.h" #include "back-ldbm.h" +/* + * 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; +#ifndef WORDS_BIGENDIAN + ID id; +#endif ldbm_datum_init( key ); ldbm_datum_init( data ); - Debug( LDAP_DEBUG_TRACE, "=> id2entry_add( %lu, \"%s\" )\n", e->e_id, +#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); ldap_pvt_thread_mutex_lock( &entry2str_mutex ); - data.dptr = entry2str( e, &len, 1 ); + data.dptr = entry2str( e, &len ); data.dsize = len + 1; /* store it */ flags = LDBM_REPLACE; - if ( li->li_dbcachewsync ) flags |= LDBM_SYNC; rc = ldbm_cache_store( db, key, data, flags ); 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 ); } @@ -57,123 +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( %lu, \"%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 */ -#ifdef LDAP_DEBUG - assert(ldap_pvt_thread_rdwr_wchk(&e->e_rdwr)); +#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.lt_readers_reading, e->e_rdwr.lt_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 %lu (%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; +#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%lx (cache)\n", - rw ? "w" : "r", (unsigned long)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_w( 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 ); +}