conv.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. /*
  5. * disk structure conversion routines
  6. */
  7. #define U8GET(p) ((p)[0])
  8. #define U16GET(p) (((p)[0]<<8)|(p)[1])
  9. #define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
  10. #define U64GET(p) (((u64int)U32GET(p)<<32)|(u64int)U32GET((p)+4))
  11. #define U8PUT(p,v) (p)[0]=(v)&0xFF
  12. #define U16PUT(p,v) (p)[0]=((v)>>8)&0xFF;(p)[1]=(v)&0xFF
  13. #define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
  14. #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
  15. int debugarena = -1; /* hack to improve error reporting */
  16. static struct {
  17. u32int m;
  18. char *s;
  19. } magics[] = {
  20. ArenaPartMagic, "ArenaPartMagic",
  21. ArenaHeadMagic, "ArenaHeadMagic",
  22. ArenaMagic, "ArenaMagic",
  23. ISectMagic, "ISectMagic",
  24. BloomMagic, "BloomMagic",
  25. };
  26. static char*
  27. fmtmagic(char *s, u32int m)
  28. {
  29. int i;
  30. for(i=0; i<nelem(magics); i++)
  31. if(magics[i].m == m)
  32. return magics[i].s;
  33. sprint(s, "%#08ux", m);
  34. return s;
  35. }
  36. u32int
  37. unpackmagic(u8int *buf)
  38. {
  39. return U32GET(buf);
  40. }
  41. void
  42. packmagic(u32int magic, u8int *buf)
  43. {
  44. U32PUT(buf, magic);
  45. }
  46. int
  47. unpackarenapart(ArenaPart *ap, u8int *buf)
  48. {
  49. u8int *p;
  50. u32int m;
  51. char fbuf[20];
  52. p = buf;
  53. m = U32GET(p);
  54. if(m != ArenaPartMagic){
  55. seterr(ECorrupt, "arena set has wrong magic number: %s expected ArenaPartMagic (%#lux)", fmtmagic(fbuf, m), ArenaPartMagic);
  56. return -1;
  57. }
  58. p += U32Size;
  59. ap->version = U32GET(p);
  60. p += U32Size;
  61. ap->blocksize = U32GET(p);
  62. p += U32Size;
  63. ap->arenabase = U32GET(p);
  64. p += U32Size;
  65. if(buf + ArenaPartSize != p)
  66. sysfatal("unpackarenapart unpacked wrong amount");
  67. return 0;
  68. }
  69. int
  70. packarenapart(ArenaPart *ap, u8int *buf)
  71. {
  72. u8int *p;
  73. p = buf;
  74. U32PUT(p, ArenaPartMagic);
  75. p += U32Size;
  76. U32PUT(p, ap->version);
  77. p += U32Size;
  78. U32PUT(p, ap->blocksize);
  79. p += U32Size;
  80. U32PUT(p, ap->arenabase);
  81. p += U32Size;
  82. if(buf + ArenaPartSize != p)
  83. sysfatal("packarenapart packed wrong amount");
  84. return 0;
  85. }
  86. int
  87. unpackarena(Arena *arena, u8int *buf)
  88. {
  89. int sz;
  90. u8int *p;
  91. u32int m;
  92. char fbuf[20];
  93. p = buf;
  94. m = U32GET(p);
  95. if(m != ArenaMagic){
  96. seterr(ECorrupt, "arena %d has wrong magic number: %s "
  97. "expected ArenaMagic (%#lux)", debugarena,
  98. fmtmagic(fbuf, m), ArenaMagic);
  99. return -1;
  100. }
  101. p += U32Size;
  102. arena->version = U32GET(p);
  103. p += U32Size;
  104. namecp(arena->name, (char*)p);
  105. p += ANameSize;
  106. arena->diskstats.clumps = U32GET(p);
  107. p += U32Size;
  108. arena->diskstats.cclumps = U32GET(p);
  109. p += U32Size;
  110. arena->ctime = U32GET(p);
  111. p += U32Size;
  112. arena->wtime = U32GET(p);
  113. p += U32Size;
  114. if(arena->version == ArenaVersion5){
  115. arena->clumpmagic = U32GET(p);
  116. p += U32Size;
  117. }
  118. arena->diskstats.used = U64GET(p);
  119. p += U64Size;
  120. arena->diskstats.uncsize = U64GET(p);
  121. p += U64Size;
  122. arena->diskstats.sealed = U8GET(p);
  123. p += U8Size;
  124. switch(arena->version){
  125. case ArenaVersion4:
  126. sz = ArenaSize4;
  127. arena->clumpmagic = _ClumpMagic;
  128. break;
  129. case ArenaVersion5:
  130. sz = ArenaSize5;
  131. break;
  132. default:
  133. seterr(ECorrupt, "arena has bad version number %d", arena->version);
  134. return -1;
  135. }
  136. /*
  137. * Additional fields for the memstats version of the stats.
  138. * Diskstats reflects what is committed to the index.
  139. * Memstats reflects what is in the arena. Originally intended
  140. * this to be a version 5 extension, but might as well use for
  141. * all the existing version 4 arenas too.
  142. *
  143. * To maintain backwards compatibility with existing venti
  144. * installations using the older format, we define that if
  145. * memstats == diskstats, then the extension fields are not
  146. * included (see packarena below). That is, only partially
  147. * indexed arenas have these fields. Fully indexed arenas
  148. * (in particular, sealed arenas) do not.
  149. */
  150. if(U8GET(p) == 1){
  151. sz += ArenaSize5a-ArenaSize5;
  152. p += U8Size;
  153. arena->memstats.clumps = U32GET(p);
  154. p += U32Size;
  155. arena->memstats.cclumps = U32GET(p);
  156. p += U32Size;
  157. arena->memstats.used = U64GET(p);
  158. p += U64Size;
  159. arena->memstats.uncsize = U64GET(p);
  160. p += U64Size;
  161. arena->memstats.sealed = U8GET(p);
  162. p += U8Size;
  163. /*
  164. * 2008/4/2
  165. * Packarena (below) used to have a bug in which it would
  166. * not zero out any existing extension fields when writing
  167. * the arena metadata. This would manifest itself as arenas
  168. * with arena->diskstats.sealed == 1 but arena->memstats.sealed == 0
  169. * after a server restart. Because arena->memstats.sealed wouldn't
  170. * be set, the server might try to fit another block into the arena
  171. * (and succeed), violating the append-only structure of the log
  172. * and invalidating any already-computed seal on the arena.
  173. *
  174. * It might end up that other fields in arena->memstats end up
  175. * behind arena->diskstats too, but that would be considerably
  176. * more rare, and the bug is fixed now. The case we need to
  177. * handle is just the sealed mismatch.
  178. *
  179. * If we encounter such a bogus arena, fix the sealed field.
  180. */
  181. if(arena->diskstats.sealed)
  182. arena->memstats.sealed = 1;
  183. }else
  184. arena->memstats = arena->diskstats;
  185. if(buf + sz != p)
  186. sysfatal("unpackarena unpacked wrong amount");
  187. return 0;
  188. }
  189. int
  190. packarena(Arena *arena, u8int *buf)
  191. {
  192. return _packarena(arena, buf, 0);
  193. }
  194. int
  195. _packarena(Arena *arena, u8int *buf, int forceext)
  196. {
  197. int sz;
  198. u8int *p;
  199. u32int t32;
  200. switch(arena->version){
  201. case ArenaVersion4:
  202. sz = ArenaSize4;
  203. if(arena->clumpmagic != _ClumpMagic)
  204. fprint(2, "warning: writing old arena tail loses clump magic 0x%lux != 0x%lux\n",
  205. (ulong)arena->clumpmagic, (ulong)_ClumpMagic);
  206. break;
  207. case ArenaVersion5:
  208. sz = ArenaSize5;
  209. break;
  210. default:
  211. sysfatal("packarena unknown version %d", arena->version);
  212. return -1;
  213. }
  214. p = buf;
  215. U32PUT(p, ArenaMagic);
  216. p += U32Size;
  217. U32PUT(p, arena->version);
  218. p += U32Size;
  219. namecp((char*)p, arena->name);
  220. p += ANameSize;
  221. U32PUT(p, arena->diskstats.clumps);
  222. p += U32Size;
  223. U32PUT(p, arena->diskstats.cclumps);
  224. p += U32Size;
  225. U32PUT(p, arena->ctime);
  226. p += U32Size;
  227. U32PUT(p, arena->wtime);
  228. p += U32Size;
  229. if(arena->version == ArenaVersion5){
  230. U32PUT(p, arena->clumpmagic);
  231. p += U32Size;
  232. }
  233. U64PUT(p, arena->diskstats.used, t32);
  234. p += U64Size;
  235. U64PUT(p, arena->diskstats.uncsize, t32);
  236. p += U64Size;
  237. U8PUT(p, arena->diskstats.sealed);
  238. p += U8Size;
  239. /*
  240. * Extension fields; see above.
  241. */
  242. if(forceext
  243. || arena->memstats.clumps != arena->diskstats.clumps
  244. || arena->memstats.cclumps != arena->diskstats.cclumps
  245. || arena->memstats.used != arena->diskstats.used
  246. || arena->memstats.uncsize != arena->diskstats.uncsize
  247. || arena->memstats.sealed != arena->diskstats.sealed){
  248. sz += ArenaSize5a - ArenaSize5;
  249. U8PUT(p, 1);
  250. p += U8Size;
  251. U32PUT(p, arena->memstats.clumps);
  252. p += U32Size;
  253. U32PUT(p, arena->memstats.cclumps);
  254. p += U32Size;
  255. U64PUT(p, arena->memstats.used, t32);
  256. p += U64Size;
  257. U64PUT(p, arena->memstats.uncsize, t32);
  258. p += U64Size;
  259. U8PUT(p, arena->memstats.sealed);
  260. p += U8Size;
  261. }else{
  262. /* Clear any extension fields already on disk. */
  263. memset(p, 0, ArenaSize5a - ArenaSize5);
  264. p += ArenaSize5a - ArenaSize5;
  265. sz += ArenaSize5a - ArenaSize5;
  266. }
  267. if(buf + sz != p)
  268. sysfatal("packarena packed wrong amount");
  269. return 0;
  270. }
  271. int
  272. unpackarenahead(ArenaHead *head, u8int *buf)
  273. {
  274. u8int *p;
  275. u32int m;
  276. int sz;
  277. char fbuf[20];
  278. p = buf;
  279. m = U32GET(p);
  280. if(m != ArenaHeadMagic){
  281. seterr(ECorrupt, "arena %d head has wrong magic number: %s "
  282. "expected ArenaHeadMagic (%#lux)", debugarena,
  283. fmtmagic(fbuf, m), ArenaHeadMagic);
  284. return -1;
  285. }
  286. p += U32Size;
  287. head->version = U32GET(p);
  288. p += U32Size;
  289. namecp(head->name, (char*)p);
  290. p += ANameSize;
  291. head->blocksize = U32GET(p);
  292. p += U32Size;
  293. head->size = U64GET(p);
  294. p += U64Size;
  295. if(head->version == ArenaVersion5){
  296. head->clumpmagic = U32GET(p);
  297. p += U32Size;
  298. }
  299. switch(head->version){
  300. case ArenaVersion4:
  301. sz = ArenaHeadSize4;
  302. head->clumpmagic = _ClumpMagic;
  303. break;
  304. case ArenaVersion5:
  305. sz = ArenaHeadSize5;
  306. break;
  307. default:
  308. seterr(ECorrupt, "arena head has unexpected version %d", head->version);
  309. return -1;
  310. }
  311. if(buf + sz != p)
  312. sysfatal("unpackarenahead unpacked wrong amount");
  313. return 0;
  314. }
  315. int
  316. packarenahead(ArenaHead *head, u8int *buf)
  317. {
  318. u8int *p;
  319. int sz;
  320. u32int t32;
  321. switch(head->version){
  322. case ArenaVersion4:
  323. sz = ArenaHeadSize4;
  324. if(head->clumpmagic != _ClumpMagic)
  325. fprint(2, "warning: writing old arena header loses clump magic 0x%lux != 0x%lux\n",
  326. (ulong)head->clumpmagic, (ulong)_ClumpMagic);
  327. break;
  328. case ArenaVersion5:
  329. sz = ArenaHeadSize5;
  330. break;
  331. default:
  332. sysfatal("packarenahead unknown version %d", head->version);
  333. return -1;
  334. }
  335. p = buf;
  336. U32PUT(p, ArenaHeadMagic);
  337. p += U32Size;
  338. U32PUT(p, head->version);
  339. p += U32Size;
  340. namecp((char*)p, head->name);
  341. p += ANameSize;
  342. U32PUT(p, head->blocksize);
  343. p += U32Size;
  344. U64PUT(p, head->size, t32);
  345. p += U64Size;
  346. if(head->version == ArenaVersion5){
  347. U32PUT(p, head->clumpmagic);
  348. p += U32Size;
  349. }
  350. if(buf + sz != p)
  351. sysfatal("packarenahead packed wrong amount");
  352. return 0;
  353. }
  354. static int
  355. checkclump(Clump *w)
  356. {
  357. if(w->encoding == ClumpENone){
  358. if(w->info.size != w->info.uncsize){
  359. seterr(ECorrupt, "uncompressed wad size mismatch");
  360. return -1;
  361. }
  362. }else if(w->encoding == ClumpECompress){
  363. if(w->info.size >= w->info.uncsize){
  364. seterr(ECorrupt, "compressed lump has inconsistent block sizes %d %d", w->info.size, w->info.uncsize);
  365. return -1;
  366. }
  367. }else{
  368. seterr(ECorrupt, "clump has illegal encoding");
  369. return -1;
  370. }
  371. return 0;
  372. }
  373. int
  374. unpackclump(Clump *c, u8int *buf, u32int cmagic)
  375. {
  376. u8int *p;
  377. u32int magic;
  378. p = buf;
  379. magic = U32GET(p);
  380. if(magic != cmagic){
  381. seterr(ECorrupt, "clump has bad magic number=%#8.8ux != %#8.8ux", magic, cmagic);
  382. return -1;
  383. }
  384. p += U32Size;
  385. c->info.type = vtfromdisktype(U8GET(p));
  386. p += U8Size;
  387. c->info.size = U16GET(p);
  388. p += U16Size;
  389. c->info.uncsize = U16GET(p);
  390. p += U16Size;
  391. scorecp(c->info.score, p);
  392. p += VtScoreSize;
  393. c->encoding = U8GET(p);
  394. p += U8Size;
  395. c->creator = U32GET(p);
  396. p += U32Size;
  397. c->time = U32GET(p);
  398. p += U32Size;
  399. if(buf + ClumpSize != p)
  400. sysfatal("unpackclump unpacked wrong amount");
  401. return checkclump(c);
  402. }
  403. int
  404. packclump(Clump *c, u8int *buf, u32int magic)
  405. {
  406. u8int *p;
  407. p = buf;
  408. U32PUT(p, magic);
  409. p += U32Size;
  410. U8PUT(p, vttodisktype(c->info.type));
  411. p += U8Size;
  412. U16PUT(p, c->info.size);
  413. p += U16Size;
  414. U16PUT(p, c->info.uncsize);
  415. p += U16Size;
  416. scorecp(p, c->info.score);
  417. p += VtScoreSize;
  418. U8PUT(p, c->encoding);
  419. p += U8Size;
  420. U32PUT(p, c->creator);
  421. p += U32Size;
  422. U32PUT(p, c->time);
  423. p += U32Size;
  424. if(buf + ClumpSize != p)
  425. sysfatal("packclump packed wrong amount");
  426. return checkclump(c);
  427. }
  428. void
  429. unpackclumpinfo(ClumpInfo *ci, u8int *buf)
  430. {
  431. u8int *p;
  432. p = buf;
  433. ci->type = vtfromdisktype(U8GET(p));
  434. p += U8Size;
  435. ci->size = U16GET(p);
  436. p += U16Size;
  437. ci->uncsize = U16GET(p);
  438. p += U16Size;
  439. scorecp(ci->score, p);
  440. p += VtScoreSize;
  441. if(buf + ClumpInfoSize != p)
  442. sysfatal("unpackclumpinfo unpacked wrong amount");
  443. }
  444. void
  445. packclumpinfo(ClumpInfo *ci, u8int *buf)
  446. {
  447. u8int *p;
  448. p = buf;
  449. U8PUT(p, vttodisktype(ci->type));
  450. p += U8Size;
  451. U16PUT(p, ci->size);
  452. p += U16Size;
  453. U16PUT(p, ci->uncsize);
  454. p += U16Size;
  455. scorecp(p, ci->score);
  456. p += VtScoreSize;
  457. if(buf + ClumpInfoSize != p)
  458. sysfatal("packclumpinfo packed wrong amount");
  459. }
  460. int
  461. unpackisect(ISect *is, u8int *buf)
  462. {
  463. u8int *p;
  464. u32int m;
  465. char fbuf[20];
  466. p = buf;
  467. m = U32GET(p);
  468. if(m != ISectMagic){
  469. seterr(ECorrupt, "index section has wrong magic number: %s expected ISectMagic (%#lux)",
  470. fmtmagic(fbuf, m), ISectMagic);
  471. return -1;
  472. }
  473. p += U32Size;
  474. is->version = U32GET(p);
  475. p += U32Size;
  476. namecp(is->name, (char*)p);
  477. p += ANameSize;
  478. namecp(is->index, (char*)p);
  479. p += ANameSize;
  480. is->blocksize = U32GET(p);
  481. p += U32Size;
  482. is->blockbase = U32GET(p);
  483. p += U32Size;
  484. is->blocks = U32GET(p);
  485. p += U32Size;
  486. is->start = U32GET(p);
  487. p += U32Size;
  488. is->stop = U32GET(p);
  489. p += U32Size;
  490. if(buf + ISectSize1 != p)
  491. sysfatal("unpackisect unpacked wrong amount");
  492. is->bucketmagic = 0;
  493. if(is->version == ISectVersion2){
  494. is->bucketmagic = U32GET(p);
  495. p += U32Size;
  496. if(buf + ISectSize2 != p)
  497. sysfatal("unpackisect unpacked wrong amount");
  498. }
  499. return 0;
  500. }
  501. int
  502. packisect(ISect *is, u8int *buf)
  503. {
  504. u8int *p;
  505. p = buf;
  506. U32PUT(p, ISectMagic);
  507. p += U32Size;
  508. U32PUT(p, is->version);
  509. p += U32Size;
  510. namecp((char*)p, is->name);
  511. p += ANameSize;
  512. namecp((char*)p, is->index);
  513. p += ANameSize;
  514. U32PUT(p, is->blocksize);
  515. p += U32Size;
  516. U32PUT(p, is->blockbase);
  517. p += U32Size;
  518. U32PUT(p, is->blocks);
  519. p += U32Size;
  520. U32PUT(p, is->start);
  521. p += U32Size;
  522. U32PUT(p, is->stop);
  523. p += U32Size;
  524. if(buf + ISectSize1 != p)
  525. sysfatal("packisect packed wrong amount");
  526. if(is->version == ISectVersion2){
  527. U32PUT(p, is->bucketmagic);
  528. p += U32Size;
  529. if(buf + ISectSize2 != p)
  530. sysfatal("packisect packed wrong amount");
  531. }
  532. return 0;
  533. }
  534. void
  535. unpackientry(IEntry *ie, u8int *buf)
  536. {
  537. u8int *p;
  538. p = buf;
  539. scorecp(ie->score, p);
  540. p += VtScoreSize;
  541. /* ie->wtime = U32GET(p); */
  542. p += U32Size;
  543. /* ie->train = U16GET(p); */
  544. p += U16Size;
  545. if(p - buf != IEntryAddrOff)
  546. sysfatal("unpackentry bad IEntryAddrOff amount");
  547. ie->ia.addr = U64GET(p);
  548. if(ie->ia.addr>>56) print("%.8H => %llux\n", p, ie->ia.addr);
  549. p += U64Size;
  550. ie->ia.size = U16GET(p);
  551. p += U16Size;
  552. if(p - buf != IEntryTypeOff)
  553. sysfatal("unpackientry bad IEntryTypeOff amount");
  554. ie->ia.type = vtfromdisktype(U8GET(p));
  555. p += U8Size;
  556. ie->ia.blocks = U8GET(p);
  557. p += U8Size;
  558. if(p - buf != IEntrySize)
  559. sysfatal("unpackientry unpacked wrong amount");
  560. }
  561. void
  562. packientry(IEntry *ie, u8int *buf)
  563. {
  564. u32int t32;
  565. u8int *p;
  566. p = buf;
  567. scorecp(p, ie->score);
  568. p += VtScoreSize;
  569. U32PUT(p, 0); /* wtime */
  570. p += U32Size;
  571. U16PUT(p, 0); /* train */
  572. p += U16Size;
  573. U64PUT(p, ie->ia.addr, t32);
  574. p += U64Size;
  575. U16PUT(p, ie->ia.size);
  576. p += U16Size;
  577. U8PUT(p, vttodisktype(ie->ia.type));
  578. p += U8Size;
  579. U8PUT(p, ie->ia.blocks);
  580. p += U8Size;
  581. if(p - buf != IEntrySize)
  582. sysfatal("packientry packed wrong amount");
  583. }
  584. void
  585. unpackibucket(IBucket *b, u8int *buf, u32int magic)
  586. {
  587. b->n = U16GET(buf);
  588. b->data = buf + IBucketSize;
  589. if(magic && magic != U32GET(buf+U16Size))
  590. b->n = 0;
  591. }
  592. void
  593. packibucket(IBucket *b, u8int *buf, u32int magic)
  594. {
  595. U16PUT(buf, b->n);
  596. U32PUT(buf+U16Size, magic);
  597. }
  598. void
  599. packbloomhead(Bloom *b, u8int *buf)
  600. {
  601. u8int *p;
  602. p = buf;
  603. U32PUT(p, BloomMagic);
  604. U32PUT(p+4, BloomVersion);
  605. U32PUT(p+8, b->nhash);
  606. U32PUT(p+12, b->size);
  607. }
  608. int
  609. unpackbloomhead(Bloom *b, u8int *buf)
  610. {
  611. u8int *p;
  612. u32int m;
  613. char fbuf[20];
  614. p = buf;
  615. m = U32GET(p);
  616. if(m != BloomMagic){
  617. seterr(ECorrupt, "bloom filter has wrong magic number: %s expected BloomMagic (%#lux)", fmtmagic(fbuf, m), (ulong)BloomMagic);
  618. return -1;
  619. }
  620. p += U32Size;
  621. m = U32GET(p);
  622. if(m != BloomVersion){
  623. seterr(ECorrupt, "bloom filter has wrong version %ud expected %ud", (uint)m, (uint)BloomVersion);
  624. return -1;
  625. }
  626. p += U32Size;
  627. b->nhash = U32GET(p);
  628. p += U32Size;
  629. b->size = U32GET(p);
  630. p += U32Size;
  631. if(b->size < BloomHeadSize || b->size > MaxBloomSize || (b->size&(b->size-1))){
  632. seterr(ECorrupt, "bloom filter has invalid size %#lux", b->size);
  633. return -1;
  634. }
  635. if(buf + BloomHeadSize != p)
  636. sysfatal("unpackarena unpacked wrong amount");
  637. return 0;
  638. }