check:
                        if (check) {
                                TDB_DATA key, data;
-                               key.dsize = rec_key_length(&rec);
-                               data.dsize = rec_data_length(&rec);
-                               key.dptr = (void *)tdb_access_read(tdb,
-                                                  off + sizeof(rec),
-                                                  key.dsize + data.dsize,
-                                                  false);
-                               if (TDB_PTR_IS_ERR(key.dptr)) {
-                                       ecode = TDB_PTR_ERR(key.dptr);
+                               const unsigned char *kptr;
+
+                               kptr = tdb_access_read(tdb,
+                                                      off + sizeof(rec),
+                                                      rec_key_length(&rec)
+                                                      + rec_data_length(&rec),
+                                                      false);
+                               if (TDB_PTR_IS_ERR(kptr)) {
+                                       ecode = TDB_PTR_ERR(kptr);
                                        goto fail;
                                }
-                               data.dptr = key.dptr + key.dsize;
+
+                               key = tdb_mkdata(kptr, rec_key_length(&rec));
+                               data = tdb_mkdata(kptr + key.dsize,
+                                                 rec_data_length(&rec));
                                ecode = check(key, data, private_data);
+                               tdb_access_release(tdb, kptr);
                                if (ecode != TDB_SUCCESS) {
                                        goto fail;
                                }
-                               tdb_access_release(tdb, key.dptr);
                        }
                }
        }
 
 #include <ccan/tdb2/tdb2.h>
 #include <ccan/likely/likely.h>
 #include <ccan/compiler/compiler.h>
-#include <ccan/cast/cast.h>
 #if HAVE_BYTESWAP_H
 #include <byteswap.h>
 #endif
 
        tdb_off_t off;
        struct tdb_used_record rec;
        struct hash_info h;
-       TDB_DATA data;
        enum TDB_ERROR ecode;
 
        off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL);
        if (!off) {
                ecode = TDB_ERR_NOEXIST;
        } else {
-               data.dsize = rec_data_length(&rec);
-               data.dptr = (void *)tdb_access_read(tdb,
-                                                   off + sizeof(rec)
-                                                   + key.dsize,
-                                                   data.dsize, false);
-               if (TDB_PTR_IS_ERR(data.dptr)) {
-                       ecode = TDB_PTR_ERR(data.dptr);
+               const void *dptr;
+               dptr = tdb_access_read(tdb, off + sizeof(rec) + key.dsize,
+                                      rec_data_length(&rec), false);
+               if (TDB_PTR_IS_ERR(dptr)) {
+                       ecode = TDB_PTR_ERR(dptr);
                } else {
+                       TDB_DATA data = tdb_mkdata(dptr, rec_data_length(&rec));
+
                        ecode = parse(key, data, p);
-                       tdb_access_release(tdb, data.dptr);
+                       tdb_access_release(tdb, dptr);
                }
        }
 
 
 #endif
 #include <ccan/compiler/compiler.h>
 #include <ccan/typesafe_cb/typesafe_cb.h>
+#include <ccan/cast/cast.h>
 
 union tdb_attribute;
 struct tdb_context;
        return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0;
 }
 
+/**
+ * tdb_mkdata - make a struct tdb_data from const data
+ * @p: the constant pointer
+ * @len: the length
+ *
+ * As the dptr member of struct tdb_data is not constant, you need to
+ * cast it.  This function keeps thost casts in one place, as well as
+ * suppressing the warning some compilers give when casting away a
+ * qualifier (eg. gcc with -Wcast-qual)
+ */
+static inline struct tdb_data tdb_mkdata(const void *p, size_t len)
+{
+       struct tdb_data d;
+       d.dptr = cast_const(void *, p);
+       d.dsize = len;
+       return d;
+}
+
 /**
  * tdb_transaction_start - start a transaction
  * @tdb: the tdb context returned from tdb_open()
 
 
        diag("external: %s", operation_name(op));
 
-       k.dptr = (void *)name;
-       k.dsize = strlen(name);
+       k = tdb_mkdata(name, strlen(name));
 
        locking_would_block = 0;
        switch (op) {
 
        /* FIXME: Test TDB_CONVERT */
 
        plan_tests(38);
-       data.dptr = (void *)"world";
-       data.dsize = 5;
-       key.dptr = (void *)"hello";
-       key.dsize = 5;
+       data = tdb_mkdata("world", 5);
+       key = tdb_mkdata("hello", 5);
 
        /* No coalescing can be done due to EOF */
        layout = new_tdb_layout("run-03-coalesce.tdb");
 
 /* We rig the hash so adjacent-numbered records always clash. */
 static uint64_t clash(const void *key, size_t len, uint64_t seed, void *priv)
 {
-       return ((uint64_t)*(unsigned int *)key)
+       return ((uint64_t)*(const unsigned int *)key)
                << (64 - TDB_TOPLEVEL_HASH_BITS - 1);
 }
 
 
        int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
                        TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, 
                        TDB_NOMMAP|TDB_CONVERT };
-       struct tdb_data key = { (unsigned char *)"key", 3 };
-       struct tdb_data data = { (unsigned char *)"data", 4 };
+       struct tdb_data key = tdb_mkdata("key", 3);
+       struct tdb_data data = tdb_mkdata("data", 4);
 
        failtest_init(argc, argv);
        failtest_hook = suppress_failure;
 
        int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
                        TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, 
                        TDB_NOMMAP|TDB_CONVERT };
-       struct tdb_data key = { (unsigned char *)"key", 3 };
-       struct tdb_data data = { (unsigned char *)"data", 4 };
+       struct tdb_data key = tdb_mkdata("key", 3);
+       struct tdb_data data = tdb_mkdata("data", 4);
 
        failtest_init(argc, argv);
        failtest_hook = suppress_failure;
 
 /* We rig the hash so adjacent-numbered records always clash. */
 static uint64_t clash(const void *key, size_t len, uint64_t seed, void *priv)
 {
-       return ((uint64_t)*(unsigned int *)key)
+       return ((uint64_t)*(const unsigned int *)key)
                << (64 - TDB_TOPLEVEL_HASH_BITS - 1);
 }
 
 
        int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
                        TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, 
                        TDB_NOMMAP|TDB_CONVERT };
-       struct tdb_data key = { (unsigned char *)"key", 3 };
+       struct tdb_data key = tdb_mkdata("key", 3);
        struct tdb_data data;
 
        buffer = malloc(MAX_SIZE);
 
 
 static uint64_t myhash(const void *key, size_t len, uint64_t seed, void *priv)
 {
-       return *(uint64_t *)key;
+       return *(const uint64_t *)key;
 }
 
 static void add_bits(uint64_t *val, unsigned new, unsigned new_bits,
 
        TDB_DATA key, data;
 
        plan_tests(11);
-       key.dptr = (unsigned char *)"Hello";
-       data.dptr = (unsigned char *)"world";
-       data.dsize = 5;
-       key.dsize = 5;
+       key = tdb_mkdata("Hello", 5);
+       data = tdb_mkdata("world", 5);
 
        /* Create a TDB with three free tables. */
        layout = new_tdb_layout(NULL);
 
        unsigned char *buffer;
        int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
                        TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT };
-       struct tdb_data key = { (unsigned char *)"key", 3 };
+       struct tdb_data key = tdb_mkdata("key", 3);
        struct tdb_data data;
 
        buffer = malloc(1000);
 
 
                opened = true;
                ok1(tdb_transaction_start(tdb) == 0);
-               key.dsize = strlen("hi");
-               key.dptr = (void *)"hi";
-               data.dptr = (void *)"world";
-               data.dsize = strlen("world");
+               key = tdb_mkdata("hi", strlen("hi"));
+               data = tdb_mkdata("world", strlen("world"));
 
                ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
                ok1(tdb_transaction_commit(tdb) == 0);
 
        }
 
        /* Put key for agent to fetch. */
-       key.dsize = strlen(KEY_STRING);
-       key.dptr = (void *)KEY_STRING;
+       key = tdb_mkdata(KEY_STRING, strlen(KEY_STRING));
        if (tdb_store(tdb, key, key, TDB_INSERT) != 0)
                return false;
 
 
        unsigned int i;
        struct tdb_context *tdb;
        struct tdb_data d = { NULL, 0 }; /* Bogus GCC warning */
-       struct tdb_data key = { (unsigned char *)"key", 3 };
-       struct tdb_data data = { (unsigned char *)"data", 4 };
+       struct tdb_data key = tdb_mkdata("key", 3);
+       struct tdb_data data = tdb_mkdata("data", 4);
        int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
                        TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
                        TDB_NOMMAP|TDB_CONVERT };
 
        int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
                        TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, 
                        TDB_NOMMAP|TDB_CONVERT };
-       struct tdb_data key = { (unsigned char *)"key", 3 };
+       struct tdb_data key = tdb_mkdata("key", 3);
        struct tdb_data data;
 
        data.dptr = malloc(MAX_SIZE);
 
        unsigned int i;
        struct agent *agent;
        struct tdb_context *tdb;
-       struct tdb_data d = { (unsigned char *)"hello", 5 };
+       struct tdb_data d = tdb_mkdata("hello", 5);
        const char filename[] = "run-remap-in-read_traverse.tdb";
 
        plan_tests(4);
 
        int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
                        TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, 
                        TDB_NOMMAP|TDB_CONVERT };
-       struct tdb_data key = { (unsigned char *)"key", 3 };
-       struct tdb_data data = { (unsigned char *)"data", 4 };
+       struct tdb_data key = tdb_mkdata("key", 3);
+       struct tdb_data data = tdb_mkdata("data", 4);
 
        plan_tests(sizeof(flags) / sizeof(flags[0]) * 7 + 1);
        for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {