X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Ftransaction.c;h=6e0b1669fcd9fa1e2276282e621856f1f8236c3c;hp=92658026ac9c006c5e6f9bf31b99f77bb116abc6;hb=f5087965ebdb24618ca59854b7a819e21c9fdf78;hpb=4e185ad8ab5a7e01edbbe12d11eb2f1577de7e8b diff --git a/ccan/tdb2/transaction.c b/ccan/tdb2/transaction.c index 92658026..6e0b1669 100644 --- a/ccan/tdb2/transaction.c +++ b/ccan/tdb2/transaction.c @@ -363,10 +363,39 @@ static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t addition) } static void *transaction_direct(struct tdb_context *tdb, tdb_off_t off, - size_t len) + size_t len, bool write) { - /* FIXME */ - return NULL; + size_t blk = off / getpagesize(), end_blk; + + /* This is wrong for zero-length blocks, but will fail gracefully */ + end_blk = (off + len - 1) / getpagesize(); + + /* Can only do direct if in single block and we've already copied. */ + if (write) { + if (blk != end_blk) + return NULL; + if (blk >= tdb->transaction->num_blocks) + return NULL; + if (tdb->transaction->blocks[blk] == NULL) + return NULL; + return tdb->transaction->blocks[blk] + off % getpagesize(); + } + + /* Single which we have copied? */ + if (blk == end_blk + && blk < tdb->transaction->num_blocks + && tdb->transaction->blocks[blk]) + return tdb->transaction->blocks[blk] + off % getpagesize(); + + /* Otherwise must be all not copied. */ + while (blk < end_blk) { + if (blk >= tdb->transaction->num_blocks) + break; + if (tdb->transaction->blocks[blk]) + return NULL; + blk++; + } + return tdb->transaction->io_methods->direct(tdb, off, len, write); } static const struct tdb_methods transaction_methods = {