Commit 84f368aa authored by Mike Hibler's avatar Mike Hibler

Make sure we finish a chunk with the header fills up.

parent 38f7e4bc
......@@ -342,6 +342,7 @@ struct chunkstate {
ndz_chunkno_t chunkno;
unsigned char *chunkdatabuf;
blockhdr_t *header;
uint32_t headerleft;
struct region *region;
struct region *curregion;
struct ndz_rangemap *verifysigmap;
......@@ -424,6 +425,17 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
return 1;
cstate->header->firstsect = rstart;
cstate->curregion->start = rstart;
cstate->headerleft = cstate->header->regionsize;
if (delta.ndz->relocentries > 0) {
/*
* Account for relocations.
* XXX we don't know how many relocs will wind up in this chunk
* so we have to assume that all remaining ones will.
*/
cstate->headerleft -=
(ndz_reloc_inrange(delta.ndz, rstart, 0) *
sizeof(struct blockreloc));
}
}
/*
......@@ -531,12 +543,15 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
size_t wbytes, chunkremaining;
chunkremaining = ndz_chunk_left(cstate->chunkobj);
if (chunkremaining < delta.ndz->sectsize) {
if (chunkremaining < delta.ndz->sectsize ||
cstate->headerleft < sizeof(struct region)) {
/* switch to new chunk */
#ifdef CHUNKIFY_DEBUG
fprintf(stderr, " chunk %u full (%lu bytes), writing...\n",
fprintf(stderr,
" chunk %u full (%lu bytes, %u header), writing\n",
cstate->chunkno,
(unsigned long)ndz_chunk_datasize(cstate->chunkobj));
(unsigned long)ndz_chunk_datasize(cstate->chunkobj),
cstate->header->regionsize - cstate->headerleft);
#endif
/* finalize the header */
......@@ -568,6 +583,11 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
return 1;
cstate->header->firstsect = pstart;
cstate->curregion->start = pstart;
cstate->headerleft = cstate->header->regionsize;
if (delta.ndz->relocentries > 0)
cstate->headerleft -=
(ndz_reloc_inrange(delta.ndz, pstart, 0) *
sizeof(struct blockreloc));
/* keep track if this hash range spans chunks */
if (psize < hsize)
......@@ -612,10 +632,13 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
cstate->curregion++;
cstate->curregion->start = pstart;
cstate->curregion->size = wsize;
cstate->headerleft -= sizeof(struct region);
#ifdef CHUNKIFY_DEBUG
fprintf(stderr, " new range entry [%u-%u]\n",
fprintf(stderr,
" new range entry [%u-%u], %u header bytes left\n",
cstate->curregion->start,
cstate->curregion->start+cstate->curregion->size-1);
cstate->curregion->start+cstate->curregion->size-1,
cstate->headerleft);
#endif
}
......
......@@ -290,16 +290,17 @@ struct chunkstate {
ndz_chunkno_t chunkno;
unsigned char *chunkdatabuf;
blockhdr_t *header;
uint32_t headerleft;
struct region *region;
struct region *curregion;
};
static int
initnewchunk(struct chunkstate *cstate)
initnewchunk(struct chunkstate *cstate, struct ndz_file *ndz)
{
struct blockhdr_V2 *hdr;
cstate->chunkobj = ndz_chunk_create(new.ndz, cstate->chunkno, clevel);
cstate->chunkobj = ndz_chunk_create(ndz, cstate->chunkno, clevel);
if (cstate->chunkobj == NULL) {
fprintf(stderr, "Error creating chunk %u\n", cstate->chunkno);
return 1;
......@@ -366,10 +367,21 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
return 1;
}
cstate->chunkno = 0;
if (initnewchunk(cstate) != 0)
if (initnewchunk(cstate, new.ndz) != 0)
return 1;
cstate->header->firstsect = rstart;
cstate->curregion->start = rstart;
cstate->headerleft = cstate->header->regionsize;
if (new.ndz->relocentries > 0) {
/*
* Account for relocations.
* XXX we don't know how many relocs will wind up in this chunk
* so we have to assume that all remaining ones will.
*/
cstate->headerleft -=
(ndz_reloc_inrange(new.ndz, rstart, 0) *
sizeof(struct blockreloc));
}
}
/*
......@@ -486,12 +498,15 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
size_t wbytes, chunkremaining;
chunkremaining = ndz_chunk_left(cstate->chunkobj);
if (chunkremaining < new.ndz->sectsize) {
if (chunkremaining < new.ndz->sectsize ||
cstate->headerleft < sizeof(struct region)) {
/* switch to new chunk */
#ifdef CHUNKIFY_DEBUG
fprintf(stderr, " chunk %u full (%lu bytes), writing...\n",
fprintf(stderr,
" chunk %u full (%lu bytes, %u header), writing\n",
cstate->chunkno,
(unsigned long)ndz_chunk_datasize(cstate->chunkobj));
(unsigned long)ndz_chunk_datasize(cstate->chunkobj),
cstate->header->regionsize - cstate->headerleft);
#endif
/* finalize the header */
......@@ -519,10 +534,15 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
}
cstate->chunkno++;
if (initnewchunk(cstate) != 0)
if (initnewchunk(cstate, new.ndz) != 0)
return 1;
cstate->header->firstsect = pstart;
cstate->curregion->start = pstart;
cstate->headerleft = cstate->header->regionsize;
if (new.ndz->relocentries > 0)
cstate->headerleft -=
(ndz_reloc_inrange(new.ndz, pstart, 0) *
sizeof(struct blockreloc));
/* keep track if this hash range spans chunks */
if (psize < hsize)
......@@ -567,10 +587,13 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
cstate->curregion++;
cstate->curregion->start = pstart;
cstate->curregion->size = wsize;
cstate->headerleft -= sizeof(struct region);
#ifdef CHUNKIFY_DEBUG
fprintf(stderr, " new range entry [%u-%u]\n",
fprintf(stderr,
" new range entry [%u-%u], %u header bytes left\n",
cstate->curregion->start,
cstate->curregion->start+cstate->curregion->size-1);
cstate->curregion->start+cstate->curregion->size-1,
cstate->headerleft);
#endif
}
......
......@@ -483,6 +483,7 @@ struct chunkstate {
ndz_chunkno_t chunkno;
unsigned char *chunkdatabuf;
blockhdr_t *header;
uint32_t headerleft;
struct region *region;
struct region *curregion;
struct ndz_rangemap *verifysigmap;
......@@ -637,6 +638,17 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
return 1;
cstate->header->firstsect = rstart;
cstate->curregion->start = rstart;
cstate->headerleft = cstate->header->regionsize;
if (delta.ndz->relocentries > 0) {
/*
* Account for relocations.
* XXX we don't know how many relocs will wind up in this chunk
* so we have to assume that all remaining ones will.
*/
cstate->headerleft -=
(ndz_reloc_inrange(new.ndz, rstart, 0) *
sizeof(struct blockreloc));
}
}
/*
......@@ -756,12 +768,15 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
size_t wbytes, chunkremaining;
chunkremaining = ndz_chunk_left(cstate->chunkobj);
if (chunkremaining < new.ndz->sectsize) {
if (chunkremaining < new.ndz->sectsize ||
cstate->headerleft < sizeof(struct region)) {
/* switch to new chunk */
#ifdef CHUNKIFY_DEBUG
fprintf(stderr, " chunk %u full (%lu bytes), writing...\n",
fprintf(stderr,
" chunk %u full (%lu bytes, %u header), writing\n",
cstate->chunkno,
(unsigned long)ndz_chunk_datasize(cstate->chunkobj));
(unsigned long)ndz_chunk_datasize(cstate->chunkobj),
cstate->header->regionsize - cstate->headerleft);
#endif
/* finalize the header */
......@@ -793,6 +808,11 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
return 1;
cstate->header->firstsect = pstart;
cstate->curregion->start = pstart;
cstate->headerleft = cstate->header->regionsize;
if (delta.ndz->relocentries > 0)
cstate->headerleft -=
(ndz_reloc_inrange(new.ndz, pstart, 0) *
sizeof(struct blockreloc));
/* keep track if this hash range spans chunks */
if (psize < hsize)
......@@ -837,10 +857,13 @@ chunkify(struct ndz_rangemap *mmap, struct ndz_range *range, void *arg)
cstate->curregion++;
cstate->curregion->start = pstart;
cstate->curregion->size = wsize;
cstate->headerleft -= sizeof(struct region);
#ifdef CHUNKIFY_DEBUG
fprintf(stderr, " new range entry [%u-%u]\n",
fprintf(stderr,
" new range entry [%u-%u], %u header bytes left\n",
cstate->curregion->start,
cstate->curregion->start+cstate->curregion->size-1);
cstate->curregion->start+cstate->curregion->size-1,
cstate->headerleft);
#endif
}
......
......@@ -241,7 +241,7 @@ ndz_readranges(struct ndz_file *ndz)
ndz_rangemap_deinit(map);
return NULL;
}
fprintf(stderr, "allocated chunkmap of %d bytes\n",
fprintf(stderr, "allocated chunkmap of %lu bytes\n",
ndz->chunkmapentries * sizeof(ndz->chunkmap[0]));
}
#endif
......
......@@ -143,35 +143,41 @@ ndz_reloc_put(struct ndz_file *ndz, blockhdr_t *hdr, void *buf)
}
/*
* Returns 1 if there is a relocation in the indicated range, 0 otherwise
* Returns the number of relocations in the indicated range, 0 otherwise
* If size is zero, count til the end.
*/
int
ndz_reloc_inrange(struct ndz_file *ndz, ndz_addr_t addr, ndz_size_t size)
{
struct blockreloc *relocdata;
ndz_addr_t eaddr;
int i;
int i, nreloc = 0;
assert(ndz != NULL);
eaddr = addr + size - 1;
if (size == 0)
eaddr = (ndz->relochi > addr) ? ndz->relochi : addr;
else
eaddr = addr + size - 1;
if (ndz->relocentries == 0 || addr > ndz->relochi || eaddr < ndz->reloclo)
return 0;
relocdata = ndz->relocdata;
for (i = 0; i < ndz->relocentries; i++) {
assert(relocdata->sectoff + relocdata->size <= ndz->sectsize);
if (relocdata->sector > eaddr)
break;
if (relocdata->sector >= addr && relocdata->sector <= eaddr) {
#ifdef RELOC_DEBUG
fprintf(stderr, "found a reloc (%u) in range [%lu-%lu]\n",
relocdata->sector, addr, eaddr);
#endif
return 1;
nreloc++;
}
relocdata++;
}
return 0;
#ifdef RELOC_DEBUG
if (nreloc)
fprintf(stderr, "found %d relocs in range [%lu-%lu]\n",
nreloc, addr, eaddr);
#endif
return nreloc;
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment