conv.c 15 KB

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