diff --git a/kmod/src/segment.c b/kmod/src/segment.c index 4e94760a..85e51c90 100644 --- a/kmod/src/segment.c +++ b/kmod/src/segment.c @@ -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) diff --git a/kmod/src/skip.c b/kmod/src/skip.c index 69bae2b8..c855ae49 100644 --- a/kmod/src/skip.c +++ b/kmod/src/skip.c @@ -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; } /*