run-64-bit-tdb.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "ntdb-source.h"
  2. #include "tap-interface.h"
  3. #include "logging.h"
  4. #include "helprun-external-agent.h"
  5. /* The largest 32-bit value which is still a multiple of NTDB_PGSIZE */
  6. #define ALMOST_4G ((uint32_t)-NTDB_PGSIZE)
  7. /* And this pushes it over 32 bits */
  8. #define A_LITTLE_BIT (NTDB_PGSIZE * 2)
  9. int main(int argc, char *argv[])
  10. {
  11. unsigned int i;
  12. struct ntdb_context *ntdb;
  13. int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
  14. NTDB_CONVERT,
  15. NTDB_NOMMAP|NTDB_CONVERT };
  16. if (sizeof(off_t) <= 4) {
  17. plan_tests(1);
  18. pass("No 64 bit off_t");
  19. return exit_status();
  20. }
  21. plan_tests(sizeof(flags) / sizeof(flags[0]) * 16);
  22. for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
  23. off_t old_size;
  24. NTDB_DATA k, d;
  25. struct hash_info h;
  26. struct ntdb_used_record rec;
  27. ntdb_off_t off;
  28. ntdb = ntdb_open("run-64-bit-ntdb.ntdb", flags[i]|MAYBE_NOSYNC,
  29. O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
  30. ok1(ntdb);
  31. if (!ntdb)
  32. continue;
  33. old_size = ntdb->file->map_size;
  34. /* Add a fake record to chew up the existing free space. */
  35. k = ntdb_mkdata("fake", 4);
  36. d.dsize = ntdb->file->map_size
  37. - NEW_DATABASE_HDR_SIZE(ntdb->hash_bits) - 8;
  38. d.dptr = malloc(d.dsize);
  39. memset(d.dptr, 0, d.dsize);
  40. ok1(ntdb_store(ntdb, k, d, NTDB_INSERT) == 0);
  41. ok1(ntdb->file->map_size == old_size);
  42. free(d.dptr);
  43. /* This makes a sparse file */
  44. ok1(ftruncate(ntdb->file->fd, ALMOST_4G) == 0);
  45. ok1(add_free_record(ntdb, old_size, ALMOST_4G - old_size,
  46. NTDB_LOCK_WAIT, false) == NTDB_SUCCESS);
  47. /* Now add a little record past the 4G barrier. */
  48. ok1(ntdb_expand_file(ntdb, A_LITTLE_BIT) == NTDB_SUCCESS);
  49. ok1(add_free_record(ntdb, ALMOST_4G, A_LITTLE_BIT,
  50. NTDB_LOCK_WAIT, false)
  51. == NTDB_SUCCESS);
  52. ok1(ntdb_check(ntdb, NULL, NULL) == NTDB_SUCCESS);
  53. /* Test allocation path. */
  54. k = ntdb_mkdata("key", 4);
  55. d = ntdb_mkdata("data", 5);
  56. ok1(ntdb_store(ntdb, k, d, NTDB_INSERT) == 0);
  57. ok1(ntdb_check(ntdb, NULL, NULL) == NTDB_SUCCESS);
  58. /* Make sure it put it at end as we expected. */
  59. off = find_and_lock(ntdb, k, F_RDLCK, &h, &rec, NULL);
  60. ok1(off >= ALMOST_4G);
  61. ntdb_unlock_hash(ntdb, h.h, F_RDLCK);
  62. ok1(ntdb_fetch(ntdb, k, &d) == 0);
  63. ok1(d.dsize == 5);
  64. ok1(strcmp((char *)d.dptr, "data") == 0);
  65. free(d.dptr);
  66. ok1(ntdb_delete(ntdb, k) == 0);
  67. ok1(ntdb_check(ntdb, NULL, NULL) == NTDB_SUCCESS);
  68. ntdb_close(ntdb);
  69. }
  70. /* We might get messages about mmap failing, so don't test
  71. * tap_log_messages */
  72. return exit_status();
  73. }