Add a redirect_intent write mode for non-capacitor SSDs
This commit is contained in:
@@ -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,
|
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)
|
uint32_t offset, uint32_t len, uint8_t *bitmap, uint8_t *data, uint8_t *checksums, uint32_t *modified_block)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -265,6 +265,9 @@ public:
|
|||||||
// adds a big_write (overwrite) entry to an object
|
// 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,
|
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);
|
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
|
// 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,
|
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);
|
uint32_t offset, uint32_t len, uint8_t *bitmap, uint8_t *data, uint8_t *checksums, uint32_t *modified_block);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "blockstore_internal.h"
|
#include "blockstore_internal.h"
|
||||||
#include "allocator.h"
|
#include "allocator.h"
|
||||||
|
|
||||||
|
#define _REDIRECT_INTENT 0x101
|
||||||
|
|
||||||
bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
|
bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
|
||||||
{
|
{
|
||||||
clock_gettime(CLOCK_REALTIME, &PRIV(op)->tv_begin);
|
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;
|
PRIV(op)->op_state = 5;
|
||||||
write_iodepth++;
|
write_iodepth++;
|
||||||
}
|
}
|
||||||
// FIXME: Add 'big_intent' write mode
|
|
||||||
// FIXME: Allow to do initial writes as buffered, not redirected
|
// FIXME: Allow to do initial writes as buffered, not redirected
|
||||||
// FIXME: Allow to do direct writes over holes
|
// 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)
|
else if (!obj || obj->type() == BS_HEAP_DELETE || op->offset == 0 && op->len == dsk.data_block_size)
|
||||||
{
|
{
|
||||||
// Big (redirect) write
|
// 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);
|
BS_SUBMIT_CHECK_SQES(1);
|
||||||
PRIV(op)->location = heap->find_free_data();
|
PRIV(op)->location = heap->find_free_data();
|
||||||
if (PRIV(op)->location == UINT64_MAX)
|
if (PRIV(op)->location == UINT64_MAX)
|
||||||
@@ -176,9 +177,14 @@ enospc:
|
|||||||
data->callback = [this, op](ring_data_t *data) { handle_write_event(data, op); };
|
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);
|
io_uring_prep_writev(sqe, dsk.data_fd, &data->iov, 1, dsk.data_offset + loc + op->offset);
|
||||||
PRIV(op)->pending_ops++;
|
PRIV(op)->pending_ops++;
|
||||||
PRIV(op)->op_state = 1;
|
|
||||||
write_iodepth++;
|
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))
|
else if (intent_write_allowed(op, obj))
|
||||||
{
|
{
|
||||||
@@ -344,8 +350,17 @@ resume_12:
|
|||||||
resume_4:
|
resume_4:
|
||||||
{
|
{
|
||||||
auto obj = heap->read_entry(op->oid);
|
auto obj = heap->read_entry(op->oid);
|
||||||
int res = heap->add_big_write(op->oid, obj, (op->opcode == BS_OP_WRITE_STABLE), op->version,
|
int res = 0;
|
||||||
op->offset, op->len, PRIV(op)->location, op->bitmap, (uint8_t*)op->buf, &PRIV(op)->modified_block);
|
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 (res == ENOSPC)
|
||||||
{
|
{
|
||||||
if (!heap->get_to_compact_count())
|
if (!heap->get_to_compact_count())
|
||||||
|
|||||||
@@ -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 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[])
|
int main(int narg, char *args[])
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user