fsck cleanups.
[osl.git] / osl_core.h
1 /*
2  * Copyright (C) 2007-2008 Andre Noll <maan@systemlinux.org>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file osl_core.h Object storage layer details, not visible to users. */
8
9 #include "rbtree.h"
10 #include "hash.h"
11
12 __must_check __printf_1_2 __malloc char *make_message(const char *fmt, ...);
13
14 /** Internal representation of a column of an osl table. */
15 struct osl_column {
16         /** The memory mapping of this comumn (only used for mapped columns). */
17         struct osl_object data_map;
18         /** The root of the rbtree (only used for columns with rbtrees). */
19         struct rb_root rbtree;
20         /** The index in the array of rb nodes (only used for columns with rbtrees). */
21         unsigned rbtree_num;
22         /** Index for volatile_objects of struct osl_row. */
23         unsigned volatile_num;
24         /**
25          * Starting point of the data for this column within the index
26          * (only used for mapped columns).
27          */
28         uint16_t index_offset;
29         /**
30          * The hash value of the name of this column.
31          *
32          * This is only used for mapped and disk storage columns).
33          */
34         HASH_TYPE name_hash[HASH_SIZE];
35 };
36
37 /** Internal representation of an osl table */
38 struct osl_table {
39         /** Pointer to the table description */
40         const struct osl_table_description *desc;
41         /** The size of the index header of this table. */
42         uint16_t index_header_size;
43         /** Contains the mapping of the table's index file */
44         struct osl_object index_map;
45         /** Total number of rows, including invalid rows. */
46         unsigned num_rows;
47         /** Keeps track of the number of invalid rows in the table. */
48         uint32_t num_invalid_rows;
49         /** Number of columns of type \p OSL_MAPPED_STORAGE. */
50         unsigned num_mapped_columns;
51         /** Number of columns of type \p OSL_NO_STORAGE. */
52         unsigned num_volatile_columns;
53         /** Number of columns of type \p OSL_DISK_STORAGE. */
54         unsigned num_disk_storage_columns;
55         /** Number of columns with associated rbtree. */
56         unsigned num_rbtrees;
57         /**
58          * The number of the column that determines the name of the disk
59          * storage objects.
60          */
61         unsigned disk_storage_name_column;
62         /** The number of bytes of an index entry of a row. */
63         unsigned row_index_size;
64         /** Pointer to the internal representation of the columns. */
65         struct osl_column *columns;
66 };
67
68 /** Internal representation of a row of an osl table */
69 struct osl_row {
70         /**
71          * The row number.
72          *
73          * It is only used if there is at least one mapped column.
74          */
75         off_t num;
76         /** Array of size \a num_volatile_columns. */
77         struct osl_object *volatile_objects;
78 };
79
80 int read_table_desc(struct osl_object *map, struct osl_table_description *desc);
81 int init_table_structure(const struct osl_table_description *desc,
82                 struct osl_table **table_ptr);
83 int row_is_invalid(struct osl_table *t, uint32_t row_num);
84 int get_mapped_object(const struct osl_table *t, unsigned col_num,
85         uint32_t row_num, struct osl_object *obj);
86 int para_truncate(const char *filename, off_t size);
87 int unmap_table(struct osl_table *t, enum osl_close_flags flags);
88 int init_rbtrees(struct osl_table *t);
89
90 /**
91  * Flags to be specified for map_table().
92  *
93  * \sa map_table().
94  */
95 enum map_table_flags {
96         /**
97          * Check whether the entries in the table index match the entries in
98          * the table description.
99          */
100         MAP_TBL_FL_VERIFY_INDEX = 1,
101         /** Do not complain even if the dirty flag is set. */
102         MAP_TBL_FL_IGNORE_DIRTY = 2,
103         /** Use read-only mappings. */
104         MAP_TBL_FL_MAP_RDONLY = 4
105 };
106
107 int map_table(struct osl_table *t, enum map_table_flags flags);
108 void clear_rbtrees(struct osl_table *t);
109 int mark_row_invalid(struct osl_table *t, uint32_t row_num);
110
111
112 /**
113  * Get the description of a column by column number
114  *
115  * \param d Pointer to the table description.
116  * \param col_num The number of the column to get the description for.
117  *
118  * \return The table description.
119  *
120  * \sa struct osl_column_description.
121  */
122 _static_inline_ struct osl_column_description *get_column_description(
123                 const struct osl_table_description *d, unsigned col_num)
124 {
125         return &d->column_descriptions[col_num];
126 }
127
128 /**
129  * Format of the header of the index file of an osl table.
130  *
131  * Bytes 16-31 are currently unused.
132  *
133  * \sa enum index_column_desc_offsets, HASH_SIZE, osl_table_flags.
134  */
135 enum index_header_offsets {
136         /** Bytes 0-8: PARASLASH. */
137         IDX_PARA_MAGIC = 0,
138         /** Byte 9: Dirty flag (nonzero if table is mapped). */
139         IDX_DIRTY_FLAG = 9,
140         /** Byte 10: osl table version number. */
141         IDX_VERSION = 10,
142         /** Byte 11: Table flags.*/
143         IDX_TABLE_FLAGS = 11,
144         /** Byte 12,13: Number of columns. */
145         IDX_NUM_COLUMNS,
146         /** Byte 14,15 Size of the index header. */
147         IDX_HEADER_SIZE = 14,
148         /** Column descriptions start here. */
149         IDX_COLUMN_DESCRIPTIONS = 32
150 };
151
152 /**
153  * Format of the column description in the index header.
154  *
155  * \sa index_header_offsets.
156  */
157 enum index_column_desc_offsets {
158         /** Bytes 0,1: Storage_type. */
159         IDX_CD_STORAGE_TYPE = 0,
160         /** Bytes 2,3: Storage_flags. */
161         IDX_CD_STORAGE_FLAGS = 2,
162         /** Bytes 4 - 7: Data_size (only used for fixed size columns). */
163         IDX_CD_DATA_SIZE = 4,
164         /** Bytes 8 - ... Name of the column. */
165         IDX_CD_NAME = 8,
166 };
167
168 /** Magic string contained in the header of the index file of each osl table. */
169 #define PARA_MAGIC "PARASLASH"
170
171 /**
172  * The minimal number of bytes for a column in the index header.
173  *
174  * The column name starts at byte IDX_CD_NAME and must at least contain one
175  * character, plus the terminating NULL byte.
176   */
177 #define MIN_IDX_COLUMN_DESCRIPTION_SIZE (IDX_CD_NAME + 2)
178
179 /**
180  * Get the number of bytes used for a column in the index header.
181  *
182  * \param name The name of the column.
183  *
184  * The amount of space used for a column in the index header of a table depends
185  * on the (length of the) name of the column.
186  *
187  * \return The total number of bytes needed to store one column of this name.
188  */
189 _static_inline_ size_t index_column_description_size(const char *name)
190 {
191         return MIN_IDX_COLUMN_DESCRIPTION_SIZE + strlen(name) - 1;
192 }
193
194 #define CURRENT_TABLE_VERSION 1
195 #define MIN_TABLE_VERSION 1
196 #define MAX_TABLE_VERSION 1
197 /** An index header must be at least that many bytes long. */
198 #define MIN_INDEX_HEADER_SIZE(num_cols) (MIN_IDX_COLUMN_DESCRIPTION_SIZE \
199         * num_cols + IDX_COLUMN_DESCRIPTIONS)
200
201 /**
202  * Get the number of rows from the size of the memory mapping.
203  *
204  * \param t Pointer to an open table.
205  *
206  * \return The number of rows, including invalid rows.
207  */
208 _static_inline_ unsigned table_num_rows(const struct osl_table *t)
209 {
210         return (t->index_map.size - t->index_header_size)
211                 / t->row_index_size;
212 }
213
214 /**
215  * Get the path of the index file from a table description.
216  *
217  * \param d The table description.
218  *
219  * \return The full path of the index file. Result must be freed by
220  * the caller.
221  */
222 _static_inline_ char *index_filename(const struct osl_table_description *d)
223 {
224         return make_message("%s/%s/index", d->dir, d->name);
225 }
226
227 /**
228  * Get the path of storage of a column.
229  *
230  * \param t Pointer to an initialized table.
231  * \param col_num The number of the column to get the path for.
232  *
233  * \return The full path of the mapped data file (mapped storage) or the
234  * data directory (disk storage). Result must be freed by the caller.
235  *
236  * \sa osl_storage_type.
237  */
238 _static_inline_ char *column_filename(const struct osl_table *t, unsigned col_num)
239 {
240         char asc[2 * HASH_SIZE + 1];
241         hash_to_asc(t->columns[col_num].name_hash, asc);
242         return make_message("%s/%s/%s", t->desc->dir, t->desc->name, asc);
243 }
244
245 /**
246  * Get the start of an index entry
247  *
248  * \param t Pointer to a table which has been mapped.
249  * \param row_num The number of the row whose index entry should be retrieved.
250  * \param row_index Result pointer.
251  *
252  * \return Positive on success, \p -E_INDEX_CORRUPTION otherwise.
253  *
254  * \sa get_cell_index().
255  */
256 _static_inline_ int get_row_index(const struct osl_table *t, uint32_t row_num,
257                 char **row_index)
258 {
259         uint32_t index_offset;
260         index_offset = t->index_header_size + t->row_index_size * row_num;
261         if (index_offset + 8 > t->index_map.size) {
262                 *row_index = NULL;
263                 return -E_OSL_INDEX_CORRUPTION;
264         }
265         *row_index = (char *)(t->index_map.data) + index_offset;
266         return 1;
267 }
268
269 /**
270  * Get the index entry of a row/column pair.
271  *
272  * \param t Pointer to a table which has been mapped.
273  * \param row_num The number of the row whose index entry should be retrieved.
274  * \param col_num The number of the column whose index entry should be retrieved.
275  * \param cell_index Result pointer.
276  *
277  * \return Positive on success, \p -E_INDEX_CORRUPTION otherwise.
278  *
279  * \sa get_row_index().
280  */
281 _static_inline_ int get_cell_index(const struct osl_table *t, uint32_t row_num,
282                 uint32_t col_num, char **cell_index)
283 {
284         int ret = get_row_index(t, row_num, cell_index);
285         if (ret < 0)
286                 return ret;
287         *cell_index += t->columns[col_num].index_offset;
288         return ret;
289 }
290
291 /**
292  * Change an index entry of a column after object was added.
293  *
294  * \param row_index Pointer to the index of the row to update.
295  * \param col Pointer to the column.
296  * \param map_size The new size of the data file.
297  * \param object_size The size of the object just appended to the data file.
298  *
299  * This is called right after an object was appended to the data file for a
300  * mapped column.
301  *
302  * \sa get_row_index().
303  */
304 _static_inline_ void update_cell_index(char *row_index, struct osl_column *col,
305                 uint32_t map_size, uint32_t object_size)
306 {
307         write_u32(row_index + col->index_offset, map_size - object_size - 1);
308         write_u32(row_index + col->index_offset + 4, object_size + 1);
309 }
310
311 /**
312  * Get the full path of a disk storage object
313  *
314  * \param t Pointer to an initialized table.
315  * \param col_num The number of the column the disk storage object belongs to.
316  * \param ds_name The disk storage name of the object.
317  *
318  * \return Pointer to the full path which must be freed by the caller.
319  *
320  * \sa column_filename(), disk_storage_name_of_row().
321  */
322 _static_inline_ char *disk_storage_path(const struct osl_table *t,
323                 unsigned col_num, const char *ds_name)
324 {
325         char *filename, *dirname = column_filename(t, col_num);
326
327         if (!dirname)
328                 return NULL;
329         filename = make_message("%s/%s", dirname, ds_name);
330         free(dirname);
331         return filename;
332 }
333
334 /**
335  * Get the column description of the next column of a given type.
336  *
337  * \param type the desired storage type.
338  * \param col_num the column to start the search.
339  * \param t the osl table.
340  * \param cd result is returned here.
341  *
342  * \return On success, \a cd contains the column description of the next column
343  * of type \a type, and the number of that column is returned.  Otherwise, \a
344  * cd is set to \p NULL and the function returns t->num_columns + 1.
345  *
346  * \sa FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN, FOR_EACH_RBTREE_COLUMN,
347  * FOR_EACH_DISK_STORAGE_COLUMN, FOR_EACH_VOLATILE_COLUMN, osl_storage_type.
348  */
349 _static_inline_ int next_column_of_type(enum osl_storage_type type, int col_num,
350                 const struct osl_table *t,
351                 const struct osl_column_description **cd)
352 {
353         *cd = NULL;
354         while (col_num < t->desc->num_columns) {
355                 *cd = get_column_description(t->desc, col_num);
356                 if ((*cd)->storage_type == type)
357                         break;
358                 col_num++;
359         }
360         return col_num;
361 }
362
363 /**
364  * Find the next column with an associated rbtree.
365  *
366  * \param col_num The column to start the search.
367  * \param t The osl table.
368  * \param cd Result is returned here.
369
370  * \return On success, \a cd contains the column description of the next column
371  * with associated rbtree, and the number of that column is returned.
372  * Otherwise, \a cd is set to \p NULL and the function returns t->num_columns +
373  * 1.
374  *
375  * \sa FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN, FOR_EACH_RBTREE_COLUMN,
376  * FOR_EACH_DISK_STORAGE_COLUMN, FOR_EACH_VOLATILE_COLUMN, osl_storage_flags.
377  */
378 _static_inline_ int next_rbtree_column(int col_num, const struct osl_table *t,
379                 const struct osl_column_description **cd)
380 {
381         *cd = NULL;
382         while (col_num < t->desc->num_columns) {
383                 *cd = get_column_description(t->desc, col_num);
384                 if ((*cd)->storage_flags & OSL_RBTREE)
385                         break;
386                 col_num++;
387         }
388         return col_num;
389 }
390
391
392 /* quite some dirty hacks */
393
394 /** Round up size of struct osl_row to multiple of 8 */
395 #define RB_NODES_OFFSET ((sizeof(struct osl_row) + 7) / 8 * 8)
396
397 /**
398  * Allocate a new osl row.
399  *
400  * \param num_rbtrees The number of rbtrees for this row.
401  *
402  * \return A pointer to a zeroed-out area suitable for holding an osl row with
403  * \a num_rbtrees rbtree columns or \p NULL if no memory could be allocated.
404  */
405 _static_inline_ struct osl_row *allocate_row(unsigned num_rbtrees)
406 {
407         size_t s = RB_NODES_OFFSET + num_rbtrees * sizeof(struct rb_node);
408         return calloc(1, s);
409 }
410
411 /**
412  * Compute the pointer to a rbtree node embedded in a osl row.
413  *
414  * \param row The row to extract the rbtree pointer from.
415  * \param rbtree_num The number of the rbtree node to extract.
416  *
417  * \return A pointer to the \a rbtree_num th node contained in \a row.
418  */
419 _static_inline_ struct rb_node *get_rb_node_pointer(const struct osl_row *row, uint32_t rbtree_num)
420 {
421         return ((struct rb_node *)(((char *)row) + RB_NODES_OFFSET)) + rbtree_num;
422 }
423
424 /**
425  * Get a pointer to the struct containing the given rbtree node.
426  *
427  * \param node Pointer to the rbtree node.
428  * \param rbtree_num Number of \a node in the array of rbtree nodes.
429  *
430  * \return A pointer to the row containing \a node.
431  */
432 _static_inline_ struct osl_row *get_row_pointer(const struct rb_node *node,
433                 unsigned rbtree_num)
434 {
435         node -= rbtree_num;
436         return (struct osl_row *)(((char *)node) - RB_NODES_OFFSET);
437 }
438
439 /**
440  * Compute a cryptographic hash of an osl object.
441  *
442  * \param obj the Object to compute the hash value from.
443  * \param hash Result is returned here.
444  */
445 _static_inline_ void hash_object(const struct osl_object *obj, HASH_TYPE *hash)
446 {
447         hash_function(obj->data, obj->size, hash);
448 }
449
450 /**
451  * Get the relative path of an object, given the hash value.
452  *
453  * \param t Pointer to an initialized osl table.
454  * \param hash An arbitrary hash value.
455  *
456  * This function is typically called with \a hash being the hash of the object
457  * stored in the disk storage name column of a row.  If the OSL_LARGE_TABLE
458  * flag is set, the first two hex digits get separated with a slash from the
459  * remaining digits.
460  *
461  * \return The relative path for all disk storage objects corresponding to \a
462  * hash.
463  *
464  * \sa struct osl_table:disk_storage_name_column.
465  */
466 _static_inline_ char *disk_storage_name_of_hash(const struct osl_table *t, HASH_TYPE *hash)
467 {
468         char asc[2 * HASH_SIZE + 2];
469
470         hash_to_asc(hash, asc);
471         if (t->desc->flags & OSL_LARGE_TABLE)
472                 return make_message("%.2s/%s", asc, asc + 2);
473         return strdup(asc);
474 }
475
476 /**
477  * Iterate over each column of an initialized table.
478  *
479  * \param col A pointer to a struct osl_column.
480  * \param desc Pointer to the table description.
481  * \param cd Pointer to struct osl_column_description.
482  *
483  * On each iteration, \a col will point to the next column of the table and \a
484  * cd will point to the column description of this column.
485  *
486  * \sa struct osl_column FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE,
487  * FOR_EACH_MAPPED_COLUMN, FOR_EACH_DISK_STORAGE_COLUMN,
488  * FOR_EACH_VOLATILE_COLUMN.
489  */
490 #define FOR_EACH_COLUMN(col, desc, cd) \
491         for (col = 0; col < (desc)->num_columns && \
492                 (cd = get_column_description(desc, col)); col++)
493
494 /**
495  * Iterate over each column with associated rbtree.
496  *
497  * \param col Same meaning as in FOR_EACH_COLUMN().
498  * \param table Same meaning as in FOR_EACH_COLUMN().
499  * \param cd Same meaning as in FOR_EACH_COLUMN().
500  *
501  * \sa osl_storage_flags::OSL_RBTREE, FOR_EACH_COLUMN, FOR_EACH_COLUMN_OF_TYPE,
502  * FOR_EACH_MAPPED_COLUMN, FOR_EACH_DISK_STORAGE_COLUMN,
503  * FOR_EACH_VOLATILE_COLUMN.
504  */
505 #define FOR_EACH_RBTREE_COLUMN(col, table, cd) \
506         for (col = next_rbtree_column(0, table, &cd); \
507         col < table->desc->num_columns; \
508         col = next_rbtree_column(++col, table, &cd))
509
510 /**
511  * Iterate over each column of given storage type.
512  *
513  * \param type The osl_storage_type to iterate over.
514  * \param col Same meaning as in FOR_EACH_COLUMN().
515  * \param table Same meaning as in FOR_EACH_COLUMN().
516  * \param cd Same meaning as in FOR_EACH_COLUMN().
517  *
518  * \sa osl_storage_type, FOR_EACH_COLUMN, FOR_EACH_RBTREE_COLUMN,
519  * FOR_EACH_MAPPED_COLUMN, FOR_EACH_DISK_STORAGE_COLUMN,
520  * FOR_EACH_VOLATILE_COLUMN.
521  */
522 #define FOR_EACH_COLUMN_OF_TYPE(type, col, table, cd) \
523         for (col = next_column_of_type(type, 0, table, &cd); \
524         col < table->desc->num_columns; \
525         col = next_column_of_type(type, ++col, table, &cd))
526
527 /**
528  * Iterate over each mapped column.
529  *
530  * \param col Same meaning as in FOR_EACH_COLUMN().
531  * \param table Same meaning as in FOR_EACH_COLUMN().
532  * \param cd Same meaning as in FOR_EACH_COLUMN().
533  *
534  * Just like FOR_EACH_COLUMN(), but skip columns which are
535  * not of type \p OSL_MAPPED_STORAGE.
536  *
537  * \sa osl_storage_flags::OSL_MAPPED_STORAGE, FOR_EACH_COLUMN,
538  * FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE,
539  * FOR_EACH_DISK_STORAGE_COLUMN, FOR_EACH_VOLATILE_COLUMN.
540  */
541 #define FOR_EACH_MAPPED_COLUMN(col, table, cd) \
542         FOR_EACH_COLUMN_OF_TYPE(OSL_MAPPED_STORAGE, col, table, cd)
543
544 /**
545  * Iterate over each disk storage column.
546  *
547  * \param col Same meaning as in FOR_EACH_COLUMN().
548  * \param table Same meaning as in FOR_EACH_COLUMN().
549  * \param cd Same meaning as in FOR_EACH_COLUMN().
550  *
551  * Just like FOR_EACH_COLUMN(), but skip columns which are
552  * not of type \p OSL_DISK_STORAGE.
553  *
554  * \sa osl_storage_flags::OSL_DISK_STORAGE, FOR_EACH_COLUMN,
555  * FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN,
556  * FOR_EACH_VOLATILE_COLUMN.
557  */
558 #define FOR_EACH_DISK_STORAGE_COLUMN(col, table, cd) \
559         FOR_EACH_COLUMN_OF_TYPE(OSL_DISK_STORAGE, col, table, cd)
560
561 /**
562  * Iterate over each volatile column.
563  *
564  * \param col Same meaning as in FOR_EACH_COLUMN().
565  * \param table Same meaning as in FOR_EACH_COLUMN().
566  * \param cd Same meaning as in FOR_EACH_COLUMN().
567  *
568  * Just like FOR_EACH_COLUMN(), but skip columns which are
569  * not of type \p OSL_NO_STORAGE.
570  *
571  * \sa osl_storage_flags::OSL_NO_STORAGE, FOR_EACH_COLUMN,
572  * FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN,
573  * FOR_EACH_DISK_STORAGE_COLUMN.
574  */
575 #define FOR_EACH_VOLATILE_COLUMN(col, table, cd) \
576         FOR_EACH_COLUMN_OF_TYPE(OSL_NO_STORAGE, col, table, cd)