From 372dcb78eb33e78ef901976203225ef8d274efa1 Mon Sep 17 00:00:00 2001 From: Jong Hyuk Choi Date: Mon, 23 Feb 2004 22:48:46 +0000 Subject: [PATCH] Glue entry pruning : delete parent entries after modrdn when they are glue and become leaf entry --- servers/slapd/back-bdb/modrdn.c | 42 +++++++++++++++++++++++++++++++++ servers/slapd/modrdn.c | 40 +++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index b42281ef74..ecef5038d8 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -70,6 +70,9 @@ bdb_modrdn( Operation *op, SlapReply *rs ) Entry *ctxcsn_e; int ctxcsn_added = 0; + int parent_is_glue = 0; + int parent_is_leaf = 0; + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n", op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val, @@ -116,6 +119,8 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto return_results; } + parent_is_glue = 0; + parent_is_leaf = 0; ldap_pvt_thread_yield(); bdb_trans_backoff( ++num_retries ); } @@ -952,6 +957,39 @@ retry: /* transaction retry */ rs->sr_text = "entry update failed"; goto return_results; } + + bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock ); + if ( eip ) p = eip->bei_e; + if ( p_ndn.bv_len != 0 ) { + parent_is_glue = is_entry_glue(p); + rs->sr_err = bdb_cache_children( op, lt2, p ); + if ( rs->sr_err != DB_NOTFOUND ) { + switch( rs->sr_err ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + case 0: + break; + default: +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "<=- bdb_modrdn: has_children failed %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#else + Debug(LDAP_DEBUG_ARGS, + "<=- bdb_modrdn: has_children failed: %s (%d)\n", + db_strerror(rs->sr_err), rs->sr_err, 0 ); +#endif + rs->sr_err = LDAP_OTHER; + rs->sr_text = "internal error"; + goto return_results; + } + parent_is_leaf = 1; + } + bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); + p = NULL; + } + if ( TXN_COMMIT( lt2, 0 ) != 0 ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "txn_commit(2) failed"; @@ -1051,6 +1089,10 @@ return_results: TXN_CHECKPOINT( bdb->bi_dbenv, bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); } + + if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { + op->o_delete_glue_parent = 1; + } done: if( new_dn.bv_val != NULL ) free( new_dn.bv_val ); diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 87b1068bd3..ea8dd0e612 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -63,6 +63,13 @@ do_modrdn( ber_len_t length; int manageDSAit; + struct berval pdn = { 0, NULL }; + struct berval org_req_dn = { 0, NULL }; + struct berval org_req_ndn = { 0, NULL }; + struct berval org_dn = { 0, NULL }; + struct berval org_ndn = { 0, NULL }; + int org_managedsait; + #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 ); #else @@ -373,6 +380,39 @@ do_modrdn( } op->o_bd->be_modrdn( op, rs ); + if ( op->o_bd->be_delete ) { + org_req_dn = op->o_req_dn; + org_req_ndn = op->o_req_ndn; + org_dn = op->o_dn; + org_ndn = op->o_ndn; + org_managedsait = get_manageDSAit( op ); + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + op->o_managedsait = 1; + + while ( rs->sr_err == LDAP_SUCCESS && + op->o_delete_glue_parent ) { + op->o_delete_glue_parent = 0; + if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) { + slap_callback cb = { NULL }; + cb.sc_response = slap_null_cb; + dnParent( &op->o_req_ndn, &pdn ); + op->o_req_dn = pdn; + op->o_req_ndn = pdn; + op->o_callback = &cb; + op->o_bd->be_delete( op, rs ); + } else { + break; + } + } + op->o_managedsait = org_managedsait; + op->o_dn = org_dn; + op->o_ndn = org_ndn; + op->o_req_dn = org_req_dn; + op->o_req_ndn = org_req_ndn; + op->o_delete_glue_parent = 0; + } + #ifndef SLAPD_MULTIMASTER } else { BerVarray defref = NULL; -- 2.39.5