diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2011-12-05 17:04:30 +1030 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-12-05 17:04:30 +1030 |
commit | 80c3ba8123ed6708ebf3afad9ed78037e571a81d (patch) | |
tree | 242254821b79c3301e4af95b8c38ae8beeb04cba /lib/tdb2/test/layout.c | |
parent | 3f99fc16a0a3aead82cf8cdfb9703f8f18388623 (diff) | |
download | samba-80c3ba8123ed6708ebf3afad9ed78037e571a81d.tar.gz samba-80c3ba8123ed6708ebf3afad9ed78037e571a81d.tar.bz2 samba-80c3ba8123ed6708ebf3afad9ed78037e571a81d.zip |
tdb2: add a capability list from the header.
This allows even more extensibility in future: in particular, the top
bits of each capability tell us what to do if we don't understand it:
fail the open, fail to open for write, or don't try to check the
format.
tdb_check needs to understand the capability list so it can know to
skip over it: each element in the list is prefixed with the type tag
and the length.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
(Imported from CCAN commit 35f198de1851a7d57064546b7ced677b6fabee27)
Diffstat (limited to 'lib/tdb2/test/layout.c')
-rw-r--r-- | lib/tdb2/test/layout.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/lib/tdb2/test/layout.c b/lib/tdb2/test/layout.c index 6c601ddb85..0bce5dd89e 100644 --- a/lib/tdb2/test/layout.c +++ b/lib/tdb2/test/layout.c @@ -39,6 +39,26 @@ void tdb_layout_add_free(struct tdb_layout *layout, tdb_len_t len, add(layout, elem); } +void tdb_layout_add_capability(struct tdb_layout *layout, + uint64_t type, + bool write_breaks, + bool check_breaks, + bool open_breaks, + tdb_len_t extra) +{ + union tdb_layout_elem elem; + elem.base.type = CAPABILITY; + elem.capability.type = type; + if (write_breaks) + elem.capability.type |= TDB_CAP_NOWRITE; + if (open_breaks) + elem.capability.type |= TDB_CAP_NOOPEN; + if (check_breaks) + elem.capability.type |= TDB_CAP_NOCHECK; + elem.capability.extra = extra; + add(layout, elem); +} + static struct tdb_data dup_key(struct tdb_data key) { struct tdb_data ret; @@ -81,6 +101,11 @@ static tdb_len_t hashtable_len(struct tle_hashtable *htable) + htable->extra; } +static tdb_len_t capability_len(struct tle_capability *cap) +{ + return sizeof(struct tdb_capability) + cap->extra; +} + static tdb_len_t freetable_len(struct tle_freetable *ftable) { return sizeof(struct tdb_freetable); @@ -122,6 +147,26 @@ static void set_hashtable(void *mem, struct tdb_context *tdb, add_zero_pad(u, len, htable->extra); } +static void set_capability(void *mem, struct tdb_context *tdb, + struct tle_capability *cap, struct tdb_header *hdr, + tdb_off_t last_cap) +{ + struct tdb_capability *c = mem; + tdb_len_t len = sizeof(*c) - sizeof(struct tdb_used_record) + cap->extra; + + c->type = cap->type; + c->next = 0; + set_header(tdb, &c->hdr, TDB_CAP_MAGIC, 0, len, len, 0); + + /* Append to capability list. */ + if (!last_cap) { + hdr->capabilities = cap->base.off; + } else { + c = (struct tdb_capability *)((char *)hdr + last_cap); + c->next = cap->base.off; + } +} + static void set_freetable(void *mem, struct tdb_context *tdb, struct tle_freetable *freetable, struct tdb_header *hdr, tdb_off_t last_ftable) @@ -228,10 +273,11 @@ static struct tle_freetable *find_ftable(struct tdb_layout *layout, unsigned num /* FIXME: Support TDB_CONVERT */ struct tdb_context *tdb_layout_get(struct tdb_layout *layout, + void (*freefn)(void *), union tdb_attribute *attr) { unsigned int i; - tdb_off_t off, len, last_ftable; + tdb_off_t off, len, last_ftable, last_cap; char *mem; struct tdb_context *tdb; @@ -254,6 +300,9 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout, case HASHTABLE: len = hashtable_len(&e->hashtable); break; + case CAPABILITY: + len = capability_len(&e->capability); + break; default: abort(); } @@ -268,11 +317,12 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout, memcpy(mem, tdb->file->map_ptr, sizeof(struct tdb_header)); /* Mug the tdb we have to make it use this. */ - free(tdb->file->map_ptr); + freefn(tdb->file->map_ptr); tdb->file->map_ptr = mem; tdb->file->map_size = off; last_ftable = 0; + last_cap = 0; for (i = 0; i < layout->num_elems; i++) { union tdb_layout_elem *e = &layout->elem[i]; switch (e->base.type) { @@ -290,6 +340,11 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout, case HASHTABLE: set_hashtable(mem + e->base.off, tdb, &e->hashtable); break; + case CAPABILITY: + set_capability(mem + e->base.off, tdb, &e->capability, + (struct tdb_header *)mem, last_cap); + last_cap = e->base.off; + break; } } /* Must have a free table! */ @@ -316,10 +371,10 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout, return tdb; } -void tdb_layout_write(struct tdb_layout *layout, union tdb_attribute *attr, - const char *filename) +void tdb_layout_write(struct tdb_layout *layout, void (*freefn)(void *), + union tdb_attribute *attr, const char *filename) { - struct tdb_context *tdb = tdb_layout_get(layout, attr); + struct tdb_context *tdb = tdb_layout_get(layout, freefn, attr); int fd; fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600); |