scoutfs: item offsets need to skip block headers

The vallue offset allocation knew to skip block headers at the start of
each segment block but, weirdly, the item offset allocation didn't.

We make item offset calculation skip the header and we add some tracing
to help see the problem.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-03-25 19:28:21 -07:00
parent 6834100251
commit 867d717d2b
2 changed files with 19 additions and 7 deletions

View File

@@ -188,9 +188,15 @@ static int add_item_off(struct scoutfs_sb_info *sbi, int height)
{
int len = offsetof(struct scoutfs_item, skip_next[height]);
int off = sbi->dirty_item_off;
int block_off;
int tail_free;
/* item's can't cross a block boundary */
/* items can't start in a block header */
block_off = off & SCOUTFS_BLOCK_MASK;
if (block_off < sizeof(struct scoutfs_block_header))
off += sizeof(struct scoutfs_block_header) - block_off;
/* items can't cross a block boundary */
tail_free = SCOUTFS_BLOCK_SIZE - (off & SCOUTFS_BLOCK_MASK);
if (tail_free < len)
off += tail_free + sizeof(struct scoutfs_block_header);
@@ -432,6 +438,8 @@ next_chunk:
item_off = add_item_off(sbi, height);
val_off = sub_val_off(sbi, bytes);
trace_printk("item_off %u val_off %u\n", item_off, val_off);
if (item_off > val_off) {
ret = scoutfs_finish_dirty_segment(sb);
if (ret)

View File

@@ -81,12 +81,16 @@ struct skip_path {
*/
static int invalid_item_off(u32 off)
{
return off < ((SCOUTFS_BLOCK_SIZE * SCOUTFS_BLOOM_BLOCKS) +
sizeof(struct scoutfs_item_block)) ||
(off & SCOUTFS_BLOCK_MASK) <
sizeof(struct scoutfs_block_header) ||
(off & SCOUTFS_BLOCK_MASK) >
(SCOUTFS_BLOCK_SIZE - sizeof(struct scoutfs_item));
if (off < ((SCOUTFS_BLOCK_SIZE * SCOUTFS_BLOOM_BLOCKS) +
sizeof(struct scoutfs_item_block)) ||
(off & SCOUTFS_BLOCK_MASK) < sizeof(struct scoutfs_block_header) ||
(off & SCOUTFS_BLOCK_MASK) >
(SCOUTFS_BLOCK_SIZE - sizeof(struct scoutfs_item))) {
trace_printk("invalid offset %u\n", off);
return 1;
}
return 0;
}
/*