Improve table versioning.
authorAndre Noll <maan@systemlinux.org>
Sun, 2 Aug 2009 10:31:07 +0000 (12:31 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 2 Aug 2009 10:38:38 +0000 (12:38 +0200)
This patch changes the way table version numbers are stored on disk.
Two version numbers instead of only one are stored in the table header:
The version of the lib that created the table, and the lowest version
number of the lib that can read the table.

As the latter is currently 0, it has no effect so far, i.e. tables
created with previous versions of the library still work fine. However,
with this change future versions of the library can detect from the
on-disk versions and the library version numbers if table and library
are compatible.

osl.c
osl_core.h

diff --git a/osl.c b/osl.c
index 430d120..90601dc 100644 (file)
--- a/osl.c
+++ b/osl.c
@@ -341,7 +341,7 @@ err:
 int read_table_desc(struct osl_object *map, struct osl_table_description *desc)
 {
        char *buf = map->data;
-       uint8_t version;
+       uint8_t version, compat_version, create_version;
        uint16_t header_size;
        int ret, i;
        unsigned offset;
@@ -352,7 +352,19 @@ int read_table_desc(struct osl_object *map, struct osl_table_description *desc)
        if (strncmp(buf + IDX_OSL_MAGIC, OSL_MAGIC, strlen(OSL_MAGIC)))
                return -E_OSL_NO_MAGIC;
        version = read_u8(buf + IDX_VERSION);
-       if (version < MIN_TABLE_VERSION || version > MAX_TABLE_VERSION)
+       /*
+        * The on-disk version consists of two version numbers: the
+        * create_version (low 4 bits) is the CURRENT_TABLE_VERSION version
+        * number of the library that created the table, and compat_version
+        * (high 4 bits) tells us the lowest version of the library that can
+        * still read this table.
+        */
+       create_version = version & 0xf;
+       compat_version = version >> 4;
+       INFO_LOG("create_version: %u, compat_version: %u\n", create_version,
+               compat_version);
+       if (create_version < MIN_TABLE_VERSION /* table too old */
+               || compat_version > CURRENT_TABLE_VERSION) /* libosl too old */
                return -E_OSL_VERSION_MISMATCH;
        desc->flags = read_u8(buf + IDX_TABLE_FLAGS);
        desc->num_columns = read_u16(buf + IDX_NUM_COLUMNS);
@@ -487,7 +499,8 @@ static int create_table_index(struct osl_table *t)
        sprintf(buf + IDX_OSL_MAGIC, "%s", OSL_MAGIC);
        write_u8(buf + IDX_TABLE_FLAGS, t->desc->flags);
        write_u8(buf + IDX_DIRTY_FLAG, 0);
-       write_u8(buf + IDX_VERSION, CURRENT_TABLE_VERSION);
+       write_u8(buf + IDX_VERSION, CURRENT_TABLE_VERSION
+               + (COMPAT_TABLE_VERSION << 4));
        write_u16(buf + IDX_NUM_COLUMNS, t->num_mapped_columns + t->num_disk_storage_columns);
        write_u16(buf + IDX_HEADER_SIZE, t->index_header_size);
        offset = IDX_COLUMN_DESCRIPTIONS;
index 6c87d6c..1220a09 100644 (file)
@@ -190,9 +190,27 @@ _static_inline_ size_t index_column_description_size(const char *name)
        return MIN_IDX_COLUMN_DESCRIPTION_SIZE + strlen(name) - 1;
 }
 
+/*
+ * The version used by this instance of the library. Written to the index of
+ * newly created tables.
+ */
 #define CURRENT_TABLE_VERSION 1
+
+/*
+ * The lowest library version that is able to use tables of version
+ * CURRENT_TABLE_VERSION. Also written to the index of new tables. If
+ * compat_version(table) > current_version(lib) the table can not be opened.
+ */
+#define COMPAT_TABLE_VERSION 0
+
+/*
+ * The lowest table version this library understands. On open, if
+ * current_version(table) < min_version(lib) the osl_open_table() call
+ * fails.
+ */
 #define MIN_TABLE_VERSION 1
-#define MAX_TABLE_VERSION 1
+
+
 /** An index header must be at least that many bytes long. */
 #define MIN_INDEX_HEADER_SIZE(num_cols) (MIN_IDX_COLUMN_DESCRIPTION_SIZE \
        * num_cols + IDX_COLUMN_DESCRIPTIONS)