X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Ftdb.c;h=a7aa4572382b0f8b10ef03c4adc08599fd7e7293;hp=7484695d7ab9a8724eb178e82bf3e1a9e52a58e2;hb=98c754ffe65bc335f66161d6cc8705d4ea2710ec;hpb=6e3d9e8a66bf8b45150500f176452ee8e9ee9927 diff --git a/ccan/tdb2/tdb.c b/ccan/tdb2/tdb.c index 7484695d..a7aa4572 100644 --- a/ccan/tdb2/tdb.c +++ b/ccan/tdb2/tdb.c @@ -70,13 +70,13 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb, } new_off += sizeof(struct tdb_used_record); - ecode = tdb->methods->twrite(tdb, new_off, key.dptr, key.dsize); + ecode = tdb->tdb2.io->twrite(tdb, new_off, key.dptr, key.dsize); if (ecode != TDB_SUCCESS) { return ecode; } new_off += key.dsize; - ecode = tdb->methods->twrite(tdb, new_off, dbuf.dptr, dbuf.dsize); + ecode = tdb->tdb2.io->twrite(tdb, new_off, dbuf.dptr, dbuf.dsize); if (ecode != TDB_SUCCESS) { return ecode; } @@ -94,10 +94,10 @@ static enum TDB_ERROR update_data(struct tdb_context *tdb, { enum TDB_ERROR ecode; - ecode = tdb->methods->twrite(tdb, off, dbuf.dptr, dbuf.dsize); + ecode = tdb->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize); if (ecode == TDB_SUCCESS && extra) { /* Put a zero in; future versions may append other data. */ - ecode = tdb->methods->twrite(tdb, off + dbuf.dsize, "", 1); + ecode = tdb->tdb2.io->twrite(tdb, off + dbuf.dsize, "", 1); } if (tdb->flags & TDB_SEQNUM) tdb_inc_seqnum(tdb); @@ -114,6 +114,12 @@ enum TDB_ERROR tdb_store(struct tdb_context *tdb, struct tdb_used_record rec; enum TDB_ERROR ecode; + if (tdb->flags & TDB_VERSION1) { + if (tdb1_store(tdb, key, dbuf, flag) == -1) + return tdb->last_error; + return TDB_SUCCESS; + } + off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { return tdb->last_error = off; @@ -211,7 +217,7 @@ enum TDB_ERROR tdb_append(struct tdb_context *tdb, + dbuf.dsize)); goto out; } - ecode = tdb->methods->tread(tdb, off + sizeof(rec) + key.dsize, + ecode = tdb->tdb2.io->tread(tdb, off + sizeof(rec) + key.dsize, newdata, old_dlen); if (ecode != TDB_SUCCESS) { goto out_free_newdata; @@ -324,6 +330,37 @@ unsigned int tdb_get_flags(struct tdb_context *tdb) return tdb->flags; } +static bool inside_transaction(const struct tdb_context *tdb) +{ + if (tdb->flags & TDB_VERSION1) + return tdb->tdb1.transaction != NULL; + else + return tdb->tdb2.transaction != NULL; +} + +static bool readonly_changable(struct tdb_context *tdb, const char *caller) +{ + if (inside_transaction(tdb)) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "%s: can't change" + " TDB_RDONLY inside transaction", + caller); + return false; + } + + if (tdb->file->allrecord_lock.count != 0 + || tdb->file->num_lockrecs != 0) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "%s: can't change" + " TDB_RDONLY holding locks", + caller); + return false; + } + return true; +} + void tdb_add_flag(struct tdb_context *tdb, unsigned flag) { if (tdb->flags & TDB_INTERNAL) { @@ -349,6 +386,10 @@ void tdb_add_flag(struct tdb_context *tdb, unsigned flag) case TDB_ALLOW_NESTING: tdb->flags |= TDB_ALLOW_NESTING; break; + case TDB_RDONLY: + if (readonly_changable(tdb, "tdb_add_flag")) + tdb->flags |= TDB_RDONLY; + break; default: tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, @@ -382,6 +423,18 @@ void tdb_remove_flag(struct tdb_context *tdb, unsigned flag) case TDB_ALLOW_NESTING: tdb->flags &= ~TDB_ALLOW_NESTING; break; + case TDB_RDONLY: + if ((tdb->open_flags & O_ACCMODE) == O_RDONLY) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_remove_flag: can't" + " remove TDB_RDONLY on tdb" + " opened with O_RDONLY"); + break; + } + if (readonly_changable(tdb, "tdb_remove_flag")) + tdb->flags &= ~TDB_RDONLY; + break; default: tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,