static void tdb_increment_seqnum | ( | struct tdb_context * | tdb | ) | [static] |
参照先 tdb_context::flags・tdb・tdb_brlock()・tdb_ofs_read()・tdb_ofs_write().
参照元 tdb_delete_hash()・tdb_store().
00038 { 00039 tdb_off_t seqnum=0; 00040 00041 if (!(tdb->flags & TDB_SEQNUM)) { 00042 return; 00043 } 00044 00045 if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) { 00046 return; 00047 } 00048 00049 /* we ignore errors from this, as we have no sane way of 00050 dealing with them. 00051 */ 00052 tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); 00053 seqnum++; 00054 tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); 00055 00056 tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1); 00057 }
static tdb_off_t tdb_find | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
u32 | hash, | |||
struct list_struct * | r | |||
) | [static] |
参照先 TDB_DATA::dsize・list_struct::full_hash・list_struct::key_len・tdb・TDB_ERR_NOEXIST・tdb_key_compare()・tdb_ofs_read()・tdb_parse_data()・tdb_rec_read().
参照元 tdb_delete_hash()・tdb_find_lock_hash()・tdb_update_hash().
00068 { 00069 tdb_off_t rec_ptr; 00070 00071 /* read in the hash top */ 00072 if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) 00073 return 0; 00074 00075 /* keep looking until we find the right record */ 00076 while (rec_ptr) { 00077 if (tdb_rec_read(tdb, rec_ptr, r) == -1) 00078 return 0; 00079 00080 if (!TDB_DEAD(r) && hash==r->full_hash 00081 && key.dsize==r->key_len 00082 && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), 00083 r->key_len, tdb_key_compare, 00084 NULL) == 0) { 00085 return rec_ptr; 00086 } 00087 rec_ptr = r->next; 00088 } 00089 return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); 00090 }
tdb_off_t tdb_find_lock_hash | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
u32 | hash, | |||
int | locktype, | |||
struct list_struct * | rec | |||
) |
参照先 tdb・tdb_find()・tdb_lock()・tdb_unlock().
参照元 tdb_delete_hash()・tdb_exists_hash()・tdb_fetch()・tdb_nextkey()・tdb_parse_record().
00095 { 00096 u32 rec_ptr; 00097 00098 if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) 00099 return 0; 00100 if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) 00101 tdb_unlock(tdb, BUCKET(hash), locktype); 00102 return rec_ptr; 00103 }
static int tdb_update_hash | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
u32 | hash, | |||
TDB_DATA | dbuf | |||
) | [static] |
参照先 TDB_DATA::dptr・TDB_DATA::dsize・tdb_context::ecode・tdb_context::methods・list_struct::rec_len・tdb・tdb_find()・tdb_rec_write()・TDB_SUCCESS・tdb_methods::tdb_write.
参照元 tdb_store().
00111 { 00112 struct list_struct rec; 00113 tdb_off_t rec_ptr; 00114 00115 /* find entry */ 00116 if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) 00117 return -1; 00118 00119 /* must be long enough key, data and tailer */ 00120 if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) { 00121 tdb->ecode = TDB_SUCCESS; /* Not really an error */ 00122 return -1; 00123 } 00124 00125 if (tdb->methods->tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, 00126 dbuf.dptr, dbuf.dsize) == -1) 00127 return -1; 00128 00129 if (dbuf.dsize != rec.data_len) { 00130 /* update size */ 00131 rec.data_len = dbuf.dsize; 00132 return tdb_rec_write(tdb, rec_ptr, &rec); 00133 } 00134 00135 return 0; 00136 }
TDB_DATA tdb_fetch | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
参照先 TDB_DATA::dptr・tdb_context::hash_fn・tdb・tdb_alloc_read()・tdb_find_lock_hash()・tdb_null・tdb_unlock().
参照元 _reg_perfcount_assemble_global()・_reg_perfcount_get_64()・_reg_perfcount_get_counter_data()・_reg_perfcount_get_counter_info()・_reg_perfcount_get_instance_info()・_reg_perfcount_get_numinst()・_reg_perfcount_multi_sz_from_tdb()・add_aliasmem()・add_fd_to_close_entry()・addrec_db()・brl_get_locks_internal()・cache_retrieve_response()・compare_db()・decrement_windows_lock_ref_count()・delete_printer_driver()・dump_tdb()・enum_group_mapping()・find_name_on_wins_subnet()・first_record()・gencache_get()・gencache_iterate()・get_a_printer_2()・get_a_printer_driver_3()・get_eventlog_record()・get_group_map_from_gid()・get_group_map_from_ntname()・get_group_map_from_sid()・get_jobs_changed_data()・get_ntforms()・get_posix_pending_close_entries()・get_privileges()・get_queue_status()・get_share_mode_lock()・get_stored_queue_info()・get_updating_pid()・get_windows_lock_ref_count()・group_map_remove()・idmap_cache_map_id()・idmap_cache_map_sid()・idmap_tdb_id_to_sid()・idmap_tdb_remove_mapping()・idmap_tdb_set_mapping()・idmap_tdb_sid_to_id()・increment_windows_lock_ref_count()・lang_msg()・login_cache_read()・make_way_for_eventlogs()・message_send_pid_internal()・messages_pending_for_pid()・move_rec()・netsamlogon_cache_get()・next_record()・one_alias_membership()・pjob_store()・pjobid_to_rap()・print_job_find()・print_queue_status()・rap_jobid_delete()・rap_to_pjobid()・reduce_windows_lock_ref_count()・reg_perfcount_get_base_index()・register_message_flags()・remove_from_jobs_changed()・retrieve_all_messages()・secrets_fetch()・session_yield()・set_driver_init_2()・show_tdb()・smb_change_share_mode_entry()・smb_create_share_mode_entry_ex()・smb_delete_share_mode_entry()・smb_get_share_mode_entries()・tdb_append()・tdb_fetch_bystring()・tdb_fetch_int32_byblob()・tdb_fetch_uint32_byblob()・tdb_hnd_subscript()・tdbsam_convert()・tdbsam_getsampwent()・tdbsam_getsampwnam()・tdbsam_getsampwrid()・upgrade_to_version_3()・wcache_cached_creds_exist()・wcache_fetch_raw()・wcache_remove_oldest_cached_creds().
00145 { 00146 tdb_off_t rec_ptr; 00147 struct list_struct rec; 00148 TDB_DATA ret; 00149 u32 hash; 00150 00151 /* find which hash bucket it is in */ 00152 hash = tdb->hash_fn(&key); 00153 if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) 00154 return tdb_null; 00155 00156 ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, 00157 rec.data_len); 00158 ret.dsize = rec.data_len; 00159 tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); 00160 return ret; 00161 }
int tdb_parse_record | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
int(*)(TDB_DATA key, TDB_DATA data, void *private_data) | parser, | |||
void * | private_data | |||
) |
参照先 tdb_context::hash_fn・tdb・TDB_ERR_NOEXIST・tdb_find_lock_hash()・tdb_parse_data()・tdb_unlock().
参照元 get_delete_on_close_flag().
00183 { 00184 tdb_off_t rec_ptr; 00185 struct list_struct rec; 00186 int ret; 00187 u32 hash; 00188 00189 /* find which hash bucket it is in */ 00190 hash = tdb->hash_fn(&key); 00191 00192 if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { 00193 return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); 00194 } 00195 00196 ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, 00197 rec.data_len, parser, private_data); 00198 00199 tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); 00200 00201 return ret; 00202 }
static int tdb_exists_hash | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
u32 | hash | |||
) | [static] |
参照先 list_struct::full_hash・tdb・tdb_find_lock_hash()・tdb_unlock().
参照元 tdb_exists()・tdb_store().
00211 { 00212 struct list_struct rec; 00213 00214 if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) 00215 return 0; 00216 tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); 00217 return 1; 00218 }
int tdb_exists | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
参照先 tdb_context::hash_fn・tdb・tdb_exists_hash().
参照元 print_job_exists()・py_tdb_hnd_has_key().
00221 { 00222 u32 hash = tdb->hash_fn(&key); 00223 return tdb_exists_hash(tdb, key, hash); 00224 }
int tdb_do_delete | ( | struct tdb_context * | tdb, | |
tdb_off_t | rec_ptr, | |||
struct list_struct * | rec | |||
) |
参照先 list_struct::full_hash・last_ptr・list_struct::magic・list_struct::next・tdb_context::read_only・tdb・tdb_free()・tdb_ofs_read()・tdb_ofs_write()・tdb_rec_read()・tdb_rec_write()・tdb_write_lock_record()・tdb_write_unlock_record()・tdb_context::traverse_read.
参照元 tdb_delete_hash()・tdb_next_lock()・tdb_purge_dead().
00228 { 00229 tdb_off_t last_ptr, i; 00230 struct list_struct lastrec; 00231 00232 if (tdb->read_only || tdb->traverse_read) return -1; 00233 00234 if (tdb_write_lock_record(tdb, rec_ptr) == -1) { 00235 /* Someone traversing here: mark it as dead */ 00236 rec->magic = TDB_DEAD_MAGIC; 00237 return tdb_rec_write(tdb, rec_ptr, rec); 00238 } 00239 if (tdb_write_unlock_record(tdb, rec_ptr) != 0) 00240 return -1; 00241 00242 /* find previous record in hash chain */ 00243 if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) 00244 return -1; 00245 for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) 00246 if (tdb_rec_read(tdb, i, &lastrec) == -1) 00247 return -1; 00248 00249 /* unlink it: next ptr is at start of record. */ 00250 if (last_ptr == 0) 00251 last_ptr = TDB_HASH_TOP(rec->full_hash); 00252 if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) 00253 return -1; 00254 00255 /* recover the space */ 00256 if (tdb_free(tdb, rec_ptr, rec) == -1) 00257 return -1; 00258 return 0; 00259 }
static int tdb_count_dead | ( | struct tdb_context * | tdb, | |
u32 | hash | |||
) | [static] |
参照先 list_struct::magic・list_struct::next・tdb・tdb_ofs_read()・tdb_rec_read().
参照元 tdb_delete_hash().
00262 { 00263 int res = 0; 00264 tdb_off_t rec_ptr; 00265 struct list_struct rec; 00266 00267 /* read in the hash top */ 00268 if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) 00269 return 0; 00270 00271 while (rec_ptr) { 00272 if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) 00273 return 0; 00274 00275 if (rec.magic == TDB_DEAD_MAGIC) { 00276 res += 1; 00277 } 00278 rec_ptr = rec.next; 00279 } 00280 return res; 00281 }
static int tdb_purge_dead | ( | struct tdb_context * | tdb, | |
u32 | hash | |||
) | [static] |
参照先 list_struct::magic・list_struct::next・tdb・tdb_do_delete()・tdb_lock()・tdb_ofs_read()・tdb_rec_read()・tdb_unlock().
参照元 tdb_delete_hash()・tdb_store().
00287 { 00288 int res = -1; 00289 struct list_struct rec; 00290 tdb_off_t rec_ptr; 00291 00292 if (tdb_lock(tdb, -1, F_WRLCK) == -1) { 00293 return -1; 00294 } 00295 00296 /* read in the hash top */ 00297 if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) 00298 goto fail; 00299 00300 while (rec_ptr) { 00301 tdb_off_t next; 00302 00303 if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) { 00304 goto fail; 00305 } 00306 00307 next = rec.next; 00308 00309 if (rec.magic == TDB_DEAD_MAGIC 00310 && tdb_do_delete(tdb, rec_ptr, &rec) == -1) { 00311 goto fail; 00312 } 00313 rec_ptr = next; 00314 } 00315 res = 0; 00316 fail: 00317 tdb_unlock(tdb, -1, F_WRLCK); 00318 return res; 00319 }
static int tdb_delete_hash | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
u32 | hash | |||
) | [static] |
参照先 list_struct::full_hash・list_struct::magic・tdb_context::max_dead_records・tdb・tdb_count_dead()・TDB_DEBUG_WARNING・tdb_do_delete()・tdb_find()・tdb_find_lock_hash()・tdb_increment_seqnum()・tdb_lock()・tdb_purge_dead()・tdb_rec_write()・tdb_unlock().
参照元 tdb_delete()・tdb_store().
00323 { 00324 tdb_off_t rec_ptr; 00325 struct list_struct rec; 00326 int ret; 00327 00328 if (tdb->max_dead_records != 0) { 00329 00330 /* 00331 * Allow for some dead records per hash chain, mainly for 00332 * tdb's with a very high create/delete rate like locking.tdb. 00333 */ 00334 00335 if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) 00336 return -1; 00337 00338 if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) { 00339 /* 00340 * Don't let the per-chain freelist grow too large, 00341 * delete all existing dead records 00342 */ 00343 tdb_purge_dead(tdb, hash); 00344 } 00345 00346 if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { 00347 tdb_unlock(tdb, BUCKET(hash), F_WRLCK); 00348 return -1; 00349 } 00350 00351 /* 00352 * Just mark the record as dead. 00353 */ 00354 rec.magic = TDB_DEAD_MAGIC; 00355 ret = tdb_rec_write(tdb, rec_ptr, &rec); 00356 } 00357 else { 00358 if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, 00359 &rec))) 00360 return -1; 00361 00362 ret = tdb_do_delete(tdb, rec_ptr, &rec); 00363 } 00364 00365 if (ret == 0) { 00366 tdb_increment_seqnum(tdb); 00367 } 00368 00369 if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) 00370 TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); 00371 return ret; 00372 }
int tdb_delete | ( | struct tdb_context * | tdb, | |
TDB_DATA | key | |||
) |
参照先 tdb_context::hash_fn・tdb・tdb_delete_hash().
参照元 addrec_db()・byte_range_lock_destructor()・cache_cleanup_response()・cache_store_response()・convert_fn()・count_fn()・cull_traverse()・del_a_printer()・del_aliasmem()・del_driver_init()・delete_a_form()・delete_close_entries()・delete_pipe_opendb()・delete_printer_driver()・delete_tdb()・delete_windows_lock_ref_count()・do_delete_fn()・gencache_del()・gencache_get()・group_map_remove()・idmap_cache_del()・idmap_cache_map_id()・idmap_cache_map_sid()・idmap_tdb_remove_mapping()・idmap_tdb_set_mapping()・login_cache_delentry()・merge_test()・message_notify()・netsamlogon_cache_get()・netsamlogon_clear_cached_user()・normalize_printers_fn()・pjob_delete()・rap_jobid_delete()・remove_name_from_wins_namelist()・sec_desc_upg_fn()・secrets_delete()・session_claim()・session_yield()・set_updating_pid()・share_mode_lock_destructor()・smb_delete_share_mode_entry()・tdb_ass_subscript()・tdb_delete_bystring()・tdb_delete_samacct_only()・tdb_trans_delete()・tdb_traverse_delete_fn()・tdbsam_delete_sam_account()・traverse_fn()・traverse_fn_cleanup()・upgrade_to_version_3()・wcache_delete()・wcache_remove_oldest_cached_creds()・yield_connection().
00375 { 00376 u32 hash = tdb->hash_fn(&key); 00377 return tdb_delete_hash(tdb, key, hash); 00378 }
static tdb_off_t tdb_find_dead | ( | struct tdb_context * | tdb, | |
u32 | hash, | |||
struct list_struct * | r, | |||
tdb_len_t | length | |||
) | [static] |
参照先 list_struct::next・list_struct::rec_len・tdb・tdb_ofs_read()・tdb_rec_read().
参照元 tdb_store().
00385 { 00386 tdb_off_t rec_ptr; 00387 00388 /* read in the hash top */ 00389 if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) 00390 return 0; 00391 00392 /* keep looking until we find the right record */ 00393 while (rec_ptr) { 00394 if (tdb_rec_read(tdb, rec_ptr, r) == -1) 00395 return 0; 00396 00397 if (TDB_DEAD(r) && r->rec_len >= length) { 00398 /* 00399 * First fit for simple coding, TODO: change to best 00400 * fit 00401 */ 00402 return rec_ptr; 00403 } 00404 rec_ptr = r->next; 00405 } 00406 return 0; 00407 }
int tdb_store | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
TDB_DATA | dbuf, | |||
int | flag | |||
) |
参照先 list_struct::data_len・TDB_DATA::dptr・TDB_DATA::dsize・tdb_context::ecode・list_struct::full_hash・tdb_context::hash_fn・list_struct::key_len・list_struct::magic・list_struct::next・tdb_context::read_only・tdb・tdb_allocate()・tdb_delete_hash()・TDB_ERR_EXISTS・TDB_ERR_NOEXIST・TDB_ERR_OOM・TDB_ERR_RDONLY・tdb_exists_hash()・tdb_find_dead()・tdb_increment_seqnum()・tdb_lock()・tdb_ofs_read()・tdb_ofs_write()・tdb_purge_dead()・tdb_rec_write()・TDB_SUCCESS・tdb_unlock()・tdb_update_hash()・tdb_context::traverse_read.
参照元 add_a_printer_driver_3()・add_aliasmem()・add_fd_to_close_entry()・add_mapping_entry()・addrec_db()・byte_range_lock_destructor()・cache_store_response()・centry_end()・claim_connection()・convert_fn()・copy_fn()・decrement_windows_lock_ref_count()・del_aliasmem()・gencache_set()・idmap_cache_set()・idmap_cache_set_negative_id()・idmap_cache_set_negative_sid()・idmap_tdb_set_mapping()・increment_windows_lock_ref_count()・insert_tdb()・load_msg()・login_cache_write()・merge_test()・message_send_pid_internal()・move_rec()・normalize_printers_fn()・pjob_store()・pjobid_to_rap()・print_queue_update_internal()・reduce_windows_lock_ref_count()・regdb_store_keys_internal()・register_message_flags()・remove_from_jobs_changed()・retrieve_all_messages()・seen_insert()・session_claim()・set_privileges()・set_updating_pid()・share_mode_lock_destructor()・smb_change_share_mode_entry()・smb_create_share_mode_entry_ex()・smb_delete_share_mode_entry()・store_or_replace_wins_namerec()・store_pipe_opendb()・store_queue_struct()・store_tdb()・tdb_append()・tdb_ass_subscript()・tdb_store_bystring()・tdb_store_int32_byblob()・tdb_store_uint32_byblob()・tdb_trans_store()・tdb_update_ridrec_only()・tdb_update_samacct_only()・tdbsam_convert()・traverse_fn()・unexpected_packet()・update_a_printer_2()・update_driver_init_2()・upgrade_to_version_3()・write_eventlog_tdb()・write_ntforms().
00415 { 00416 struct list_struct rec; 00417 u32 hash; 00418 tdb_off_t rec_ptr; 00419 char *p = NULL; 00420 int ret = -1; 00421 00422 if (tdb->read_only || tdb->traverse_read) { 00423 tdb->ecode = TDB_ERR_RDONLY; 00424 return -1; 00425 } 00426 00427 /* find which hash bucket it is in */ 00428 hash = tdb->hash_fn(&key); 00429 if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) 00430 return -1; 00431 00432 /* check for it existing, on insert. */ 00433 if (flag == TDB_INSERT) { 00434 if (tdb_exists_hash(tdb, key, hash)) { 00435 tdb->ecode = TDB_ERR_EXISTS; 00436 goto fail; 00437 } 00438 } else { 00439 /* first try in-place update, on modify or replace. */ 00440 if (tdb_update_hash(tdb, key, hash, dbuf) == 0) { 00441 goto done; 00442 } 00443 if (tdb->ecode == TDB_ERR_NOEXIST && 00444 flag == TDB_MODIFY) { 00445 /* if the record doesn't exist and we are in TDB_MODIFY mode then 00446 we should fail the store */ 00447 goto fail; 00448 } 00449 } 00450 /* reset the error code potentially set by the tdb_update() */ 00451 tdb->ecode = TDB_SUCCESS; 00452 00453 /* delete any existing record - if it doesn't exist we don't 00454 care. Doing this first reduces fragmentation, and avoids 00455 coalescing with `allocated' block before it's updated. */ 00456 if (flag != TDB_INSERT) 00457 tdb_delete_hash(tdb, key, hash); 00458 00459 /* Copy key+value *before* allocating free space in case malloc 00460 fails and we are left with a dead spot in the tdb. */ 00461 00462 if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { 00463 tdb->ecode = TDB_ERR_OOM; 00464 goto fail; 00465 } 00466 00467 memcpy(p, key.dptr, key.dsize); 00468 if (dbuf.dsize) 00469 memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); 00470 00471 if (tdb->max_dead_records != 0) { 00472 /* 00473 * Allow for some dead records per hash chain, look if we can 00474 * find one that can hold the new record. We need enough space 00475 * for key, data and tailer. If we find one, we don't have to 00476 * consult the central freelist. 00477 */ 00478 rec_ptr = tdb_find_dead( 00479 tdb, hash, &rec, 00480 key.dsize + dbuf.dsize + sizeof(tdb_off_t)); 00481 00482 if (rec_ptr != 0) { 00483 rec.key_len = key.dsize; 00484 rec.data_len = dbuf.dsize; 00485 rec.full_hash = hash; 00486 rec.magic = TDB_MAGIC; 00487 if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 00488 || tdb->methods->tdb_write( 00489 tdb, rec_ptr + sizeof(rec), 00490 p, key.dsize + dbuf.dsize) == -1) { 00491 goto fail; 00492 } 00493 goto done; 00494 } 00495 } 00496 00497 /* 00498 * We have to allocate some space from the freelist, so this means we 00499 * have to lock it. Use the chance to purge all the DEAD records from 00500 * the hash chain under the freelist lock. 00501 */ 00502 00503 if (tdb_lock(tdb, -1, F_WRLCK) == -1) { 00504 goto fail; 00505 } 00506 00507 if ((tdb->max_dead_records != 0) 00508 && (tdb_purge_dead(tdb, hash) == -1)) { 00509 tdb_unlock(tdb, -1, F_WRLCK); 00510 goto fail; 00511 } 00512 00513 /* we have to allocate some space */ 00514 rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec); 00515 00516 tdb_unlock(tdb, -1, F_WRLCK); 00517 00518 if (rec_ptr == 0) { 00519 goto fail; 00520 } 00521 00522 /* Read hash top into next ptr */ 00523 if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) 00524 goto fail; 00525 00526 rec.key_len = key.dsize; 00527 rec.data_len = dbuf.dsize; 00528 rec.full_hash = hash; 00529 rec.magic = TDB_MAGIC; 00530 00531 /* write out and point the top of the hash chain at it */ 00532 if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 00533 || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 00534 || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { 00535 /* Need to tdb_unallocate() here */ 00536 goto fail; 00537 } 00538 00539 done: 00540 ret = 0; 00541 fail: 00542 if (ret == 0) { 00543 tdb_increment_seqnum(tdb); 00544 } 00545 00546 SAFE_FREE(p); 00547 tdb_unlock(tdb, BUCKET(hash), F_WRLCK); 00548 return ret; 00549 }
int tdb_append | ( | struct tdb_context * | tdb, | |
TDB_DATA | key, | |||
TDB_DATA | new_dbuf | |||
) |
参照先 TDB_DATA::dptr・TDB_DATA::dsize・tdb_context::ecode・failed・tdb_context::hash_fn・tdb・TDB_ERR_OOM・tdb_fetch()・tdb_lock()・tdb_store()・tdb_unlock().
参照元 add_to_jobs_changed()・addrec_db()・message_send_pid_internal().
00554 { 00555 u32 hash; 00556 TDB_DATA dbuf; 00557 int ret = -1; 00558 00559 /* find which hash bucket it is in */ 00560 hash = tdb->hash_fn(&key); 00561 if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) 00562 return -1; 00563 00564 dbuf = tdb_fetch(tdb, key); 00565 00566 if (dbuf.dptr == NULL) { 00567 dbuf.dptr = (char *)malloc(new_dbuf.dsize); 00568 } else { 00569 char *new_dptr = (char *)realloc(dbuf.dptr, 00570 dbuf.dsize + new_dbuf.dsize); 00571 if (new_dptr == NULL) { 00572 free(dbuf.dptr); 00573 } 00574 dbuf.dptr = new_dptr; 00575 } 00576 00577 if (dbuf.dptr == NULL) { 00578 tdb->ecode = TDB_ERR_OOM; 00579 goto failed; 00580 } 00581 00582 memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize); 00583 dbuf.dsize += new_dbuf.dsize; 00584 00585 ret = tdb_store(tdb, key, dbuf, 0); 00586 00587 failed: 00588 tdb_unlock(tdb, BUCKET(hash), F_WRLCK); 00589 SAFE_FREE(dbuf.dptr); 00590 return ret; 00591 }
const char* tdb_name | ( | struct tdb_context * | tdb | ) |
int tdb_fd | ( | struct tdb_context * | tdb | ) |
tdb_log_func tdb_log_fn | ( | struct tdb_context * | tdb | ) |
int tdb_get_seqnum | ( | struct tdb_context * | tdb | ) |
参照先 tdb・tdb_ofs_read().
参照元 notify_init()・notify_load().
00634 { 00635 tdb_off_t seqnum=0; 00636 00637 tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); 00638 return seqnum; 00639 }
int tdb_hash_size | ( | struct tdb_context * | tdb | ) |
size_t tdb_map_size | ( | struct tdb_context * | tdb | ) |
int tdb_get_flags | ( | struct tdb_context * | tdb | ) |