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