X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=osl.c;h=fa37dea95ce42faec7131e0b371c837790361c3d;hp=a71f93c3243153d20504eae0fed91a88141145ff;hb=340eefa8e83c72319de0feda257d49e668b33f22;hpb=4a262fc2d915538dd5ebaa58fa5ec7403de650cd diff --git a/osl.c b/osl.c index a71f93c3..fa37dea9 100644 --- a/osl.c +++ b/osl.c @@ -12,9 +12,6 @@ #include /* readdir() */ #include -//#define FMT_OFF_T "%li" - - /** * A wrapper for lseek(2). * @@ -41,7 +38,7 @@ int para_lseek(int fd, off_t *offset, int whence) } /** - * Waraper for the write system call. + * Wrapper for the write system call. * * \param fd The file descriptor to write to. * \param buf The buffer to write. @@ -270,7 +267,6 @@ int for_each_file_in_dir(const char *dirname, * and calling chdir() afterwards (see man 3 getcwd). */ int cwd_fd = open(".", O_RDONLY); - struct stat s; int ret = -1; // PARA_DEBUG_LOG("dirname: %s\n", dirname); @@ -287,12 +283,12 @@ int for_each_file_in_dir(const char *dirname, while ((entry = readdir(dir))) { mode_t m; char *tmp; + struct stat s; if (!strcmp(entry->d_name, ".")) continue; if (!strcmp(entry->d_name, "..")) continue; - ret = -E_OSL_LSTAT; if (lstat(entry->d_name, &s) == -1) continue; m = s.st_mode; @@ -337,18 +333,18 @@ int para_mkdir(const char *path, mode_t mode) return -E_MKDIR; } -static int verify_basename(const char *name) +static int verify_name(const char *name) { if (!name) - return -E_BAD_BASENAME; + return -E_BAD_NAME; if (!*name) - return -E_BAD_BASENAME; + return -E_BAD_NAME; if (strchr(name, '/')) - return -E_BAD_BASENAME; + return -E_BAD_NAME; if (!strcmp(name, "..")) - return -E_BAD_BASENAME; + return -E_BAD_NAME; if (!strcmp(name, ".")) - return -E_BAD_BASENAME; + return -E_BAD_NAME; return 1; } @@ -432,7 +428,7 @@ static int init_column_descriptions(struct osl_table *t) const struct osl_column_description *cd; ret = -E_BAD_TABLE_DESC; - ret = verify_basename(t->desc->name); + ret = verify_name(t->desc->name); if (ret < 0) goto err; ret = -E_BAD_DB_DIR; @@ -451,7 +447,7 @@ static int init_column_descriptions(struct osl_table *t) ret = -E_NO_COLUMN_NAME; if (!cd->name || !cd->name[0]) goto err; - ret = verify_basename(cd->name); + ret = verify_name(cd->name); if (ret < 0) goto err; t->index_header_size += index_column_description_size(cd->name); @@ -526,8 +522,8 @@ int init_table_structure(const struct osl_table_description *desc, break; case OSL_MAPPED_STORAGE: t->num_mapped_columns++; - col->index_offset = t->index_entry_size; - t->index_entry_size += 8; + col->index_offset = t->row_index_size; + t->row_index_size += 8; break; case OSL_NO_STORAGE: col->volatile_num = t->num_volatile_columns; @@ -551,7 +547,7 @@ int init_table_structure(const struct osl_table_description *desc, if (!t->num_rbtrees) goto err; /* success */ - PARA_DEBUG_LOG("OK. Index entry size: %u\n", t->index_entry_size); + PARA_DEBUG_LOG("OK. Index entry size: %u\n", t->row_index_size); ret = init_column_descriptions(t); if (ret < 0) goto err; @@ -730,7 +726,7 @@ static int create_table_index(struct osl_table *t) * \param desc Pointer to the table description. * * \return Positive on success, negative on errors. Possible errors include: \p - * E_BAD_TABLE_DESC, \p E_BAD_DB_DIR, \p E_BAD_BASENAME, \p E_NO_COMPARE_FUNC, \p + * E_BAD_TABLE_DESC, \p E_BAD_DB_DIR, \p E_BAD_NAME, \p E_NO_COMPARE_FUNC, \p * E_NO_COLUMN_NAME, \p E_DUPLICATE_COL_NAME, \p E_MKDIR, any errors returned * by para_open(). */ @@ -806,6 +802,17 @@ static void mark_table_clean(struct osl_table *t) write_u8(buf, read_u8(buf) & 0xfe); } +static void unmap_column(struct osl_table *t, unsigned col_num) +{ + struct osl_object map = t->columns[col_num].data_map; + int ret; + if (!map.data) + return; + ret = para_munmap(map.data, map.size); + assert(ret > 0); + map.data = NULL; +} + /** * Unmap all mapped files of an osl table. * @@ -836,18 +843,30 @@ int unmap_table(struct osl_table *t, enum osl_close_flags flags) t->index_map.data = NULL; if (!t->num_rows) return 1; - FOR_EACH_MAPPED_COLUMN(i, t, cd) { - struct osl_object map = t->columns[i].data_map; - if (!map.data) - continue; - ret = para_munmap(map.data, map.size); - if (ret < 0) - return ret; - map.data = NULL; - } + FOR_EACH_MAPPED_COLUMN(i, t, cd) + unmap_column(t, i); return 1; } +static int map_column(struct osl_table *t, unsigned col_num) +{ + struct stat statbuf; + char *filename = column_filename(t, col_num); + int ret = -E_STAT; + if (stat(filename, &statbuf) < 0) { + free(filename); + return ret; + } + if (!(S_IFREG & statbuf.st_mode)) { + free(filename); + return ret; + } + ret = mmap_full_file(filename, O_RDWR, + &t->columns[col_num].data_map); + free(filename); + return ret; +} + /** * Map the index file and all columns of type \p OSL_MAPPED_STORAGE into memory. * @@ -894,20 +913,7 @@ int map_table(struct osl_table *t, enum map_table_flags flags) return num_rows; /* map data files */ FOR_EACH_MAPPED_COLUMN(i, t, cd) { - struct stat statbuf; - filename = column_filename(t, i); - ret = -E_STAT; - if (stat(filename, &statbuf) < 0) { - free(filename); - goto err; - } - if (!(S_IFREG & statbuf.st_mode)) { - free(filename); - goto err; - } - ret = mmap_full_file(filename, O_RDWR, - &t->columns[i].data_map); - free(filename); + ret = map_column(t, i); if (ret < 0) goto err; } @@ -935,7 +941,7 @@ err: /* unmap what is already mapped */ * of storage type \p OSL_MAPPED_STORAGE. * * \return Positive on success, negative on errors. Possible errors include: - * \p E_BAD_ID, \p E_INVALID_OBJECT. + * \p E_BAD_ROW_NUM, \p E_INVALID_OBJECT. * * \sa osl_storage_type. */ @@ -945,16 +951,16 @@ int get_mapped_object(const struct osl_table *t, unsigned col_num, struct osl_column *col = &t->columns[col_num]; uint32_t offset; char *header; - char *index_entry; + char *cell_index; int ret; if (t->num_rows <= row_num) - return -E_BAD_ID; - ret = get_index_entry(t, row_num, col_num, &index_entry); + return -E_BAD_ROW_NUM; + ret = get_cell_index(t, row_num, col_num, &cell_index); if (ret < 0) return ret; - offset = read_u32(index_entry); - obj->size = read_u32(index_entry + 4) - 1; + offset = read_u32(cell_index); + obj->size = read_u32(cell_index + 4) - 1; header = col->data_map.data + offset; obj->data = header + 1; if (read_u8(header) == 0xff) { @@ -981,7 +987,7 @@ static int search_rbtree(const struct osl_object *obj, struct osl_object this_obj; parent = *new; if (st == OSL_MAPPED_STORAGE) { - ret = get_mapped_object(t, col_num, this_row->id, + ret = get_mapped_object(t, col_num, this_row->num, &this_obj); if (ret < 0) return ret; @@ -1051,7 +1057,7 @@ static void remove_rb_node(struct osl_table *t, unsigned col_num, rb_erase(victim, &col->rbtree); } -static int add_row_to_rbtrees(struct osl_table *t, uint32_t id, +static int add_row_to_rbtrees(struct osl_table *t, uint32_t row_num, struct osl_object *volatile_objs, struct osl_row **row_ptr) { unsigned i; @@ -1059,12 +1065,12 @@ static int add_row_to_rbtrees(struct osl_table *t, uint32_t id, struct osl_row *row = allocate_row(t->num_rbtrees); const struct osl_column_description *cd; - row->id = id; + row->num = row_num; row->volatile_objects = volatile_objs; FOR_EACH_RBTREE_COLUMN(i, t, cd) { if (cd->storage_type == OSL_MAPPED_STORAGE) { struct osl_object obj; - ret = get_mapped_object(t, i, id, &obj); + ret = get_mapped_object(t, i, row_num, &obj); if (ret < 0) goto err; ret = insert_rbtree(t, i, row, &obj); @@ -1185,13 +1191,13 @@ int osl_close_table(struct osl_table *t, enum osl_close_flags flags) */ int row_is_invalid(struct osl_table *t, uint32_t row_num) { - char *index_entry; - int i, ret = get_index_entry_start(t, row_num, &index_entry); + char *row_index; + int i, ret = get_row_index(t, row_num, &row_index); if (ret < 0) return ret; - for (i = 0; i < t->index_entry_size; i++) { - if ((unsigned char)index_entry[i] != 0xff) + for (i = 0; i < t->row_index_size; i++) { + if ((unsigned char)row_index[i] != 0xff) return 0; } PARA_INFO_LOG("row %d is invalid\n", row_num); @@ -1211,14 +1217,13 @@ int row_is_invalid(struct osl_table *t, uint32_t row_num) */ int mark_row_invalid(struct osl_table *t, uint32_t row_num) { - char *index_entry; - int i, ret = get_index_entry_start(t, row_num, &index_entry); + char *row_index; + int ret = get_row_index(t, row_num, &row_index); - PARA_INFO_LOG("marking row %d as invalid\n", row_num); if (ret < 0) return ret; - for (i = 0; i < t->index_entry_size; i++) - index_entry[i] = 0xff; + PARA_INFO_LOG("marking row %d as invalid\n", row_num); + memset(row_index, 0xff, t->row_index_size); return 1; } @@ -1361,7 +1366,7 @@ static int append_map_file(const struct osl_table *t, unsigned col_num, return ret; } -static int append_index_entry(const struct osl_table *t, char *new_index_entry) +static int append_row_index(const struct osl_table *t, char *row_index) { char *filename; int ret; @@ -1369,9 +1374,8 @@ static int append_index_entry(const struct osl_table *t, char *new_index_entry) if (!t->num_mapped_columns) return 1; filename = index_filename(t->desc); -// PARA_DEBUG_LOG("appending %u bytes\n", t->index_entry_size); - ret = append_file(filename, NULL, 0, new_index_entry, - t->index_entry_size, NULL); + ret = append_file(filename, NULL, 0, row_index, + t->row_index_size, NULL); free(filename); return ret; } @@ -1423,7 +1427,7 @@ static int delete_disk_storage_file(const struct osl_table *t, unsigned col_num, char *dirname, *filename = disk_storage_path(t, col_num, ds_name); int ret = unlink(filename); - PARA_INFO_LOG("deleted %s\n", filename); + PARA_DEBUG_LOG("deleted %s\n", filename); free(filename); if (ret < 0) { if (errno == ENOENT) @@ -1469,7 +1473,7 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, int i, ret; char *ds_name = NULL; struct rb_node **rb_parents = NULL, ***rb_links = NULL; - char *new_index_entry = NULL; + char *new_row_index = NULL; struct osl_object *volatile_objs = NULL; const struct osl_column_description *cd; @@ -1478,7 +1482,7 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, rb_parents = para_malloc(t->num_rbtrees * sizeof(struct rn_node*)); rb_links = para_malloc(t->num_rbtrees * sizeof(struct rn_node**)); if (t->num_mapped_columns) - new_index_entry = para_malloc(t->index_entry_size); + new_row_index = para_malloc(t->row_index_size); /* pass 1: sanity checks */ // PARA_DEBUG_LOG("sanity tests: %p:%p\n", objects[0].data, // objects[1].data); @@ -1529,7 +1533,7 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, ret = append_map_file(t, i, objects + i, &new_size); if (ret < 0) goto rollback; - update_index_entry(new_index_entry, col, new_size, + update_cell_index(new_row_index, col, new_size, objects[i].size); continue; } @@ -1538,13 +1542,13 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, if (ret < 0) goto rollback; } - ret = append_index_entry(t, new_index_entry); + ret = append_row_index(t, new_row_index); if (ret < 0) goto rollback; ret = map_table(t, MAP_TBL_FL_VERIFY_INDEX); if (ret < 0) { /* truncate index and rollback changes */ char *filename = index_filename(t->desc); - para_truncate(filename, t->index_entry_size); + para_truncate(filename, t->row_index_size); free(filename); goto rollback; } @@ -1578,7 +1582,7 @@ rollback: /* rollback all changes made, ignore further errors */ /* ignore error and return previous error value */ map_table(t, MAP_TBL_FL_VERIFY_INDEX); out: - free(new_index_entry); + free(new_row_index); free(ds_name); free(rb_parents); free(rb_links); @@ -1629,18 +1633,18 @@ int osl_get_object(const struct osl_table *t, const struct osl_row *r, if (cd->storage_type == OSL_DISK_STORAGE) return -E_BAD_STORAGE_TYPE; if (cd->storage_type == OSL_MAPPED_STORAGE) - return get_mapped_object(t, col_num, r->id, object); + return get_mapped_object(t, col_num, r->num, object); /* volatile */ *object = r->volatile_objects[t->columns[col_num].volatile_num]; return 1; } -static int mark_mapped_object_invalid(const struct osl_table *t, uint32_t id, - unsigned col_num) +static int mark_mapped_object_invalid(const struct osl_table *t, + uint32_t row_num, unsigned col_num) { struct osl_object obj; char *p; - int ret = get_mapped_object(t, col_num, id, &obj); + int ret = get_mapped_object(t, col_num, row_num, &obj); if (ret < 0) return ret; @@ -1688,14 +1692,14 @@ int osl_del_row(struct osl_table *t, struct osl_row *row) enum osl_storage_type st = cd->storage_type; remove_rb_node(t, i, r); if (st == OSL_MAPPED_STORAGE) { - mark_mapped_object_invalid(t, r->id, i); + mark_mapped_object_invalid(t, r->num, i); continue; } if (st == OSL_NO_STORAGE) free(r->volatile_objects[col->volatile_num].data); } if (t->num_mapped_columns) { - ret = mark_row_invalid(t, r->id); + ret = mark_row_invalid(t, r->num); if (ret < 0) goto out; t->num_invalid_rows++; @@ -1915,13 +1919,14 @@ int osl_update_object(struct osl_table *t, const struct osl_row *r, return -E_BAD_TABLE; col = &t->columns[col_num]; cd = get_column_description(t->desc, col_num); + PARA_DEBUG_LOG("updating column %u of %s\n", col_num, t->desc->name); if (cd->storage_flags & OSL_RBTREE) { if (search_rbtree(obj, t, col_num, NULL, NULL) > 0) return -E_RB_KEY_EXISTS; } if (cd->storage_flags & OSL_FIXED_SIZE) { if (obj->size != cd->data_size) - return -E_BAD_SIZE; + return -E_BAD_DATA_SIZE; } remove_rb_node(t, col_num, r); if (cd->storage_type == OSL_NO_STORAGE) { /* TODO: If fixed size, reuse object? */ @@ -1943,7 +1948,7 @@ int osl_update_object(struct osl_table *t, const struct osl_row *r, return ret; } else { /* mapped storage */ struct osl_object old_obj; - ret = get_mapped_object(t, col_num, r->id, &old_obj); + ret = get_mapped_object(t, col_num, r->num, &old_obj); if (ret < 0) return ret; /* @@ -1960,18 +1965,22 @@ int osl_update_object(struct osl_table *t, const struct osl_row *r, memcpy(old_obj.data, obj->data, cd->data_size); else { /* TODO: if the size doesn't change, use old space */ uint32_t new_data_map_size; - char *index_entry; - ret = get_index_entry_start(t, r->id, &index_entry); + char *row_index; + ret = get_row_index(t, r->num, &row_index); if (ret < 0) return ret; - ret = mark_mapped_object_invalid(t, r->id, col_num); + ret = mark_mapped_object_invalid(t, r->num, col_num); if (ret < 0) return ret; + unmap_column(t, col_num); ret = append_map_file(t, col_num, obj, &new_data_map_size); if (ret < 0) return ret; - update_index_entry(index_entry, col, new_data_map_size, + ret = map_column(t, col_num); + if (ret < 0) + return ret; + update_cell_index(row_index, col, new_data_map_size, obj->size); } }