110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** 210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @file db_manage.c 310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Management of a DB file 410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * 510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @remark Copyright 2002 OProfile authors 610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @remark Read the file COPYING 710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * 810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @author Philippe Elie 910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */ 1010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 1110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define _GNU_SOURCE 1210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 1310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdlib.h> 145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#ifdef ANDROID 1510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <fcntl.h> 165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#else 175a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include <sys/fcntl.h> 1810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 1910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/mman.h> 2010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/types.h> 2110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/stat.h> 2210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <unistd.h> 2310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <errno.h> 2410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <string.h> 2510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdio.h> 2610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 2710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "odb.h" 2810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_string.h" 2910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_libiberty.h" 3010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic __inline odb_descr_t * odb_to_descr(odb_data_t * data) 3310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 3410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return (odb_descr_t *)(((char*)data->base_memory) + data->sizeof_header); 3510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 3610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic __inline odb_node_t * odb_to_node_base(odb_data_t * data) 3910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 4010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return (odb_node_t *)(((char *)data->base_memory) + data->offset_node); 4110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 4210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 4310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 4410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic __inline odb_index_t * odb_to_hash_base(odb_data_t * data) 4510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 4610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return (odb_index_t *)(((char *)data->base_memory) + 4710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->offset_node + 4810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project (data->descr->size * sizeof(odb_node_t))); 4910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 5010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 5110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 5210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** 5310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * return the number of bytes used by hash table, node table and header. 5410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */ 5510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic unsigned int tables_size(odb_data_t const * data, odb_node_nr_t node_nr) 5610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 5710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t size; 5810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 5910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size = node_nr * (sizeof(odb_index_t) * BUCKET_FACTOR); 6010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size += node_nr * sizeof(odb_node_t); 6110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size += data->offset_node; 6210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 6310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return size; 6410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 6510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 6610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 6710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint odb_grow_hashtable(odb_data_t * data) 6810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 6910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project unsigned int old_file_size; 7010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project unsigned int new_file_size; 7110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project unsigned int pos; 7210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project void * new_map; 7310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 7410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project old_file_size = tables_size(data, data->descr->size); 7510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project new_file_size = tables_size(data, data->descr->size * 2); 7610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 7710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (ftruncate(data->fd, new_file_size)) 7810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return 1; 7910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 80b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown#ifdef MISSING_MREMAP 81b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown new_map = mmap(0, new_file_size, PROT_READ | PROT_WRITE, 82b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown MAP_SHARED, data->fd, 0); 83b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown#else 8410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project new_map = mremap(data->base_memory, 8510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project old_file_size, new_file_size, MREMAP_MAYMOVE); 86b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown#endif 8710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 8810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (new_map == MAP_FAILED) 8910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return 1; 9010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 91b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown#ifdef MISSING_MREMAP 92b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown munmap(data->base_memory, old_file_size); 93b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown#endif 94b415faba7482dd7ee3335f0f1518333554e3da0dJeff Brown 9510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->base_memory = new_map; 9610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->descr = odb_to_descr(data); 9710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->descr->size *= 2; 9810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->node_base = odb_to_node_base(data); 9910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->hash_base = odb_to_hash_base(data); 10010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->hash_mask = (data->descr->size * BUCKET_FACTOR) - 1; 10110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 10210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project /* rebuild the hash table, node zero is never used. This works 10310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * because layout of file is node table then hash table, 10410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * sizeof(node) > sizeof(bucket) and when we grow table we 10510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * double size ==> old hash table and new hash table can't 10610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * overlap so on the new hash table is entirely in the new 10710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * memory area (the grown part) and we know the new hash 10810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * hash table is zeroed. That's why we don't need to zero init 10910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * the new table */ 11010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project /* OK: the above is not exact 11110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * if BUCKET_FACTOR < sizeof(bd_node_t) / sizeof(bd_node_nr_t) 11210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * all things are fine and we don't need to init the hash 11310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * table because in this case the new hash table is completely 11410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * inside the new growed part. Avoiding to touch this memory is 11510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * useful. 11610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */ 11710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#if 0 11810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (pos = 0 ; pos < data->descr->size*BUCKET_FACTOR ; ++pos) 11910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->hash_base[pos] = 0; 12010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 12110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 12210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (pos = 1; pos < data->descr->current_size; ++pos) { 12310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb_node_t * node = &data->node_base[pos]; 12410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t index = odb_do_hash(data, node->key); 12510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project node->next = data->hash_base[index]; 12610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->hash_base[index] = pos; 12710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 12810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 12910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return 0; 13010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 13110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 13210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 13310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid odb_init(odb_t * odb) 13410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 13510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb->data = NULL; 13610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 13710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 13810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 13910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* the default number of page, calculated to fit in 4096 bytes */ 14010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define DEFAULT_NODE_NR(offset_node) 128 14110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define FILES_HASH_SIZE 512 14210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic struct list_head files_hash[FILES_HASH_SIZE]; 14410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void init_hash() 14710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 14810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 14910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < FILES_HASH_SIZE; ++i) 15010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project list_init(&files_hash[i]); 15110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 15210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 15310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 15410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic odb_data_t * 15510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectfind_samples_data(size_t hash, char const * filename) 15610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 15710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project struct list_head * pos; 15810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 15910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project /* FIXME: maybe an initial init routine ? */ 16010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (files_hash[0].next == NULL) { 16110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project init_hash(); 16210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return NULL; 16310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 16410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 16510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project list_for_each(pos, &files_hash[hash]) { 16610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb_data_t * entry = list_entry(pos, odb_data_t, list); 16710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (strcmp(entry->filename, filename) == 0) 16810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return entry; 16910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 17010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 17110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return NULL; 17210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 17310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 17410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 17510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint odb_open(odb_t * odb, char const * filename, enum odb_rw rw, 17610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t sizeof_header) 17710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 17810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project struct stat stat_buf; 17910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb_node_nr_t nr_node; 18010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb_data_t * data; 18110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t hash; 18210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int err = 0; 18310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 18410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int flags = (rw == ODB_RDWR) ? (O_CREAT | O_RDWR) : O_RDONLY; 18510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int mmflags = (rw == ODB_RDWR) ? (PROT_READ | PROT_WRITE) : PROT_READ; 18610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 18710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project hash = op_hash_string(filename) % FILES_HASH_SIZE; 18810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data = find_samples_data(hash, filename); 18910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (data) { 19010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb->data = data; 19110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->ref_count++; 19210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return 0; 19310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 19410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 19510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data = xmalloc(sizeof(odb_data_t)); 19610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memset(data, '\0', sizeof(odb_data_t)); 19710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project list_init(&data->list); 19810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->offset_node = sizeof_header + sizeof(odb_descr_t); 19910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->sizeof_header = sizeof_header; 20010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->ref_count = 1; 20110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->filename = xstrdup(filename); 20210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 20310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->fd = open(filename, flags, 0644); 20410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (data->fd < 0) { 20510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = errno; 20610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto out; 20710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 20810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 20910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (fstat(data->fd, &stat_buf)) { 21010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = errno; 21110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto fail; 21210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 21310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 21410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (stat_buf.st_size == 0) { 21510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t file_size; 21610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 21710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (rw == ODB_RDONLY) { 21810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = EIO; 21910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto fail; 22010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 22110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 22210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project nr_node = DEFAULT_NODE_NR(data->offset_node); 22310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 22410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project file_size = tables_size(data, nr_node); 22510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (ftruncate(data->fd, file_size)) { 22610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = errno; 22710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto fail; 22810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 22910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } else { 23010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project /* Calculate nr node allowing a sanity check later */ 23110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project nr_node = (stat_buf.st_size - data->offset_node) / 23210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ((sizeof(odb_index_t) * BUCKET_FACTOR) + sizeof(odb_node_t)); 23310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 23410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 23510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->base_memory = mmap(0, tables_size(data, nr_node), mmflags, 23610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project MAP_SHARED, data->fd, 0); 23710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 23810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (data->base_memory == MAP_FAILED) { 23910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = errno; 24010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto fail; 24110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 24210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 24310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->descr = odb_to_descr(data); 24410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 24510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (stat_buf.st_size == 0) { 24610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->descr->size = nr_node; 24710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project /* page zero is not used */ 24810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->descr->current_size = 1; 24910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } else { 25010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project /* file already exist, sanity check nr node */ 25110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (nr_node != data->descr->size) { 25210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = EINVAL; 25310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto fail_unmap; 25410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 25510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 25610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 25710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->hash_base = odb_to_hash_base(data); 25810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->node_base = odb_to_node_base(data); 25910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->hash_mask = (data->descr->size * BUCKET_FACTOR) - 1; 26010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 26110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project list_add(&data->list, &files_hash[hash]); 26210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb->data = data; 26310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectout: 26410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return err; 26510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectfail_unmap: 26610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project munmap(data->base_memory, tables_size(data, nr_node)); 26710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectfail: 26810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project close(data->fd); 26910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project free(data->filename); 27010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project free(data); 27110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb->data = NULL; 27210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project goto out; 27310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 27410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 27510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 27610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid odb_close(odb_t * odb) 27710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 27810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb_data_t * data = odb->data; 27910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 28010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (data) { 28110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project data->ref_count--; 28210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (data->ref_count == 0) { 28310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t size = tables_size(data, data->descr->size); 28410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project list_del(&data->list); 28510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project munmap(data->base_memory, size); 28610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (data->fd >= 0) 28710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project close(data->fd); 28810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project free(data->filename); 28910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project free(data); 29010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb->data = NULL; 29110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 29210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 29310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 29410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 29510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 29610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint odb_open_count(odb_t const * odb) 29710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 29810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (!odb->data) 29910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return 0; 30010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return odb->data->ref_count; 30110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 30210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 30310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 30410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid * odb_get_data(odb_t * odb) 30510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 30610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return odb->data->base_memory; 30710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 30810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 30910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 31010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid odb_sync(odb_t const * odb) 31110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 31210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project odb_data_t * data = odb->data; 31310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t size; 31410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 31510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (!data) 31610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 31710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 31810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size = tables_size(data, data->descr->size); 31910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project msync(data->base_memory, size, MS_ASYNC); 32010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 321