]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/id2entry.c
Fixup bdb_entry_release now that entry_decode uses two memory blocks
[openldap] / servers / slapd / back-ldbm / id2entry.c
1 /* id2entry.c - routines to deal with the id2entry index */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13
14 #include "slap.h"
15 #include "back-ldbm.h"
16
17 /*
18  * This routine adds (or updates) an entry on disk.
19  * The cache should already be updated. 
20  */
21
22 int
23 id2entry_add( Backend *be, Entry *e )
24 {
25         DBCache *db;
26         Datum           key, data;
27         int             len, rc, flags;
28
29         ldbm_datum_init( key );
30         ldbm_datum_init( data );
31
32 #ifdef NEW_LOGGING
33         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
34                    "id2entry_add: (%s)%ld\n", e->e_dn, e->e_id ));
35 #else
36         Debug( LDAP_DEBUG_TRACE, "=> id2entry_add( %ld, \"%s\" )\n", e->e_id,
37             e->e_dn, 0 );
38 #endif
39
40
41         if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT ))
42             == NULL ) {
43 #ifdef NEW_LOGGING
44                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
45                            "id2entry_add: could not open/create id2entry%s\n",
46                            LDBM_SUFFIX ));
47 #else
48                 Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
49                     LDBM_SUFFIX, 0, 0 );
50 #endif
51
52                 return( -1 );
53         }
54
55         key.dptr = (char *) &e->e_id;
56         key.dsize = sizeof(ID);
57
58         ldap_pvt_thread_mutex_lock( &entry2str_mutex );
59         data.dptr = entry2str( e, &len );
60         data.dsize = len + 1;
61
62         /* store it */
63         flags = LDBM_REPLACE;
64         rc = ldbm_cache_store( db, key, data, flags );
65
66         ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
67
68         ldbm_cache_close( be, db );
69
70 #ifdef NEW_LOGGING
71         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
72                    "id2entry_add: return %d\n", rc ));
73 #else
74         Debug( LDAP_DEBUG_TRACE, "<= id2entry_add %d\n", rc, 0, 0 );
75 #endif
76
77
78         return( rc );
79 }
80
81 int
82 id2entry_delete( Backend *be, Entry *e )
83 {
84         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
85         DBCache *db;
86         Datum           key;
87         int             rc;
88
89 #ifdef NEW_LOGGING
90         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
91                    "id2entry_delete: (%s)%ld\n", e->e_dn, e->e_id ));
92 #else
93         Debug(LDAP_DEBUG_TRACE, "=> id2entry_delete( %ld, \"%s\" )\n", e->e_id,
94             e->e_dn, 0 );
95 #endif
96
97
98 #ifdef notdef
99 #ifdef LDAP_RDWR_DEBUG
100         /* check for writer lock */
101         assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1);
102 #endif
103 #endif
104
105         ldbm_datum_init( key );
106
107         if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT ))
108                 == NULL ) {
109 #ifdef NEW_LOGGING
110                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
111                            "id2entry_delete: could not open/create id2entry%s\n",
112                            LDBM_SUFFIX ));
113 #else
114                 Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
115                     LDBM_SUFFIX, 0, 0 );
116 #endif
117
118                 return( -1 );
119         }
120
121         if ( cache_delete_entry( &li->li_cache, e ) != 0 ) {
122 #ifdef NEW_LOGGING
123                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
124                            "id2entry_delete: Could not delete (%s)%ld from cache\n",
125                            e->e_dn, e->e_id ));
126 #else
127                 Debug(LDAP_DEBUG_ANY, "could not delete %ld (%s) from cache\n",
128                     e->e_id, e->e_dn, 0 );
129 #endif
130
131         }
132
133         key.dptr = (char *) &e->e_id;
134         key.dsize = sizeof(ID);
135
136         rc = ldbm_cache_delete( db, key );
137
138         ldbm_cache_close( be, db );
139
140 #ifdef NEW_LOGGING
141         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
142                    "id2entry_delete: return %d\n", rc ));
143 #else
144         Debug( LDAP_DEBUG_TRACE, "<= id2entry_delete %d\n", rc, 0, 0 );
145 #endif
146
147         return( rc );
148 }
149
150 /* returns entry with reader/writer lock */
151 Entry *
152 id2entry_rw( Backend *be, ID id, int rw )
153 {
154         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
155         DBCache *db;
156         Datum           key, data;
157         Entry           *e;
158
159         ldbm_datum_init( key );
160         ldbm_datum_init( data );
161
162 #ifdef NEW_LOGGING
163         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
164                    "id2entry_rw: %s (%ld)\n",
165                    rw ? "write" : "read", id ));
166 #else
167         Debug( LDAP_DEBUG_TRACE, "=> id2entry_%s( %ld )\n",
168                 rw ? "w" : "r", id, 0 );
169 #endif
170
171
172         if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
173 #ifdef NEW_LOGGING
174                 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
175                            "id2entry_rw: %s (%ld) 0x%lx (cache).\n",
176                            rw ? "write" : "read", id, (unsigned long)e ));
177 #else
178                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n",
179                         rw ? "w" : "r", id, (unsigned long) e );
180 #endif
181
182                 return( e );
183         }
184
185         if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT ))
186                 == NULL ) {
187 #ifdef NEW_LOGGING
188                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
189                            "id2entry_rw: could not open id2entry%s\n", LDBM_SUFFIX ));
190 #else
191                 Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n",
192                     LDBM_SUFFIX, 0, 0 );
193 #endif
194
195                 return( NULL );
196         }
197
198         key.dptr = (char *) &id;
199         key.dsize = sizeof(ID);
200
201         data = ldbm_cache_fetch( db, key );
202
203         if ( data.dptr == NULL ) {
204 #ifdef NEW_LOGGING
205                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
206                            "id2entry_rw: (%ld) not found\n", id ));
207 #else
208                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) not found\n",
209                         rw ? "w" : "r", id, 0 );
210 #endif
211
212                 ldbm_cache_close( be, db );
213                 return( NULL );
214         }
215
216         e = str2entry( data.dptr );
217         ldbm_datum_free( db->dbc_db, data );
218         ldbm_cache_close( be, db );
219
220         if ( e == NULL ) {
221 #ifdef NEW_LOGGING
222                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
223                            "id2entry_rw: %s of %ld failed\n",
224                            rw ? "write" : "read", id ));
225 #else
226                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (failed)\n",
227                         rw ? "w" : "r", id, 0 );
228 #endif
229
230                 return( NULL );
231         }
232
233         e->e_id = id;
234
235         if( cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) {
236                 entry_free( e );
237
238                 /* XXX this is a kludge.
239                  * maybe the entry got added underneath us
240                  * There are many underlying race condtions in the cache/disk code.
241                  */
242                 if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
243 #ifdef NEW_LOGGING
244                         LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
245                                    "id2entry_rw: %s of %ld 0x%lx (cache)\n",
246                                    rw ? "write" : "read", id, (unsigned long)e ));
247 #else
248                         Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n",
249                                 rw ? "w" : "r", id, (unsigned long) e );
250 #endif
251
252                         return( e );
253                 }
254
255 #ifdef NEW_LOGGING
256                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
257                            "id2entry_rw: %s of %ld (cache add failed)\n",
258                            rw ? "write" : "read", id ));
259 #else
260                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (cache add failed)\n",
261                         rw ? "w" : "r", id, 0 );
262 #endif
263
264                 return NULL;
265         }
266
267 #ifdef NEW_LOGGING
268         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
269                    "id2entry_rw: %s of %ld 0x%lx (disk)\n",
270                    rw ? "write" : "read", id, (unsigned long)e ));
271 #else
272         Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (disk)\n",
273                 rw ? "w" : "r", id, (unsigned long) e );
274 #endif
275
276         /* marks the entry as committed, so it will get added to the cache
277          * when the lock is released */
278         cache_entry_commit( e );
279
280         return( e );
281 }