From 8866cc9c921ada5969a5e0323489b296ca079512 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 27 Nov 2004 07:47:24 +0000 Subject: [PATCH] Force a refresh if the search base has changed --- servers/slapd/overlays/syncprov.c | 135 +++++++++++++++++------------- 1 file changed, 76 insertions(+), 59 deletions(-) diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index d61061faa6..61a7fa71a6 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -780,6 +780,68 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry *e, int mode return rs.sr_err; } +static void +syncprov_free_syncop( syncops *so ) +{ + syncres *sr, *srnext; + + ldap_pvt_thread_mutex_lock( &so->s_mutex ); + so->s_inuse--; + if ( so->s_inuse > 0 ) { + ldap_pvt_thread_mutex_unlock( &so->s_mutex ); + return; + } + ldap_pvt_thread_mutex_unlock( &so->s_mutex ); + filter_free( so->s_op->ors_filter ); + ch_free( so->s_op ); + ch_free( so->s_base.bv_val ); + for ( sr=so->s_res; sr; sr=srnext ) { + srnext = sr->s_next; + ch_free( sr ); + } + ldap_pvt_thread_mutex_destroy( &so->s_mutex ); + ch_free( so ); +} + +static int +syncprov_drop_psearch( syncops *so ) +{ + ldap_pvt_thread_mutex_lock( &so->s_op->o_conn->c_mutex ); + so->s_op->o_conn->c_n_ops_executing--; + so->s_op->o_conn->c_n_ops_completed++; + ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex ); + syncprov_free_syncop( so ); +} + +static int +syncprov_op_abandon( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + syncprov_info_t *si = on->on_bi.bi_private; + syncops *so, *soprev; + + ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); + for ( so=si->si_ops, soprev = (syncops *)&si->si_ops; so; + soprev=so, so=so->s_next ) { + if ( so->s_op->o_connid == op->o_connid && + so->s_op->o_msgid == op->orn_msgid ) { + so->s_op->o_abandon = 1; + soprev->s_next = so->s_next; + break; + } + } + ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); + if ( so ) { + /* Is this really a Cancel exop? */ + if ( op->o_tag != LDAP_REQ_ABANDON ) { + rs->sr_err = LDAP_CANCELLED; + send_ldap_result( so->s_op, rs ); + } + syncprov_drop_psearch( so ); + } + return SLAP_CB_CONTINUE; +} + /* Find which persistent searches are affected by this operation */ static void syncprov_matchops( Operation *op, opcookie *opc, int saveit ) @@ -788,7 +850,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) syncprov_info_t *si = on->on_bi.bi_private; fbase_cookie fc; - syncops *ss; + syncops *ss, *sprev, *snext; Entry *e; Attribute *a; int rc; @@ -824,17 +886,28 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) } ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); - for (ss = si->si_ops; ss; ss=ss->s_next) + for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss; + sprev = ss, ss=snext) { syncmatches *sm; int found = 0; + snext = ss->s_next; /* validate base */ fc.fss = ss; fc.fbase = 0; fc.fscope = 0; + + /* If the base of the search is missing, signal a refresh */ rc = syncprov_findbase( op, &fc ); - if ( rc != LDAP_SUCCESS ) continue; + if ( rc != LDAP_SUCCESS ) { + SlapReply rs = {REP_RESULT}; + send_ldap_error( ss->s_op, &rs, LDAP_SYNC_REFRESH_REQUIRED, + "search base has changed" ); + sprev->s_next = snext; + syncprov_drop_psearch( ss ); + continue; + } /* If we're sending results now, look for this op in old matches */ if ( !saveit ) { @@ -877,29 +950,6 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) } } -static void -syncprov_free_syncop( syncops *so ) -{ - syncres *sr, *srnext; - - ldap_pvt_thread_mutex_lock( &so->s_mutex ); - so->s_inuse--; - if ( so->s_inuse > 0 ) { - ldap_pvt_thread_mutex_unlock( &so->s_mutex ); - return; - } - ldap_pvt_thread_mutex_unlock( &so->s_mutex ); - filter_free( so->s_op->ors_filter ); - ch_free( so->s_op ); - ch_free( so->s_base.bv_val ); - for ( sr=so->s_res; sr; sr=srnext ) { - srnext = sr->s_next; - ch_free( sr ); - } - ldap_pvt_thread_mutex_destroy( &so->s_mutex ); - ch_free( so ); -} - static int syncprov_op_cleanup( Operation *op, SlapReply *rs ) { @@ -1000,39 +1050,6 @@ syncprov_op_response( Operation *op, SlapReply *rs ) return SLAP_CB_CONTINUE; } -static int -syncprov_op_abandon( Operation *op, SlapReply *rs ) -{ - slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; - syncprov_info_t *si = on->on_bi.bi_private; - syncops *so, *soprev; - - ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); - for ( so=si->si_ops, soprev = (syncops *)&si->si_ops; so; - soprev=so, so=so->s_next ) { - if ( so->s_op->o_connid == op->o_connid && - so->s_op->o_msgid == op->orn_msgid ) { - so->s_op->o_abandon = 1; - soprev->s_next = so->s_next; - break; - } - } - ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); - if ( so ) { - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - op->o_conn->c_n_ops_executing--; - op->o_conn->c_n_ops_completed++; - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); - /* Is this really a Cancel exop? */ - if ( op->o_tag != LDAP_REQ_ABANDON ) { - rs->sr_err = LDAP_CANCELLED; - send_ldap_result( so->s_op, rs ); - } - syncprov_free_syncop( so ); - } - return SLAP_CB_CONTINUE; -} - #if 0 /* We don't use a subentry to store the context CSN any more. But * we ought to expose the current context CSN as an operational attribute -- 2.39.5