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