tdb/common/tdb.c

ソースコードを見る。

関数

static void tdb_increment_seqnum (struct tdb_context *tdb)
static int tdb_key_compare (TDB_DATA key, TDB_DATA data, void *private_data)
static tdb_off_t tdb_find (struct tdb_context *tdb, TDB_DATA key, u32 hash, struct list_struct *r)
tdb_off_t tdb_find_lock_hash (struct tdb_context *tdb, TDB_DATA key, u32 hash, int locktype, struct list_struct *rec)
static int tdb_update_hash (struct tdb_context *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf)
TDB_DATA tdb_fetch (struct tdb_context *tdb, TDB_DATA key)
int tdb_parse_record (struct tdb_context *tdb, TDB_DATA key, int(*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data)
static int tdb_exists_hash (struct tdb_context *tdb, TDB_DATA key, u32 hash)
int tdb_exists (struct tdb_context *tdb, TDB_DATA key)
int tdb_do_delete (struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec)
static int tdb_count_dead (struct tdb_context *tdb, u32 hash)
static int tdb_purge_dead (struct tdb_context *tdb, u32 hash)
static int tdb_delete_hash (struct tdb_context *tdb, TDB_DATA key, u32 hash)
int tdb_delete (struct tdb_context *tdb, TDB_DATA key)
static tdb_off_t tdb_find_dead (struct tdb_context *tdb, u32 hash, struct list_struct *r, tdb_len_t length)
int tdb_store (struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
int tdb_append (struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
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)
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)

変数

TDB_DATA tdb_null


関数

static void tdb_increment_seqnum ( struct tdb_context tdb  )  [static]

tdb.c37 行で定義されています。

参照先 tdb_context::flagstdbtdb_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 int tdb_key_compare ( TDB_DATA  key,
TDB_DATA  data,
void *  private_data 
) [static]

tdb.c59 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsize.

参照元 tdb_find().

00060 {
00061         return memcmp(data.dptr, key.dptr, data.dsize);
00062 }

static tdb_off_t tdb_find ( struct tdb_context tdb,
TDB_DATA  key,
u32  hash,
struct list_struct r 
) [static]

tdb.c66 行で定義されています。

参照先 TDB_DATA::dsizelist_struct::full_hashlist_struct::key_lentdbTDB_ERR_NOEXISTtdb_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.c93 行で定義されています。

参照先 tdbtdb_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.c110 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizetdb_context::ecodetdb_context::methodslist_struct::rec_lentdbtdb_find()tdb_rec_write()TDB_SUCCESStdb_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.c144 行で定義されています。

参照先 TDB_DATA::dptrtdb_context::hash_fntdbtdb_alloc_read()tdb_find_lock_hash()tdb_nulltdb_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.c179 行で定義されています。

参照先 tdb_context::hash_fntdbTDB_ERR_NOEXISTtdb_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]

tdb.c210 行で定義されています。

参照先 list_struct::full_hashtdbtdb_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.c220 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_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 
)

tdb.c227 行で定義されています。

参照先 list_struct::full_hashlast_ptrlist_struct::magiclist_struct::nexttdb_context::read_onlytdbtdb_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]

tdb.c261 行で定義されています。

参照先 list_struct::magiclist_struct::nexttdbtdb_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]

tdb.c286 行で定義されています。

参照先 list_struct::magiclist_struct::nexttdbtdb_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]

tdb.c322 行で定義されています。

参照先 list_struct::full_hashlist_struct::magictdb_context::max_dead_recordstdbtdb_count_dead()TDB_DEBUG_WARNINGtdb_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.c374 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_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]

tdb.c383 行で定義されています。

参照先 list_struct::nextlist_struct::rec_lentdbtdb_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 
)

tdb.c414 行で定義されています。

参照先 list_struct::data_lenTDB_DATA::dptrTDB_DATA::dsizetdb_context::ecodelist_struct::full_hashtdb_context::hash_fnlist_struct::key_lenlist_struct::magiclist_struct::nexttdb_context::read_onlytdbtdb_allocate()tdb_delete_hash()TDB_ERR_EXISTSTDB_ERR_NOEXISTTDB_ERR_OOMTDB_ERR_RDONLYtdb_exists_hash()tdb_find_dead()tdb_increment_seqnum()tdb_lock()tdb_ofs_read()tdb_ofs_write()tdb_purge_dead()tdb_rec_write()TDB_SUCCESStdb_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.c553 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizetdb_context::ecodefailedtdb_context::hash_fntdbTDB_ERR_OOMtdb_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  ) 

tdb.c598 行で定義されています。

参照先 tdb_context::nametdb.

参照元 _reg_perfcount_multi_sz_from_tdb()copy_fn()tdb_chainlock_with_timeout_internal()tdb_log()tdb_wrap_log().

00599 {
00600         return tdb->name;
00601 }

int tdb_fd ( struct tdb_context tdb  ) 

tdb.c608 行で定義されています。

参照先 tdb_context::fdtdb.

参照元 backup_tdb()winbindd_check_cache_size().

00609 {
00610         return tdb->fd;
00611 }

tdb_log_func tdb_log_fn ( struct tdb_context tdb  ) 

tdb.c617 行で定義されています。

参照先 tdb_context::logtdb_logging_context::log_fntdb.

00618 {
00619         return tdb->log.log_fn;
00620 }

int tdb_get_seqnum ( struct tdb_context tdb  ) 

tdb.c633 行で定義されています。

参照先 tdbtdb_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  ) 

tdb.c641 行で定義されています。

参照先 tdb_header::hash_sizetdb_context::headertdb.

参照元 backup_tdb().

00642 {
00643         return tdb->header.hash_size;
00644 }

size_t tdb_map_size ( struct tdb_context tdb  ) 

tdb.c646 行で定義されています。

参照先 tdb_context::map_sizetdb.

参照元 stat_cache_add().

00647 {
00648         return tdb->map_size;
00649 }

int tdb_get_flags ( struct tdb_context tdb  ) 

tdb.c651 行で定義されています。

参照先 tdb_context::flagstdb.

参照元 idmap_tdb_convert().

00652 {
00653         return tdb->flags;
00654 }


変数

TDB_DATA tdb_null

tdb.c31 行で定義されています。

参照元 tdb_fetch()tdb_firstkey()tdb_nextkey().


Sambaに対してSat Aug 29 21:24:30 2009に生成されました。  doxygen 1.4.7