Fix intent_write_allowed check, add offset & len validation on start
This commit is contained in:
@@ -354,6 +354,26 @@ corrupted_object:
|
|||||||
block_num, block_offset, expected_crc32c, wr->crc32c);
|
block_num, block_offset, expected_crc32c, wr->crc32c);
|
||||||
goto corrupted_object;
|
goto corrupted_object;
|
||||||
}
|
}
|
||||||
|
// Verify offset & len
|
||||||
|
if ((wr->type() == BS_HEAP_SMALL_WRITE || wr->type() == BS_HEAP_INTENT_WRITE) &&
|
||||||
|
(wr->small().offset+wr->small().len > dsk->data_block_size ||
|
||||||
|
wr->small().offset % dsk->bitmap_granularity ||
|
||||||
|
wr->small().len % dsk->bitmap_granularity))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: %s entry %jx:%jx v%ju has invalid offset/length: %u/%u. Metadata is incompatible with current parameters, aborting\n",
|
||||||
|
wr->type() == BS_HEAP_SMALL_WRITE ? "small_write" : "intent_write",
|
||||||
|
wr->inode, wr->stripe, wr->version, wr->small().offset, wr->small().len);
|
||||||
|
goto corrupted_object;
|
||||||
|
}
|
||||||
|
if (wr->type() == BS_HEAP_BIG_INTENT &&
|
||||||
|
(wr->big_intent().offset+wr->big_intent().len > dsk->data_block_size ||
|
||||||
|
wr->big_intent().offset % dsk->bitmap_granularity ||
|
||||||
|
wr->big_intent().len % dsk->bitmap_granularity))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: big_intent entry %jx:%jx v%ju has invalid offset/length: %u/%u. Metadata is incompatible with current parameters, aborting\n",
|
||||||
|
wr->inode, wr->stripe, wr->version, wr->big_intent().offset, wr->big_intent().len);
|
||||||
|
goto corrupted_object;
|
||||||
|
}
|
||||||
handle_write(block_num, wr);
|
handle_write(block_num, wr);
|
||||||
block_offset += wr->size;
|
block_offset += wr->size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,11 +72,12 @@ bool blockstore_impl_t::intent_write_allowed(blockstore_op_t *op, heap_entry_t *
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool ok = true, has_intent = false;
|
bool ok = true;
|
||||||
heap->iterate_with_stable(obj, obj->lsn, [&](heap_entry_t *wr, bool stable)
|
heap->iterate_with_stable(obj, obj->lsn, [&](heap_entry_t *wr, bool stable)
|
||||||
{
|
{
|
||||||
// Intent writes are not allowed over buffered writes
|
// Intent writes are not allowed over buffered writes
|
||||||
if (wr->type() == BS_HEAP_SMALL_WRITE)
|
auto t = wr->type();
|
||||||
|
if (t == BS_HEAP_SMALL_WRITE)
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
return false;
|
return false;
|
||||||
@@ -87,17 +88,14 @@ bool blockstore_impl_t::intent_write_allowed(blockstore_op_t *op, heap_entry_t *
|
|||||||
ok = false;
|
ok = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// One intent-write is allowed even with fsyncs because BIG_WRITE is always counted as fsynced
|
// Intent writes are not allowed over unfinished intent writes
|
||||||
if (dsk.disable_data_fsync && wr->type() == BS_HEAP_INTENT_WRITE)
|
if ((t == BS_HEAP_INTENT_WRITE || t == BS_HEAP_BIG_INTENT) && wr->lsn > heap->get_fsynced_lsn())
|
||||||
{
|
{
|
||||||
if (has_intent)
|
ok = false;
|
||||||
{
|
return false;
|
||||||
ok = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
has_intent = true;
|
|
||||||
}
|
}
|
||||||
if (wr->type() == BS_HEAP_BIG_WRITE || wr->type() == BS_HEAP_BIG_INTENT)
|
// Intent writes are allowed over BIG_WRITEs even with fsyncs because BIG_WRITE is always counted as fsynced
|
||||||
|
if (t == BS_HEAP_BIG_WRITE || t == BS_HEAP_BIG_INTENT)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user