X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb%2Fcheck.c;h=fa003b79aebabd28aed807c4f9ca1d65d3014d09;hp=b3b8c23104e5a4d770672d15f68acc6e8d7f875a;hb=c4c5fed020ba44b9930119672a36a1cb33aff090;hpb=735980539f488d6f6299ec710f4045abbb104d46;ds=sidebyside diff --git a/ccan/tdb/check.c b/ccan/tdb/check.c index b3b8c231..fa003b79 100644 --- a/ccan/tdb/check.c +++ b/ccan/tdb/check.c @@ -29,8 +29,9 @@ static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery) { struct tdb_header hdr; + uint32_t h1, h2; - if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), DOCONV()) == -1) + if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) return false; if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) goto corrupt; @@ -39,7 +40,12 @@ static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery) if (hdr.version != TDB_VERSION) goto corrupt; - if (hdr.hashcheck != hashcheck(tdb)) + if (hdr.rwlocks != 0 && hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC) + goto corrupt; + + tdb_header_hash(tdb, &h1, &h2); + if (hdr.magic1_hash && hdr.magic2_hash && + (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) goto corrupt; if (hdr.hash_size == 0) @@ -327,9 +333,17 @@ int tdb_check(struct tdb_context *tdb, struct tdb_record rec; bool found_recovery = false; tdb_len_t dead; - - if (tdb_lockall(tdb) == -1) - return -1; + bool locked; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return -1; + locked = true; + } /* Make sure we know true size of the underlying file. */ tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); @@ -444,12 +458,16 @@ int tdb_check(struct tdb_context *tdb, } free(hashes); - tdb_unlockall(tdb); + if (locked) { + tdb_unlockall_read(tdb); + } return 0; free: free(hashes); unlock: - tdb_unlockall(tdb); + if (locked) { + tdb_unlockall_read(tdb); + } return -1; }