Add a redirect_intent write mode for non-capacitor SSDs

This commit is contained in:
Vitaliy Filippov
2025-12-02 01:52:12 +03:00
parent f2cbe793e2
commit b17691ba02
4 changed files with 53 additions and 6 deletions
+28
View File
@@ -1267,6 +1267,34 @@ int blockstore_heap_t::add_big_write(object_id oid, heap_entry_t *old_head, bool
});
}
int blockstore_heap_t::add_redirect_intent(object_id oid, heap_entry_t **obj_ptr, uint64_t version,
uint32_t offset, uint32_t len, uint64_t location, uint8_t *bitmap, uint8_t *data, uint32_t *modified_block)
{
uint32_t wr_size = get_big_intent_entry_size();
// Big-redirect intents, just like regular big writes, are written after writing data so they don't require explicit_complete
return add_entry(wr_size, modified_block, false, false, [&](heap_entry_t *wr)
{
wr->entry_type = BS_HEAP_BIG_INTENT|BS_HEAP_STABLE;
wr->inode = oid.inode;
wr->stripe = oid.stripe;
wr->version = version;
wr->set_big_location(this, location);
auto & bi = wr->big_intent();
bi.offset = offset;
bi.len = len;
if (bitmap)
memcpy(wr->get_ext_bitmap(this), bitmap, dsk->clean_entry_bitmap_size);
else
memset(wr->get_ext_bitmap(this), 0, dsk->clean_entry_bitmap_size);
memset(wr->get_int_bitmap(this), 0, dsk->clean_entry_bitmap_size);
bitmap_set(wr->get_int_bitmap(this), offset, len, dsk->bitmap_granularity);
if (dsk->data_csum_type)
memset(wr->get_checksums(this), 0, get_csum_size(wr));
calc_checksums(wr, (uint8_t*)data, true, offset, len);
*obj_ptr = wr;
});
}
int blockstore_heap_t::add_big_intent(object_id oid, heap_entry_t **obj_ptr, uint64_t version,
uint32_t offset, uint32_t len, uint8_t *bitmap, uint8_t *data, uint8_t *checksums, uint32_t *modified_block)
{
+3
View File
@@ -265,6 +265,9 @@ public:
// adds a big_write (overwrite) entry to an object
int add_big_write(object_id oid, heap_entry_t *old_head, bool stable, uint64_t version,
uint32_t offset, uint32_t len, uint64_t location, uint8_t *bitmap, uint8_t *data, uint32_t *modified_block);
// adds a "redirecting" big_intent entry to an object (same as big_write, used to avoid fsync on desktop SSDs)
int add_redirect_intent(object_id oid, heap_entry_t **obj_ptr, uint64_t version,
uint32_t offset, uint32_t len, uint64_t location, uint8_t *bitmap, uint8_t *data, uint32_t *modified_block);
// adds a big_intent (atomic partial modification) entry to an object
int add_big_intent(object_id oid, heap_entry_t **obj_ptr, uint64_t version,
uint32_t offset, uint32_t len, uint8_t *bitmap, uint8_t *data, uint8_t *checksums, uint32_t *modified_block);
+21 -6
View File
@@ -5,6 +5,8 @@
#include "blockstore_internal.h"
#include "allocator.h"
#define _REDIRECT_INTENT 0x101
bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
{
clock_gettime(CLOCK_REALTIME, &PRIV(op)->tv_begin);
@@ -138,13 +140,12 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
PRIV(op)->op_state = 5;
write_iodepth++;
}
// FIXME: Add 'big_intent' write mode
// FIXME: Allow to do initial writes as buffered, not redirected
// FIXME: Allow to do direct writes over holes
else if (!obj || obj->type() == BS_HEAP_DELETE || op->offset == 0 && op->len == dsk.data_block_size)
{
// Big (redirect) write
PRIV(op)->write_type = BS_HEAP_BIG_WRITE;
PRIV(op)->write_type = dsk.disable_data_fsync || op->opcode != BS_OP_WRITE_STABLE ? BS_HEAP_BIG_WRITE : _REDIRECT_INTENT;
BS_SUBMIT_CHECK_SQES(1);
PRIV(op)->location = heap->find_free_data();
if (PRIV(op)->location == UINT64_MAX)
@@ -176,9 +177,14 @@ enospc:
data->callback = [this, op](ring_data_t *data) { handle_write_event(data, op); };
io_uring_prep_writev(sqe, dsk.data_fd, &data->iov, 1, dsk.data_offset + loc + op->offset);
PRIV(op)->pending_ops++;
PRIV(op)->op_state = 1;
write_iodepth++;
inflight_big++;
if (PRIV(op)->write_type == BS_HEAP_BIG_WRITE)
{
PRIV(op)->op_state = 1;
inflight_big++;
}
else
PRIV(op)->op_state = 3;
}
else if (intent_write_allowed(op, obj))
{
@@ -344,8 +350,17 @@ resume_12:
resume_4:
{
auto obj = heap->read_entry(op->oid);
int res = heap->add_big_write(op->oid, obj, (op->opcode == BS_OP_WRITE_STABLE), op->version,
op->offset, op->len, PRIV(op)->location, op->bitmap, (uint8_t*)op->buf, &PRIV(op)->modified_block);
int res = 0;
if (PRIV(op)->write_type == _REDIRECT_INTENT)
{
res = heap->add_redirect_intent(op->oid, &obj, op->version, op->offset, op->len,
PRIV(op)->location, op->bitmap, (uint8_t*)op->buf, &PRIV(op)->modified_block);
}
else
{
res = heap->add_big_write(op->oid, obj, op->opcode == BS_OP_WRITE_STABLE,
op->version, op->offset, op->len, PRIV(op)->location, op->bitmap, (uint8_t*)op->buf, &PRIV(op)->modified_block);
}
if (res == ENOSPC)
{
if (!heap->get_to_compact_count())
+1
View File
@@ -1240,6 +1240,7 @@ void test_intent_write(bool csum)
}
// FIXME: Add a test for big_intent, incl. explicit_complete with big_intent over big_write over deletion over big_write :)
// FIXME: Add a test for redirect_intent
int main(int narg, char *args[])
{