conv.c 15 KB

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