X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Fadd.c;h=797398ad4b5cd72d14f409874fad2dd7752bae2b;hb=76ed17f7942d4e3810fa90b46143e615af311167;hp=3dacd6da3dba445dece437a7eff58708971c2e65;hpb=42e0d83cb3a1a1c5b25183f1ab74ce7edbe25de7;p=openldap diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 3dacd6da3d..797398ad4b 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -6,11 +6,11 @@ #include #include "slap.h" #include "back-ldbm.h" +#include "proto-back-ldbm.h" extern int global_schemacheck; extern char *dn_parent(); extern char *dn_normalize(); -extern Entry *dn2entry(); int ldbm_back_add( @@ -21,27 +21,30 @@ ldbm_back_add( ) { struct ldbminfo *li = (struct ldbminfo *) be->be_private; - char *matched; char *dn = NULL, *pdn = NULL; - Entry *p; + Entry *p = NULL; + int rc; dn = dn_normalize( strdup( e->e_dn ) ); - matched = NULL; - if ( (p = dn2entry( be, dn, &matched )) != NULL ) { - cache_return_entry( &li->li_cache, p ); + + Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", dn, 0, 0); + + if ( ( dn2id( be, dn ) ) != NOID ) { entry_free( e ); free( dn ); send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" ); return( -1 ); } - if ( matched != NULL ) { - free( matched ); - } + /* XXX race condition here til we cache_add_entry_lock below XXX */ if ( global_schemacheck && oc_schema_check( e ) != 0 ) { - Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n", 0, 0, - 0 ); + Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n", + 0, 0, 0 ); + + /* XXX this should be ok, no other thread should have access + * because e hasn't been added to the cache yet + */ entry_free( e ); free( dn ); send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION, "", @@ -61,6 +64,10 @@ ldbm_back_add( Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0, 0 ); next_id_return( be, e->e_id ); + + /* XXX this should be ok, no other thread should have access + * because e hasn't been added to the cache yet + */ entry_free( e ); free( dn ); send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" ); @@ -74,17 +81,22 @@ ldbm_back_add( */ if ( (pdn = dn_parent( be, dn )) != NULL ) { + char *matched; /* no parent */ matched = NULL; - if ( (p = dn2entry( be, pdn, &matched )) == NULL ) { + + /* get entry with reader lock */ + if ( (p = dn2entry_r( be, pdn, &matched )) == NULL ) { + Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", 0, + 0, 0 ); send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, "" ); if ( matched != NULL ) { free( matched ); } - Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", 0, - 0, 0 ); - goto error_return; + + rc = -1; + goto return_results; } if ( matched != NULL ) { free( matched ); @@ -96,7 +108,9 @@ ldbm_back_add( 0, 0 ); send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" ); - goto error_return; + + rc = -1; + goto return_results; } } else { if ( ! be_isroot( be, op->o_dn ) ) { @@ -104,9 +118,10 @@ ldbm_back_add( 0, 0 ); send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" ); - goto error_return; + + rc = -1; + goto return_results; } - p = NULL; } /* @@ -116,9 +131,10 @@ ldbm_back_add( if ( id2children_add( be, p, e ) != 0 ) { Debug( LDAP_DEBUG_TRACE, "id2children_add failed\n", 0, 0, 0 ); - send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", - "" ); - goto error_return; + send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" ); + + rc = -1; + goto return_results; } /* @@ -131,7 +147,9 @@ ldbm_back_add( Debug( LDAP_DEBUG_TRACE, "index_add_entry failed\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" ); - goto error_return; + + rc = -1; + goto return_results; } /* dn2id index */ @@ -139,35 +157,44 @@ ldbm_back_add( Debug( LDAP_DEBUG_TRACE, "dn2id_add failed\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" ); - goto error_return; + + rc = -1; + goto return_results; } + /* acquire writer lock */ + entry_rdwr_lock(e, 1); + /* id2entry index */ if ( id2entry_add( be, e ) != 0 ) { Debug( LDAP_DEBUG_TRACE, "id2entry_add failed\n", 0, 0, 0 ); (void) dn2id_delete( be, dn ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" ); - goto error_return; + + rc = -1; + goto return_results; } send_ldap_result( conn, op, LDAP_SUCCESS, "", "" ); + rc = 0; + +return_results:; + if ( dn != NULL ) free( dn ); if ( pdn != NULL ) free( pdn ); + cache_set_state( &li->li_cache, e, 0 ); - cache_return_entry( &li->li_cache, e ); - return( 0 ); -error_return:; - if ( dn != NULL ) - free( dn ); - if ( pdn != NULL ) - free( pdn ); - next_id_return( be, e->e_id ); - cache_delete_entry( &li->li_cache, e ); - cache_return_entry( &li->li_cache, e ); + /* free entry and writer lock */ + cache_return_entry_w( &li->li_cache, e ); + + /* free entry and reader lock */ + if (p != NULL) { + cache_return_entry_r( &li->li_cache, p ); + } - return( -1 ); + return( rc ); }