mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-07 04:26:29 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user