00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "replace.h"
00028 #include "system/filesys.h"
00029 #include "system/time.h"
00030 #include "system/shmem.h"
00031 #include "system/select.h"
00032 #include "system/wait.h"
00033 #include "tdb.h"
00034
00035 #ifndef u32
00036 #define u32 unsigned
00037 #endif
00038
00039 #ifndef HAVE_GETPAGESIZE
00040 #define getpagesize() 0x2000
00041 #endif
00042
00043 typedef u32 tdb_len_t;
00044 typedef u32 tdb_off_t;
00045
00046 #ifndef offsetof
00047 #define offsetof(t,f) ((unsigned int)&((t *)0)->f)
00048 #endif
00049
00050 #define TDB_MAGIC_FOOD "TDB file\n"
00051 #define TDB_VERSION (0x26011967 + 6)
00052 #define TDB_MAGIC (0x26011999U)
00053 #define TDB_FREE_MAGIC (~TDB_MAGIC)
00054 #define TDB_DEAD_MAGIC (0xFEE1DEAD)
00055 #define TDB_RECOVERY_MAGIC (0xf53bc0e7U)
00056 #define TDB_ALIGNMENT 4
00057 #define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT)
00058 #define DEFAULT_HASH_SIZE 131
00059 #define FREELIST_TOP (sizeof(struct tdb_header))
00060 #define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1))
00061 #define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24))
00062 #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
00063 #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
00064 #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t))
00065 #define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t))
00066 #define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1)
00067 #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start)
00068 #define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number)
00069 #define TDB_PAD_BYTE 0x42
00070 #define TDB_PAD_U32 0x42424242
00071
00072
00073
00074
00075 #define TDB_LOG(x) tdb->log.log_fn x
00076
00077
00078 #define GLOBAL_LOCK 0
00079 #define ACTIVE_LOCK 4
00080 #define TRANSACTION_LOCK 8
00081
00082
00083 #ifndef SAFE_FREE
00084 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
00085 #endif
00086
00087 #define BUCKET(hash) ((hash) % tdb->header.hash_size)
00088
00089 #define DOCONV() (tdb->flags & TDB_CONVERT)
00090 #define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x)
00091
00092
00093
00094
00095 struct list_struct {
00096 tdb_off_t next;
00097 tdb_len_t rec_len;
00098 tdb_len_t key_len;
00099 tdb_len_t data_len;
00100 u32 full_hash;
00101 u32 magic;
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 };
00113
00114
00115
00116 struct tdb_header {
00117 char magic_food[32];
00118 u32 version;
00119 u32 hash_size;
00120 tdb_off_t rwlocks;
00121 tdb_off_t recovery_start;
00122 tdb_off_t sequence_number;
00123 tdb_off_t reserved[29];
00124 };
00125
00126 struct tdb_lock_type {
00127 int list;
00128 u32 count;
00129 u32 ltype;
00130 };
00131
00132 struct tdb_traverse_lock {
00133 struct tdb_traverse_lock *next;
00134 u32 off;
00135 u32 hash;
00136 int lock_rw;
00137 };
00138
00139
00140 struct tdb_methods {
00141 int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int );
00142 int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t);
00143 void (*next_hash_chain)(struct tdb_context *, u32 *);
00144 int (*tdb_oob)(struct tdb_context *, tdb_off_t , int );
00145 int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t );
00146 int (*tdb_brlock)(struct tdb_context *, tdb_off_t , int, int, int, size_t);
00147 };
00148
00149 struct tdb_context {
00150 char *name;
00151 void *map_ptr;
00152 int fd;
00153 tdb_len_t map_size;
00154 int read_only;
00155 int traverse_read;
00156 struct tdb_lock_type global_lock;
00157 int num_lockrecs;
00158 struct tdb_lock_type *lockrecs;
00159 enum TDB_ERROR ecode;
00160 struct tdb_header header;
00161 u32 flags;
00162 struct tdb_traverse_lock travlocks;
00163 struct tdb_context *next;
00164 dev_t device;
00165 ino_t inode;
00166 struct tdb_logging_context log;
00167 unsigned int (*hash_fn)(TDB_DATA *key);
00168 int open_flags;
00169 unsigned int num_locks;
00170 const struct tdb_methods *methods;
00171 struct tdb_transaction *transaction;
00172 int page_size;
00173 int max_dead_records;
00174 volatile sig_atomic_t *interrupt_sig_ptr;
00175 };
00176
00177
00178
00179
00180
00181 int tdb_munmap(struct tdb_context *tdb);
00182 void tdb_mmap(struct tdb_context *tdb);
00183 int tdb_lock(struct tdb_context *tdb, int list, int ltype);
00184 int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
00185 int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len);
00186 int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len);
00187 int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
00188 int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off);
00189 int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
00190 int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
00191 void *tdb_convert(void *buf, u32 size);
00192 int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
00193 tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec);
00194 int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
00195 int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
00196 int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off);
00197 int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off);
00198 int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
00199 int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
00200 int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec);
00201 char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len);
00202 int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
00203 tdb_off_t offset, tdb_len_t len,
00204 int (*parser)(TDB_DATA key, TDB_DATA data,
00205 void *private_data),
00206 void *private_data);
00207 tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash, int locktype,
00208 struct list_struct *rec);
00209 void tdb_io_init(struct tdb_context *tdb);
00210 int tdb_expand(struct tdb_context *tdb, tdb_off_t size);
00211 int rec_free_read(struct tdb_context *tdb, tdb_off_t off,
00212 struct list_struct *rec);
00213
00214