For ITS#5340. Here is a draft for what rs_ensure_entry_modifiable() usage is supposed to look like, though I haven't tested it well and I'm going home now. I'm unsure of the translucent code. rwm looks a bit weird, but that's mostly to assert that some functions that receive rs won't modify it. I haven't touched dynlist, don't know what entry ownership is there. Index: collect.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/overlays/collect.c,v retrieving revision 1.17 diff -u -2 -r1.17 collect.c --- collect.c 8 Dec 2009 19:53:39 -0000 1.17 +++ collect.c 10 Dec 2009 05:22:28 -0000 @@ -387,17 +387,5 @@ * work with that instead. */ - if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) { - Entry *e; - - e = entry_dup( rs->sr_entry ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - rs->sr_flags &= ~REP_ENTRY_MUSTRELEASE; - } else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - entry_free( rs->sr_entry ); - } - rs->sr_entry = e; - rs->sr_flags |= REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED; - } + (void) rs_ensure_entry_modifiable( op, rs, on ); /* Loop for each attribute in this collectinfo */ Index: rwm.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/overlays/rwm.c,v retrieving revision 1.122 diff -u -2 -r1.122 rwm.c --- rwm.c 8 Dec 2009 18:36:10 -0000 1.122 +++ rwm.c 10 Dec 2009 05:22:28 -0000 @@ -887,8 +887,13 @@ op2.o_bd->bd_info = (BackendInfo *)on; rc = rwm_send_entry( &op2, &rs ); - if ( rc == SLAP_CB_CONTINUE ) { - *ep = rs.sr_entry; + if ( rc == SLAP_CB_CONTINUE || rc == LDAP_SUCCESS ) { rc = LDAP_SUCCESS; + /* TESTING:Assert(we can give it away, to be released by caller) */ + assert( (rs.sr_flags & REP_ENTRY_MUSTFLUSH) || !rs.sr_entry ); + } else { + rs_replace_entry( &op2, &rs, on, NULL ); } + + *ep = rs.sr_entry; } @@ -1439,6 +1444,5 @@ (struct ldaprwmap *)on->on_bi.bi_private; - Entry *e = NULL; - slap_mask_t flags; + Entry *e; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; @@ -1456,23 +1460,12 @@ dc.ctx = "searchEntryDN"; + /* FIXME: all we need to duplicate are: + * - dn + * - ndn + * - attributes that are requested + * - no values if attrsonly is set + */ + (void) rs_ensure_entry_modifiable( op, rs, on ); e = rs->sr_entry; - flags = rs->sr_flags; - if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) { - /* FIXME: all we need to duplicate are: - * - dn - * - ndn - * - attributes that are requested - * - no values if attrsonly is set - */ - - e = entry_dup( e ); - if ( e == NULL ) { - rc = LDAP_NO_MEMORY; - goto fail; - } - - flags &= ~REP_ENTRY_MUSTRELEASE; - flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED ); - } /* @@ -1505,38 +1498,12 @@ (void)rwm_attrs( op, rs, &e->e_attrs, 1 ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - /* ITS#6423: REP_ENTRY_MUSTRELEASE incompatible - * with REP_ENTRY_MODIFIABLE */ - if ( rs->sr_entry == e ) { - rc = 1; - goto fail; - } - - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - - rs->sr_entry = e; - rs->sr_flags = flags; - return SLAP_CB_CONTINUE; fail:; - if ( e != NULL && e != rs->sr_entry ) { - if ( e->e_name.bv_val == dn.bv_val ) { - BER_BVZERO( &e->e_name ); - } - - if ( e->e_nname.bv_val == ndn.bv_val ) { - BER_BVZERO( &e->e_nname ); - } - - entry_free( e ); - } - - if ( !BER_BVISNULL( &dn ) ) { + if ( dn.bv_val != e->e_name.bv_val ) { ch_free( dn.bv_val ); } - if ( !BER_BVISNULL( &ndn ) ) { + if ( ndn.bv_val != e->e_nname.bv_val ) { ch_free( ndn.bv_val ); } Index: syncprov.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/overlays/syncprov.c,v retrieving revision 1.307 diff -u -2 -r1.307 syncprov.c --- syncprov.c 23 Nov 2009 21:17:25 -0000 1.307 +++ syncprov.c 10 Dec 2009 05:22:28 -0000 @@ -2666,15 +2666,5 @@ if ( !ap ) { - if ( !(rs->sr_flags & REP_ENTRY_MODIFIABLE) ) { - Entry *e = entry_dup( rs->sr_entry ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - } else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - entry_free( rs->sr_entry ); - } - rs->sr_entry = e; - rs->sr_flags |= - REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED; + if ( rs_ensure_entry_modifiable( op, rs, on )) { a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_contextCSN ); Index: translucent.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/overlays/translucent.c,v retrieving revision 1.67 diff -u -2 -r1.67 translucent.c --- translucent.c 29 Nov 2009 18:53:01 -0000 1.67 +++ translucent.c 10 Dec 2009 05:22:28 -0000 @@ -817,17 +817,8 @@ re = tavl_delete( &tc->list, le, entry_dn_cmp ); if ( re ) { - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - rs->sr_flags ^= REP_ENTRY_MUSTBEFREED; - entry_free( rs->sr_entry ); - } + rs_replace_entry( op, rs, on, re ); + rs->sr_flags |= REP_ENTRY_MUSTBEFREED; rc = test_filter( op, re, tc->orig ); if ( rc == LDAP_COMPARE_TRUE ) { - rs->sr_flags |= REP_ENTRY_MUSTBEFREED; - rs->sr_entry = re; - if ( tc->slimit >= 0 && rs->sr_nentries >= tc->slimit ) { return LDAP_SIZELIMIT_EXCEEDED; @@ -836,6 +827,5 @@ return SLAP_CB_CONTINUE; } else { - entry_free( re ); - rs->sr_entry = NULL; + rs_replace_entry( op, rs, on, NULL ); return 0; } @@ -856,13 +846,6 @@ rc = overlay_entry_get_ov(op, &rs->sr_entry->e_nname, NULL, NULL, 0, &le, on); if ( rc == LDAP_SUCCESS && le ) { - re = entry_dup( rs->sr_entry ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - rs->sr_flags ^= REP_ENTRY_MUSTBEFREED; - entry_free( rs->sr_entry ); - } + re = entry_dup(rs->sr_entry); + rs_replace_entry(op, rs, on, NULL); } else { le = NULL; @@ -904,12 +887,5 @@ /* Dispose of local entry */ if ( tc->step & LCL_SIDE ) { - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - rs->sr_flags ^= REP_ENTRY_MUSTBEFREED; - entry_free( rs->sr_entry ); - } + rs_replace_entry(op, rs, on, NULL); } else { overlay_entry_release_ov(op, le, 0, on); @@ -1159,17 +1135,17 @@ av = tavl_end( tc.list, TAVL_DIR_LEFT ); while ( av ) { - rs->sr_entry = av->avl_data; + assert( !(rs->sr_flags & REP_ENTRY_MUSTRELEASE) ); /* FIXME: do not know which overlay to use below? */ + rs_replace_entry( op, rs, NULL, av->avl_data ); + rs->sr_flags = REP_ENTRY_MUSTBEFREED; rc = test_filter( op, rs->sr_entry, op->ors_filter ); if ( rc == LDAP_COMPARE_TRUE ) { - rs->sr_flags = REP_ENTRY_MUSTBEFREED; rc = send_search_entry( op, rs ); if ( rc ) break; - } else { - entry_free( rs->sr_entry ); } av = tavl_next( av, TAVL_DIR_RIGHT ); } tavl_free( tc.list, NULL ); - rs->sr_entry = NULL; + assert( !(rs->sr_flags & REP_ENTRY_MUSTRELEASE) ); /* FIXME: do not know which overlay to use below? */ + rs_replace_entry( op, rs, NULL, NULL ); } send_ldap_result( op, rs ); Index: valsort.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/overlays/valsort.c,v retrieving revision 1.27 diff -u -2 -r1.27 valsort.c --- valsort.c 8 Dec 2009 19:53:39 -0000 1.27 +++ valsort.c 10 Dec 2009 05:22:28 -0000 @@ -298,18 +298,5 @@ if ( !a ) continue; - if (( rs->sr_flags & ( REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED ) ) != - ( REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED ) ) - { - Entry *e; - - e = entry_dup( rs->sr_entry ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - rs->sr_flags &= ~REP_ENTRY_MUSTRELEASE; - } else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - entry_free( rs->sr_entry ); - } - rs->sr_entry = e; - rs->sr_flags |= REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED; + if ( rs_ensure_entry_modifiable( op, rs, on )) { a = attr_find( rs->sr_entry->e_attrs, vi->vi_ad ); }