X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fio.c;h=6c8f847b2b8bb19e29ce482d5a3a82c78779102c;hp=2bcee8a29a17665edf3a08a6b6264bdb7c446322;hb=6520c8318b9b8f2d92ae4b9f062788b7e4035aac;hpb=a0ac303da08672d4cfe5629b794b2651e1e98399 diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 2bcee8a2..6c8f847b 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -123,27 +123,13 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, bool probe) return 0; } -static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len) -{ - if (unlikely(!tdb->map_ptr)) - return NULL; - - /* FIXME: We can do a subset of this! */ - if (tdb->transaction) - return NULL; - - if (unlikely(tdb_oob(tdb, off + len, true) == -1)) - return NULL; - return (char *)tdb->map_ptr + off; -} - /* Either make a copy into pad and return that, or return ptr into mmap. */ /* Note: pad has to be a real object, so we can't get here if len * overflows size_t */ void *tdb_get(struct tdb_context *tdb, tdb_off_t off, void *pad, size_t len) { if (likely(!(tdb->flags & TDB_CONVERT))) { - void *ret = tdb_direct(tdb, off, len); + void *ret = tdb->methods->direct(tdb, off, len); if (ret) return ret; } @@ -205,7 +191,7 @@ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, int zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) { char buf[8192] = { 0 }; - void *p = tdb_direct(tdb, off, len); + void *p = tdb->methods->direct(tdb, off, len); if (p) { memset(p, 0, len); return 0; @@ -311,7 +297,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, tdb->ecode = TDB_ERR_IO; tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, "tdb_write failed at %llu len=%llu (%s)\n", - off, len, strerror(errno)); + (long long)off, (long long)len, + strerror(errno)); return -1; } } @@ -477,7 +464,7 @@ const void *tdb_access_read(struct tdb_context *tdb, const void *ret = NULL; if (likely(!(tdb->flags & TDB_CONVERT))) - ret = tdb_direct(tdb, off, len); + ret = tdb->methods->direct(tdb, off, len); if (!ret) { struct tdb_access_hdr *hdr; @@ -499,7 +486,7 @@ void *tdb_access_write(struct tdb_context *tdb, void *ret = NULL; if (likely(!(tdb->flags & TDB_CONVERT))) - ret = tdb_direct(tdb, off, len); + ret = tdb->methods->direct(tdb, off, len); if (!ret) { struct tdb_access_hdr *hdr; @@ -549,119 +536,22 @@ int tdb_access_commit(struct tdb_context *tdb, void *p) return ret; } -#if 0 -/* write a lump of data at a specified offset */ -static int tdb_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - if (len == 0) { - return 0; - } - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) { - memcpy(off + (char *)tdb->map_ptr, buf, len); - } else { - ssize_t written = pwrite(tdb->fd, buf, len, off); - if ((written != (ssize_t)len) && (written != -1)) { - /* try once more */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " - "%d of %d bytes at %d, trying once more\n", - (int)written, len, off)); - written = pwrite(tdb->fd, (const char *)buf+written, - len-written, - off+written); - } - if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d " - "len=%d (%s)\n", off, len, strerror(errno))); - return -1; - } else if (written != (ssize_t)len) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " - "write %d bytes at %d in two attempts\n", - len, off)); - return -1; - } - } - return 0; -} - - - -/* - do an unlocked scan of the hash table heads to find the next non-zero head. The value - will then be confirmed with the lock held -*/ -static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - if (tdb->map_ptr) { - for (;h < tdb->header.hash_size;h++) { - if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { - break; - } - } - } else { - uint32_t off=0; - for (;h < tdb->header.hash_size;h++) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { - break; - } - } - } - (*chain) = h; -} - -/* read/write a tdb_off_t */ -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); -} - -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - tdb_off_t off = *d; - return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); -} - - -/* read/write a record */ -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) +static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len) { - if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - if (TDB_BAD_MAGIC(rec)) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); - return -1; - } - return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0); -} + if (unlikely(!tdb->map_ptr)) + return NULL; -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) -{ - struct tdb_record r = *rec; - return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); + if (unlikely(tdb_oob(tdb, off + len, true) == -1)) + return NULL; + return (char *)tdb->map_ptr + off; } -#endif static const struct tdb_methods io_methods = { tdb_read, tdb_write, tdb_oob, tdb_expand_file, + tdb_direct, }; /*