Allow to return chain_info in response to reads

This commit is contained in:
Vitaliy Filippov
2026-03-20 21:00:32 +03:00
parent a2debfca68
commit b4d172be35
5 changed files with 72 additions and 15 deletions
+34 -10
View File
@@ -958,14 +958,23 @@ bool cluster_client_t::check_rw(cluster_op_t *op)
{
op->flags |= OP_IMMEDIATE_COMMIT;
}
auto ino_it = st_cli.inode_config.find(op->inode);
if (ino_it != st_cli.inode_config.end() && ino_it->second.enc)
// FIXME: Rework client API by adding open/close and cache inode information in the "FD"
bool searched = false;
std::map<inode_t, inode_config_t>::iterator ino_it;
if (op->opcode == OSD_OP_READ || op->opcode == OSD_OP_WRITE)
{
// FIXME: Rework client API by adding open/close and cache inode information in the "FD"
op->enc = ino_it->second.enc;
if (!op->enc->bitmap_granularity)
if (!searched)
{
op->enc->bitmap_granularity = pool_it->second.bitmap_granularity;
ino_it = st_cli.inode_config.find(op->inode);
searched = true;
}
if (ino_it != st_cli.inode_config.end() && ino_it->second.enc)
{
op->enc = ino_it->second.enc;
if (!op->enc->bitmap_granularity)
{
op->enc->bitmap_granularity = pool_it->second.bitmap_granularity;
}
}
}
else
@@ -974,6 +983,11 @@ bool cluster_client_t::check_rw(cluster_op_t *op)
}
if ((op->opcode == OSD_OP_WRITE || op->opcode == OSD_OP_DELETE) && !(op->flags & OSD_OP_IGNORE_READONLY))
{
if (!searched)
{
ino_it = st_cli.inode_config.find(op->inode);
searched = true;
}
if (ino_it != st_cli.inode_config.end() && ino_it->second.readonly)
{
op->retval = -EROFS;
@@ -985,6 +999,11 @@ bool cluster_client_t::check_rw(cluster_op_t *op)
op->deoptimise_snapshot = false;
if (enable_writeback && (op->opcode == OSD_OP_READ || op->opcode == OSD_OP_READ_BITMAP || op->opcode == OSD_OP_READ_CHAIN_BITMAP))
{
if (!searched)
{
ino_it = st_cli.inode_config.find(op->inode);
searched = true;
}
if (ino_it != st_cli.inode_config.end())
{
int chain_size = 0;
@@ -1264,7 +1283,11 @@ void cluster_client_t::slice_rw(cluster_op_t *op)
// Allocate memory for the bitmap
unsigned object_bitmap_size = ((op->len / pool_cfg.bitmap_granularity + 7) / 8);
object_bitmap_size = (object_bitmap_size < 8 ? 8 : object_bitmap_size);
unsigned bitmap_mem = object_bitmap_size + (pool_cfg.data_block_size / pool_cfg.bitmap_granularity / 8 * pg_data_size) * op->parts.size();
unsigned bitmap_mem = object_bitmap_size +
op->parts.size() * pg_data_size *
(pool_cfg.data_block_size / pool_cfg.bitmap_granularity / 8
// read chain info - 1 byte per block
+ (op->enc ? op->len/pool_cfg.bitmap_granularity : 0));
if (!op->bitmap_buf || op->bitmap_buf_size < bitmap_mem)
{
op->bitmap_buf = realloc_or_die(op->bitmap_buf, bitmap_mem);
@@ -1419,9 +1442,9 @@ int cluster_client_t::try_send(cluster_op_t *op, int i, std::function<void(osd_o
int peer_fd = peer_it->second;
part->flags |= PART_SENT|PART_VALID;
op->inflight_count++;
uint64_t pg_bitmap_size = (pool_cfg.data_block_size / pool_cfg.bitmap_granularity / 8) * (
pool_cfg.scheme == POOL_SCHEME_REPLICATED ? 1 : pool_cfg.pg_size-pool_cfg.parity_chunks
);
uint32_t pg_data_size = (pool_cfg.scheme == POOL_SCHEME_REPLICATED ? 1 : pool_cfg.pg_size-pool_cfg.parity_chunks);
uint64_t pg_bitmap_size = pg_data_size * (pool_cfg.data_block_size / pool_cfg.bitmap_granularity / 8
+ (op->opcode == OSD_OP_READ && op->enc ? pool_cfg.data_block_size/pool_cfg.bitmap_granularity : 0));
uint64_t meta_rev = 0;
if (op->opcode != OSD_OP_READ_BITMAP && op->opcode != OSD_OP_DELETE && !op->deoptimise_snapshot)
{
@@ -1440,6 +1463,7 @@ int cluster_client_t::try_send(cluster_op_t *op, int i, std::function<void(osd_o
.inode = op->cur_inode,
.offset = part->offset,
.len = part->len,
.flags = op->opcode == OSD_OP_READ && op->enc ? OSD_OP_RETURN_CHAIN : 0,
.meta_revision = meta_rev,
.version = op->opcode == OSD_OP_WRITE || op->opcode == OSD_OP_DELETE ? op->version : 0,
} },
+13 -2
View File
@@ -37,6 +37,7 @@
#define OSD_OP_RECOVERY_RELATED (uint32_t)1
#define OSD_OP_IGNORE_PG_LOCK (uint32_t)2
#define OSD_OP_RETURN_CHAIN (uint32_t)4
// Memory alignment for direct I/O (usually 512 bytes)
#ifndef DIRECT_IO_ALIGNMENT
@@ -228,9 +229,10 @@ struct __attribute__((__packed__)) osd_op_rw_t
uint64_t offset;
// length. 0 means to read all bitmaps of the specified range, but no data.
uint32_t len;
// flags (for future)
// flags
// OSD_OP_RETURN_CHAIN for chained reads: return parent number in chain for each block
uint32_t flags;
// inode metadata revision
// inode metadata revision for chained reads
uint64_t meta_revision;
// object version for atomic "CAS" (compare-and-set) writes
// writes and deletes fail with -EINTR if object version differs from (version-1)
@@ -245,6 +247,15 @@ struct __attribute__((__packed__)) osd_reply_rw_t
uint32_t pad0;
// for reads and writes: object version
uint64_t version;
// for reads: chain info size for OSD_OP_RETURN_CHAIN
// (parent number is returned as a variable 2^N number of bits)
// i.e. 0 bits = everything is read from the inode itself
// 1 bit = inode(0) or its parent(1)
// 2 bits = inode(0) or its 1-3 parents
// 4 bits = inode(0) or its 1-7 parents
// and etc
// chain size in bits is (op->req.rw.len / bitmap_granularity * chain_bits_per_block + 7) / 8
uint32_t chain_bits_per_block;
};
struct __attribute__((__packed__)) osd_reply_del_t