#endif /* SLAPD_MONITOR */
Connection *conn = op->o_conn;
void *memctx;
+ ber_len_t memsiz;
ldap_pvt_thread_mutex_lock( &num_ops_mutex );
num_ops_initiated++;
* storage for most mallocs.
*/
#define SLAB_SIZE 1048576
+ memsiz = ber_len( op->o_ber ) * 32;
+ if ( SLAB_SIZE > memsiz ) memsiz = SLAB_SIZE;
+
if ( tag == LDAP_REQ_SEARCH ) {
- memctx = sl_mem_create( SLAB_SIZE, ctx );
+ memctx = sl_mem_create( memsiz, ctx );
ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, memctx );
op->o_tmpmemctx = memctx;
op->o_tmpmfuncs = &sl_mfuncs;
co_op_free:
+ ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, NULL );
slap_op_free( op );
no_co_op_free:
return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) );
}
-#ifdef SLAPD_BDB
-
/* This is like a ber_len */
static ber_len_t
entry_lenlen(ber_len_t len)
return len;
}
-/* Flatten an Entry into a buffer. The buffer is filled with just the
- * strings/bervals of all the entry components. Each field is preceded
- * by its length, encoded the way ber_put_len works. Every field is NUL
- * terminated. The entire buffer size is precomputed so that a single
- * malloc can be performed. The entry size is also recorded,
- * to aid in entry_decode.
- */
-int entry_encode(Entry *e, struct berval *bv)
+/* Add up the size of the entry for a flattened buffer */
+void entry_flatsize(Entry *e, ber_len_t *psiz, ber_len_t *plen, int norm)
{
ber_len_t siz = sizeof(Entry);
ber_len_t len, dnlen, ndnlen;
int i;
Attribute *a;
- unsigned char *ptr;
-#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx \"%s\"\n",
- (long) e->e_id, e->e_dn, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
- (long) e->e_id, e->e_dn, 0 );
-#endif
dnlen = e->e_name.bv_len;
- ndnlen = e->e_nname.bv_len;
- len = dnlen + ndnlen + 2; /* two trailing NUL bytes */
+ len = dnlen + 1; /* trailing NUL byte */
len += entry_lenlen(dnlen);
- len += entry_lenlen(ndnlen);
+ if (norm) {
+ ndnlen = e->e_nname.bv_len;
+ len += ndnlen + 1;
+ len += entry_lenlen(ndnlen);
+ }
for (a=e->e_attrs; a; a=a->a_next) {
/* For AttributeDesc, we only store the attr name */
siz += sizeof(Attribute);
}
len += entry_lenlen(i);
siz += sizeof(struct berval); /* empty berval at end */
- if (a->a_nvals != a->a_vals) {
+ if (norm && a->a_nvals != a->a_vals) {
for (i=0; a->a_nvals[i].bv_val; i++) {
siz += sizeof(struct berval);
len += a->a_nvals[i].bv_len + 1;
}
len += 1; /* NUL byte at end */
len += entry_lenlen(siz);
+ *psiz = siz;
+ *plen = len;
+}
+
+/* Flatten an Entry into a buffer. The buffer is filled with just the
+ * strings/bervals of all the entry components. Each field is preceded
+ * by its length, encoded the way ber_put_len works. Every field is NUL
+ * terminated. The entire buffer size is precomputed so that a single
+ * malloc can be performed. The entry size is also recorded,
+ * to aid in entry_decode.
+ */
+int entry_encode(Entry *e, struct berval *bv)
+{
+ ber_len_t siz = sizeof(Entry);
+ ber_len_t len, dnlen, ndnlen;
+ int i;
+ Attribute *a;
+ unsigned char *ptr;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx \"%s\"\n",
+ (long) e->e_id, e->e_dn, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
+ (long) e->e_id, e->e_dn, 0 );
+#endif
+ dnlen = e->e_name.bv_len;
+ ndnlen = e->e_nname.bv_len;
+
+ entry_flatsize( e, &siz, &len, 1 );
+
bv->bv_len = len;
bv->bv_val = ch_malloc(len);
ptr = (unsigned char *)bv->bv_val;
*e = x;
return 0;
}
-#endif
ValuesReturnFilter *p;
struct berval tmp;
ber_len_t len;
- BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc :
- (BER_MEMREALLOC_FN *)ch_realloc;
if ( vrf == NULL ) {
ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx );
simple_vrFilter2bv( op, p, &tmp );
fstr->bv_len += tmp.bv_len;
- fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+ fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
/*"("*/ "%s)", tmp.bv_val );
{
struct berval tmp;
ber_len_t len;
- BER_MEMREALLOC_FN *reallo = op->o_tmpmemctx ? sl_realloc :
- (BER_MEMREALLOC_FN *) ch_realloc;
if ( vrf == NULL ) {
ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx );
filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx );
fstr->bv_len += tmp.bv_len;
- fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+ fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
/* "(attr=" */ "%s*)",
filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp, op->o_tmpmemctx );
fstr->bv_len += tmp.bv_len + 1;
- fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+ fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
/* "(attr=[init]*[any*]" */ "%s*)",
filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx );
fstr->bv_len += tmp.bv_len;
- fstr->bv_val = reallo( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
+ fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
/* "(attr=[init*][any*]" */ "%s)",
LDAP_SLAPD_F (Entry *) str2entry LDAP_P(( char *s ));
LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len ));
+LDAP_SLAPD_F (void) entry_flatsize LDAP_P((
+ Entry *e, ber_len_t *siz, ber_len_t *len, int norm ));
LDAP_SLAPD_F (int) entry_decode LDAP_P(( struct berval *bv, Entry **e ));
LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv ));
LDAP_SLAPD_F (void *) sl_calloc LDAP_P(( ber_len_t nelem, ber_len_t size, void *ctx ));
LDAP_SLAPD_F (void) sl_free LDAP_P(( void *, void *ctx ));
LDAP_SLAPD_F (void *) sl_mem_create LDAP_P(( ber_len_t size, void *ctx ));
+LDAP_SLAPD_F (void *) sl_mark LDAP_P(( void *ctx ));
+LDAP_SLAPD_F (void) sl_release LDAP_P(( void *, void *ctx ));
/*
* starttls.c
computed_attr_context ctx;
AttributeName *anp;
#endif
+ void *mark = NULL;
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
rs->sr_entry->e_name.bv_val, op->ors_attrsonly ? " (attrsOnly)" : "", 0 );
#endif
+ mark = sl_mark( op->o_tmpmemctx );
+
if ( ! access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL ) )
{
#ifdef NEW_LOGGING
0, 0, 0 );
#endif
+ sl_release( mark, op->o_tmpmemctx );
return( 1 );
}
ber = op->o_res_ber;
else
#endif
- ber_init_w_nullc( ber, LBER_USE_DER );
+ {
+ ber_len_t siz, len;
+ struct berval bv;
+
+ entry_flatsize( rs->sr_entry, &siz, &len, 0 );
+ bv.bv_len = siz + len;
+ bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx );
+
+ ber_init2( ber, &bv, LBER_USE_DER );
+ ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx );
+ }
#ifdef LDAP_CONNECTIONLESS
if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
size = i * sizeof(char *) + k;
if ( size > 0 ) {
char *a_flags;
- e_flags = SLAP_CALLOC ( 1, i * sizeof(char *) + k );
+ e_flags = sl_calloc ( 1, i * sizeof(char *) + k, op->o_tmpmemctx );
if( e_flags == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "send_search_entry: conn %lu SLAP_CALLOC failed\n",
+ "send_search_entry: conn %lu sl_calloc failed\n",
op->o_connid : 0, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "send_search_entry: SLAP_CALLOC failed\n", 0, 0, 0 );
+ "send_search_entry: sl_calloc failed\n", 0, 0, 0 );
#endif
ber_free( ber, 1 );
* Reuse previous memory - we likely need less space
* for operational attributes
*/
- tmp = SLAP_REALLOC ( e_flags, i * sizeof(char *) + k );
+ tmp = sl_realloc( e_flags, i * sizeof(char *) + k, op->o_tmpmemctx );
if ( tmp == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
/* free e_flags */
if ( e_flags ) {
- free( e_flags );
+ sl_free( e_flags, op->o_tmpmemctx );
e_flags = NULL;
}
#endif
ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
+ sl_release( mark, op->o_tmpmemctx );
return( 1 );
}
0, 0, 0 );
#endif
+ sl_release( mark, op->o_tmpmemctx );
return -1;
}
rs->sr_nentries++;
rc = 0;
error_return:;
- if ( e_flags ) free( e_flags );
+ sl_release( mark, op->o_tmpmemctx );
+ if ( e_flags ) sl_free( e_flags, op->o_tmpmemctx );
return( rc );
}
if (sh->h_last + size >= sh->h_end ) {
#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, ERR,
- "sl_malloc: allocation of %lu bytes failed\n", (long)size, 0,0 );
+ LDAP_LOG( OPERATION, INFO,
+ "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 );
#else
- Debug( LDAP_DEBUG_ANY, "sl_malloc of %lu bytes failed\n",
- (long) size, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "sl_malloc of %lu bytes failed, using ch_malloc\n", (long)size, 0,0 );
#endif
- assert( 0 );
- exit( EXIT_FAILURE );
+ return ch_malloc( size );
}
new = sh->h_last;
*new++ = size - sizeof(ber_len_t);
if ( ptr == NULL ) return sl_malloc( size, ctx );
+ /* Not our memory? */
if ( ptr < sh->h_base || ptr >= sh->h_end ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, ERR,
- "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#endif
- assert( 0 );
- exit( EXIT_FAILURE );
+ return ch_realloc( ptr, size );
}
if ( size == 0 ) return NULL;
size += pad + sizeof( ber_len_t );
size &= ~pad;
- /* We always alloc a new block */
+ /* Never shrink blocks, always alloc if growth needed */
if (size <= p[-1]) {
- p[-1] = size;
new = p;
} else {
new = sl_malloc( size, ctx );
struct slab_heap *sh = ctx;
if ( ptr < sh->h_base || ptr >= sh->h_end ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, ERR,
- "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "sl_free: not mine: 0x%lx\n", (long)ptr, 0,0 );
-#endif
- assert( 0 );
- exit( EXIT_FAILURE );
+ ch_free( ptr );
}
}
+
+void
+sl_release( void *ptr, void *ctx )
+{
+ struct slab_heap *sh = ctx;
+
+ if ( ptr >= sh->h_base && ptr <= sh->h_end ) {
+ sh->h_last = ptr;
+ }
+}
+
+void *
+sl_mark( void *ctx )
+{
+ struct slab_heap *sh = ctx;
+
+ return sh->h_last;
+}