Changeset 740 for vendor/current/lib/tdb/common/check.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified vendor/current/lib/tdb/common/check.c ¶
r414 r740 29 29 { 30 30 struct tdb_header hdr; 31 32 if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), DOCONV()) == -1) 31 uint32_t h1, h2; 32 33 if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) 33 34 return false; 34 35 if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) … … 39 40 goto corrupt; 40 41 41 if (hdr.rwlocks != 0) 42 if (hdr.rwlocks != 0 && hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC) 43 goto corrupt; 44 45 tdb_header_hash(tdb, &h1, &h2); 46 if (hdr.magic1_hash && hdr.magic2_hash && 47 (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) 42 48 goto corrupt; 43 49 … … 302 308 } 303 309 304 int tdb_check(struct tdb_context *tdb, 310 /* Slow, but should be very rare. */ 311 size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off) 312 { 313 size_t len; 314 315 for (len = 0; off + len < tdb->map_size; len++) { 316 char c; 317 if (tdb->methods->tdb_read(tdb, off, &c, 1, 0)) 318 return 0; 319 if (c != 0 && c != 0x42) 320 break; 321 } 322 return len; 323 } 324 325 _PUBLIC_ int tdb_check(struct tdb_context *tdb, 305 326 int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), 306 327 void *private_data) … … 311 332 struct tdb_record rec; 312 333 bool found_recovery = false; 313 314 if (tdb_lockall(tdb) == -1) 315 return -1; 334 tdb_len_t dead; 335 bool locked; 336 337 /* Read-only databases use no locking at all: it's best-effort. 338 * We may have a write lock already, so skip that case too. */ 339 if (tdb->read_only || tdb->allrecord_lock.count != 0) { 340 locked = false; 341 } else { 342 if (tdb_lockall_read(tdb) == -1) 343 return -1; 344 locked = true; 345 } 316 346 317 347 /* Make sure we know true size of the underlying file. */ … … 370 400 goto free; 371 401 break; 402 /* If we crash after ftruncate, we can get zeroes or fill. */ 403 case TDB_RECOVERY_INVALID_MAGIC: 404 case 0x42424242: 405 if (recovery_start == off) { 406 found_recovery = true; 407 break; 408 } 409 dead = tdb_dead_space(tdb, off); 410 if (dead < sizeof(rec)) 411 goto corrupt; 412 413 TDB_LOG((tdb, TDB_DEBUG_ERROR, 414 "Dead space at %d-%d (of %u)\n", 415 off, off + dead, tdb->map_size)); 416 rec.rec_len = dead - sizeof(rec); 417 break; 372 418 case TDB_RECOVERY_MAGIC: 373 case 0: /* Used for invalid (or in-progress) recovery area. */374 419 if (recovery_start != off) { 375 420 TDB_LOG((tdb, TDB_DEBUG_ERROR, … … 380 425 found_recovery = true; 381 426 break; 382 default: 427 default: ; 428 corrupt: 383 429 tdb->ecode = TDB_ERR_CORRUPT; 384 430 TDB_LOG((tdb, TDB_DEBUG_ERROR, … … 406 452 if (recovery_start != 0 && !found_recovery) { 407 453 TDB_LOG((tdb, TDB_DEBUG_ERROR, 408 "Expected %s recovery area, got %s\n", 409 recovery_start ? "a" : "no", 410 found_recovery ? "one" : "none")); 454 "Expected a recovery area at %u\n", 455 recovery_start)); 411 456 goto free; 412 457 } 413 458 414 459 free(hashes); 415 tdb_unlockall(tdb); 460 if (locked) { 461 tdb_unlockall_read(tdb); 462 } 416 463 return 0; 417 464 … … 419 466 free(hashes); 420 467 unlock: 421 tdb_unlockall(tdb); 468 if (locked) { 469 tdb_unlockall_read(tdb); 470 } 422 471 return -1; 423 472 }
Note:
See TracChangeset
for help on using the changeset viewer.