/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2000-2012 The OpenLDAP Foundation.
+ * Copyright 2000-2014 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
if (rc == MDB_SUCCESS) {
rc = mdb_entry_encode( op, e, &data, &ec );
if( rc != LDAP_SUCCESS )
- return LDAP_OTHER;
+ return rc;
}
if (rc) {
/* Was there a hole from slapadd? */
MDB_val *data )
{
MDB_val key;
+ int rc;
key.mv_data = &id;
key.mv_size = sizeof(ID);
/* fetch it */
- return mdb_cursor_get( mc, &key, data, MDB_SET );
+ rc = mdb_cursor_get( mc, &key, data, MDB_SET );
+ /* stubs from missing parents - DB is actually invalid */
+ if ( rc == MDB_SUCCESS && !data->mv_size )
+ rc = MDB_NOTFOUND;
+ return rc;
}
int mdb_id2entry(
return MDB_SUCCESS;
}
}
+ /* stubs from missing parents - DB is actually invalid */
+ if ( rc == MDB_SUCCESS && !data.mv_size )
+ rc = MDB_NOTFOUND;
if ( rc ) return rc;
- rc = mdb_entry_decode( op, &data, e );
+ rc = mdb_entry_decode( op, mdb_cursor_txn( mc ), &data, e );
if ( rc ) return rc;
(*e)->e_id = id;
Entry *e
)
{
+ if ( !e )
+ return 0;
if ( e->e_private ) {
if ( op->o_hdr ) {
op->o_tmpfree( e->e_nname.bv_val, op->o_tmpmemctx );
/* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE,
SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */
- mdb_entry_return( op, e );
- if ( slapMode == SLAP_SERVER_MODE ) {
+ if ( slapMode & SLAP_SERVER_MODE ) {
OpExtra *oex;
LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
if ( oex->oe_key == mdb ) {
+ mdb_entry_return( op, e );
moi = (mdb_op_info *)oex;
/* If it was setup by entry_get we should probably free it */
if ( moi->moi_flag & MOI_FREEIT ) {
break;
}
}
+ } else {
+ mdb_entry_return( op, e );
}
return 0;
txn = moi->moi_txn;
/* can we find entry */
- rc = mdb_dn2entry( op, txn, NULL, ndn, &e, 0 );
+ rc = mdb_dn2entry( op, txn, NULL, ndn, &e, NULL, 0 );
switch( rc ) {
case MDB_NOTFOUND:
case 0:
return_results:
if( rc != LDAP_SUCCESS ) {
/* free entry */
- if ( e )
- mdb_entry_return( op, e );
-
- if (moi->moi_ref == 1) {
- LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
- mdb_txn_reset( txn );
- op->o_tmpfree( moi, op->o_tmpmemctx );
- }
+ mdb_entry_release( op, e, rw );
} else {
*ent = e;
}
}
}
+extern MDB_txn *mdb_tool_txn;
+
int
mdb_opinfo_get( Operation *op, struct mdb_info *mdb, int rdonly, mdb_op_info **moip )
{
}
moi->moi_ref++;
if ( !moi->moi_txn ) {
- rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &moi->moi_txn );
- if (rc) {
- Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
- mdb_strerror(rc), rc, 0 );
+ if (( slapMode & SLAP_TOOL_MODE ) && mdb_tool_txn ) {
+ moi->moi_txn = mdb_tool_txn;
+ } else {
+ rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &moi->moi_txn );
+ if (rc) {
+ Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
+ mdb_strerror(rc), rc, 0 );
+ }
+ return rc;
}
- return rc;
}
return 0;
}
/* OK, this is a reader */
if ( !moi->moi_txn ) {
+ if (( slapMode & SLAP_TOOL_MODE ) && mdb_tool_txn ) {
+ moi->moi_txn = mdb_tool_txn;
+ goto ok;
+ }
if ( !ctx ) {
/* Shouldn't happen unless we're single-threaded */
rc = mdb_txn_begin( mdb->mi_dbenv, NULL, MDB_RDONLY, &moi->moi_txn );
}
moi->moi_flag |= MOI_READER;
}
+ok:
if ( moi->moi_ref < 1 ) {
moi->moi_ref = 0;
}
if ( renew ) {
- mdb_txn_renew( moi->moi_txn );
+ rc = mdb_txn_renew( moi->moi_txn );
+ assert(!rc);
}
moi->moi_ref++;
if ( *moip != moi )
* entry, and the e_ocflags. It then contains a list of integers for each
* attribute. For each attribute the first integer gives the index of the
* matching AttributeDescription, followed by the number of values in the
- * attribute. If the high bit is set, the attribute also has normalized
+ * attribute. If the high bit of the attr index is set, the attribute's
+ * values are already sorted.
+ * If the high bit of numvals is set, the attribute also has normalized
* values present. (Note - a_numvals is an unsigned int, so this means
* it's possible to receive an attribute that we can't encode due to size
* overflow. In practice, this should not be an issue.) Then the length
ptr = (unsigned char *)(lp + eh->offset);
for (a=e->e_attrs; a; a=a->a_next) {
- *lp++ = mdb->mi_adxs[a->a_desc->ad_index];
+ if (!a->a_desc->ad_index)
+ return LDAP_UNDEFINED_TYPE;
+ l = mdb->mi_adxs[a->a_desc->ad_index];
+ if (a->a_flags & SLAP_ATTR_SORTED_VALS)
+ l |= HIGH_BIT;
+ *lp++ = l;
l = a->a_numvals;
if (a->a_nvals != a->a_vals)
l |= HIGH_BIT;
* structure. Attempting to do so will likely corrupt memory.
*/
-int mdb_entry_decode(Operation *op, MDB_val *data, Entry **e)
+int mdb_entry_decode(Operation *op, MDB_txn *txn, MDB_val *data, Entry **e)
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
int i, j, nattrs, nvals;
for (;nattrs>0; nattrs--) {
int have_nval = 0;
- a->a_desc = mdb->mi_ads[*lp++];
a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
+ i = *lp++;
+ if (i & HIGH_BIT) {
+ i ^= HIGH_BIT;
+ a->a_flags |= SLAP_ATTR_SORTED_VALS;
+ }
+ if (i > mdb->mi_numads) {
+ rc = mdb_ad_read(mdb, txn);
+ if (rc)
+ return rc;
+ if (i > mdb->mi_numads) {
+ Debug( LDAP_DEBUG_ANY,
+ "mdb_entry_decode: attribute index %d not recognized\n",
+ i, 0, 0 );
+ return LDAP_OTHER;
+ }
+ }
+ a->a_desc = mdb->mi_ads[i];
a->a_numvals = *lp++;
if (a->a_numvals & HIGH_BIT) {
a->a_numvals ^= HIGH_BIT;
a->a_nvals = a->a_vals;
}
/* FIXME: This is redundant once a sorted entry is saved into the DB */
- if ( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
+ if (( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL )
+ && !(a->a_flags & SLAP_ATTR_SORTED_VALS)) {
rc = slap_sort_vals( (Modifications *)a, &text, &j, NULL );
if ( rc == LDAP_SUCCESS ) {
a->a_flags |= SLAP_ATTR_SORTED_VALS;