forked from vitalif/vitastor
Implement min/max inode filters in LIST operation
parent
a8b3cbd6af
commit
0918ea08fa
|
@ -114,6 +114,8 @@ Input:
|
||||||
- oid.stripe = PG alignment
|
- oid.stripe = PG alignment
|
||||||
- len = PG count or 0 to list all objects
|
- len = PG count or 0 to list all objects
|
||||||
- offset = PG number
|
- offset = PG number
|
||||||
|
- oid.inode = min inode number or 0 to list all inodes
|
||||||
|
- version = max inode number or 0 to list all inodes
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
- retval = total obj_ver_id count
|
- retval = total obj_ver_id count
|
||||||
|
|
|
@ -431,10 +431,12 @@ static bool replace_stable(object_id oid, uint64_t version, int search_start, in
|
||||||
|
|
||||||
void blockstore_impl_t::process_list(blockstore_op_t *op)
|
void blockstore_impl_t::process_list(blockstore_op_t *op)
|
||||||
{
|
{
|
||||||
// Check PG
|
|
||||||
uint32_t list_pg = op->offset;
|
uint32_t list_pg = op->offset;
|
||||||
uint32_t pg_count = op->len;
|
uint32_t pg_count = op->len;
|
||||||
uint64_t pg_stripe_size = op->oid.stripe;
|
uint64_t pg_stripe_size = op->oid.stripe;
|
||||||
|
uint64_t min_inode = op->oid.inode;
|
||||||
|
uint64_t max_inode = op->version;
|
||||||
|
// Check PG
|
||||||
if (pg_count != 0 && (pg_stripe_size < MIN_BLOCK_SIZE || list_pg >= pg_count))
|
if (pg_count != 0 && (pg_stripe_size < MIN_BLOCK_SIZE || list_pg >= pg_count))
|
||||||
{
|
{
|
||||||
op->retval = -EINVAL;
|
op->retval = -EINVAL;
|
||||||
|
@ -450,9 +452,22 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
|
||||||
FINISH_OP(op);
|
FINISH_OP(op);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto it = clean_db.begin(); it != clean_db.end(); it++)
|
|
||||||
{
|
{
|
||||||
if (!pg_count || ((it->first.inode + it->first.stripe / pg_stripe_size) % pg_count) == list_pg)
|
auto clean_it = clean_db.begin(), clean_end = clean_db.end();
|
||||||
|
if ((min_inode != 0 || max_inode != 0) && min_inode <= max_inode)
|
||||||
|
{
|
||||||
|
clean_it = clean_db.lower_bound({
|
||||||
|
.inode = min_inode,
|
||||||
|
.stripe = 0,
|
||||||
|
});
|
||||||
|
clean_end = clean_db.upper_bound({
|
||||||
|
.inode = max_inode,
|
||||||
|
.stripe = UINT64_MAX,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (; clean_it != clean_end; clean_it++)
|
||||||
|
{
|
||||||
|
if (!pg_count || ((clean_it->first.inode + clean_it->first.stripe / pg_stripe_size) % pg_count) == list_pg)
|
||||||
{
|
{
|
||||||
if (stable_count >= stable_alloc)
|
if (stable_count >= stable_alloc)
|
||||||
{
|
{
|
||||||
|
@ -466,36 +481,56 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stable[stable_count++] = {
|
stable[stable_count++] = {
|
||||||
.oid = it->first,
|
.oid = clean_it->first,
|
||||||
.version = it->second.version,
|
.version = clean_it->second.version,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
int clean_stable_count = stable_count;
|
int clean_stable_count = stable_count;
|
||||||
// Copy dirty_db entries (sorted, too)
|
// Copy dirty_db entries (sorted, too)
|
||||||
int unstable_count = 0, unstable_alloc = 0;
|
int unstable_count = 0, unstable_alloc = 0;
|
||||||
obj_ver_id *unstable = NULL;
|
obj_ver_id *unstable = NULL;
|
||||||
for (auto it = dirty_db.begin(); it != dirty_db.end(); it++)
|
|
||||||
{
|
{
|
||||||
if (!pg_count || ((it->first.oid.inode + it->first.oid.stripe / pg_stripe_size) % pg_count) == list_pg)
|
auto dirty_it = dirty_db.begin(), dirty_end = dirty_db.end();
|
||||||
|
if ((min_inode != 0 || max_inode != 0) && min_inode <= max_inode)
|
||||||
{
|
{
|
||||||
if (IS_DELETE(it->second.state))
|
dirty_it = dirty_db.lower_bound({
|
||||||
|
.oid = {
|
||||||
|
.inode = min_inode,
|
||||||
|
.stripe = 0,
|
||||||
|
},
|
||||||
|
.version = 0,
|
||||||
|
});
|
||||||
|
dirty_end = dirty_db.upper_bound({
|
||||||
|
.oid = {
|
||||||
|
.inode = max_inode,
|
||||||
|
.stripe = UINT64_MAX,
|
||||||
|
},
|
||||||
|
.version = UINT64_MAX,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (; dirty_it != dirty_end; dirty_it++)
|
||||||
|
{
|
||||||
|
if (!pg_count || ((dirty_it->first.oid.inode + dirty_it->first.oid.stripe / pg_stripe_size) % pg_count) == list_pg)
|
||||||
|
{
|
||||||
|
if (IS_DELETE(dirty_it->second.state))
|
||||||
{
|
{
|
||||||
// Deletions are always stable, so try to zero out two possible entries
|
// Deletions are always stable, so try to zero out two possible entries
|
||||||
if (!replace_stable(it->first.oid, 0, 0, clean_stable_count, stable))
|
if (!replace_stable(dirty_it->first.oid, 0, 0, clean_stable_count, stable))
|
||||||
{
|
{
|
||||||
replace_stable(it->first.oid, 0, clean_stable_count, stable_count, stable);
|
replace_stable(dirty_it->first.oid, 0, clean_stable_count, stable_count, stable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IS_STABLE(it->second.state))
|
else if (IS_STABLE(dirty_it->second.state))
|
||||||
{
|
{
|
||||||
// First try to replace a clean stable version in the first part of the list
|
// First try to replace a clean stable version in the first part of the list
|
||||||
if (!replace_stable(it->first.oid, it->first.version, 0, clean_stable_count, stable))
|
if (!replace_stable(dirty_it->first.oid, dirty_it->first.version, 0, clean_stable_count, stable))
|
||||||
{
|
{
|
||||||
// Then try to replace the last dirty stable version in the second part of the list
|
// Then try to replace the last dirty stable version in the second part of the list
|
||||||
if (stable[stable_count-1].oid == it->first.oid)
|
if (stable[stable_count-1].oid == dirty_it->first.oid)
|
||||||
{
|
{
|
||||||
stable[stable_count-1].version = it->first.version;
|
stable[stable_count-1].version = dirty_it->first.version;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -512,7 +547,7 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stable[stable_count++] = it->first;
|
stable[stable_count++] = dirty_it->first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,7 +566,8 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unstable[unstable_count++] = it->first;
|
unstable[unstable_count++] = dirty_it->first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,10 @@ struct __attribute__((__packed__)) osd_op_secondary_list_t
|
||||||
osd_op_header_t header;
|
osd_op_header_t header;
|
||||||
// placement group total number and total count
|
// placement group total number and total count
|
||||||
pg_num_t list_pg, pg_count;
|
pg_num_t list_pg, pg_count;
|
||||||
|
// size of an area that maps to one PG continuously
|
||||||
uint64_t pg_stripe_size;
|
uint64_t pg_stripe_size;
|
||||||
|
// inode range (used to select pools)
|
||||||
|
uint64_t min_inode, max_inode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((__packed__)) osd_reply_secondary_list_t
|
struct __attribute__((__packed__)) osd_reply_secondary_list_t
|
||||||
|
|
|
@ -90,6 +90,8 @@ void osd_t::exec_secondary(osd_op_t *cur_op)
|
||||||
cur_op->bs_op->oid.stripe = cur_op->req.sec_list.pg_stripe_size;
|
cur_op->bs_op->oid.stripe = cur_op->req.sec_list.pg_stripe_size;
|
||||||
cur_op->bs_op->len = cur_op->req.sec_list.pg_count;
|
cur_op->bs_op->len = cur_op->req.sec_list.pg_count;
|
||||||
cur_op->bs_op->offset = cur_op->req.sec_list.list_pg - 1;
|
cur_op->bs_op->offset = cur_op->req.sec_list.list_pg - 1;
|
||||||
|
cur_op->bs_op->oid.inode = cur_op->req.sec_list.min_inode;
|
||||||
|
cur_op->bs_op->version = cur_op->req.sec_list.max_inode;
|
||||||
#ifdef OSD_STUB
|
#ifdef OSD_STUB
|
||||||
cur_op->bs_op->retval = 0;
|
cur_op->bs_op->retval = 0;
|
||||||
cur_op->bs_op->buf = NULL;
|
cur_op->bs_op->buf = NULL;
|
||||||
|
|
Loading…
Reference in New Issue