Skip to content

Commit 86107a4

Browse files
committed
crimson/os/seastore: do "copy_on_write" if the to-be-modified object
needs it At present, only clone objects may need COW, as HEAD objects won't be sharing any direct lba mapping with other objects in non-recovery scenarios. Although the HEAD object may share its direct mappings with the temp object that's going to be recovered and replace it, it won't be accepting any modifications at that time. Signed-off-by: Xuehan Xu <[email protected]>
1 parent 039314e commit 86107a4

File tree

3 files changed

+80
-29
lines changed

3 files changed

+80
-29
lines changed

src/crimson/os/seastore/object_data_handler.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,36 @@ ObjectDataHandler::clear_ret ObjectDataHandler::clear(
13831383
});
13841384
}
13851385

1386+
ObjectDataHandler::clone_ret
1387+
ObjectDataHandler::copy_on_write(
1388+
context_t ctx)
1389+
{
1390+
return with_object_data(
1391+
ctx,
1392+
[ctx, this](auto &object_data) -> clone_iertr::future<> {
1393+
auto mapping = co_await ctx.tm.get_pin(
1394+
ctx.t, object_data.get_reserved_data_base()
1395+
).handle_error_interruptible(
1396+
clone_iertr::pass_further{},
1397+
crimson::ct_error::assert_all{"unexpected enoent"}
1398+
);
1399+
object_data_t d_object_data = get_null_object_data();
1400+
co_await do_clone(ctx, object_data, d_object_data, mapping, false);
1401+
auto old_base = object_data.get_reserved_data_base();
1402+
auto old_len = object_data.get_reserved_data_len();
1403+
object_data.update_reserved(
1404+
d_object_data.get_reserved_data_base(),
1405+
d_object_data.get_reserved_data_len());
1406+
ctx.onode.unset_need_cow(ctx.t);
1407+
co_await ctx.tm.remove_mappings_in_range(
1408+
ctx.t, old_base, old_len, std::move(mapping), {false, true}
1409+
).handle_error_interruptible(
1410+
clone_iertr::pass_further{},
1411+
crimson::ct_error::assert_all{"unexpected enoent"}
1412+
).discard_result();
1413+
});
1414+
}
1415+
13861416
ObjectDataHandler::clone_ret
13871417
ObjectDataHandler::do_clone(
13881418
context_t ctx,

src/crimson/os/seastore/object_data_handler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ class ObjectDataHandler {
331331
using clone_ret = clone_iertr::future<>;
332332
clone_ret clone(context_t ctx);
333333

334+
clone_ret copy_on_write(context_t ctx);
335+
334336
private:
335337
/// Updates region [_offset, _offset + bl.length) to bl
336338
write_ret overwrite(

src/crimson/os/seastore/seastore.cc

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,12 +1891,18 @@ SeaStore::Shard::_remove(
18911891
ObjectDataHandler(max_object_size),
18921892
[&onode, this, &ctx](auto &objhandler)
18931893
{
1894-
return objhandler.clear(
1895-
ObjectDataHandler::context_t{
1896-
*transaction_manager,
1897-
*ctx.transaction,
1898-
*onode,
1899-
});
1894+
auto fut = ObjectDataHandler::clone_iertr::now();
1895+
auto objctx = ObjectDataHandler::context_t{
1896+
*transaction_manager,
1897+
*ctx.transaction,
1898+
*onode,
1899+
};
1900+
if (onode->need_cow()) {
1901+
fut = objhandler.copy_on_write(objctx);
1902+
}
1903+
return fut.si_then([&objhandler, objctx] {
1904+
return objhandler.clear(objctx);
1905+
});
19001906
});
19011907
}).si_then([this, &ctx, &onode] {
19021908
return onode_manager->erase_onode(*ctx.transaction, onode);
@@ -1934,14 +1940,18 @@ SeaStore::Shard::_write(
19341940
std::move(_bl),
19351941
ObjectDataHandler(max_object_size),
19361942
[=, this, &ctx, &onode](auto &bl, auto &objhandler) {
1937-
return objhandler.write(
1938-
ObjectDataHandler::context_t{
1939-
*transaction_manager,
1940-
*ctx.transaction,
1941-
onode,
1942-
},
1943-
offset,
1944-
bl);
1943+
auto fut = ObjectDataHandler::clone_iertr::now();
1944+
auto objctx = ObjectDataHandler::context_t{
1945+
*transaction_manager,
1946+
*ctx.transaction,
1947+
onode,
1948+
};
1949+
if (onode.need_cow()) {
1950+
fut = objhandler.copy_on_write(objctx);
1951+
}
1952+
return fut.si_then([&objhandler, objctx, offset, &bl] {
1953+
return objhandler.write(objctx, offset, bl);
1954+
});
19451955
});
19461956
}
19471957

@@ -2023,14 +2033,18 @@ SeaStore::Shard::_zero(
20232033
return seastar::do_with(
20242034
ObjectDataHandler(max_object_size),
20252035
[=, this, &ctx, &onode](auto &objhandler) {
2026-
return objhandler.zero(
2027-
ObjectDataHandler::context_t{
2028-
*transaction_manager,
2029-
*ctx.transaction,
2030-
onode,
2031-
},
2032-
offset,
2033-
len);
2036+
auto fut = ObjectDataHandler::clone_iertr::now();
2037+
auto objctx = ObjectDataHandler::context_t{
2038+
*transaction_manager,
2039+
*ctx.transaction,
2040+
onode,
2041+
};
2042+
if (onode.need_cow()) {
2043+
fut = objhandler.copy_on_write(objctx);
2044+
}
2045+
return fut.si_then([&objhandler, objctx, offset, len] {
2046+
return objhandler.zero(objctx, offset, len);
2047+
});
20342048
});
20352049
}
20362050

@@ -2079,13 +2093,18 @@ SeaStore::Shard::_truncate(
20792093
return seastar::do_with(
20802094
ObjectDataHandler(max_object_size),
20812095
[=, this, &ctx, &onode](auto &objhandler) {
2082-
return objhandler.truncate(
2083-
ObjectDataHandler::context_t{
2084-
*transaction_manager,
2085-
*ctx.transaction,
2086-
onode
2087-
},
2088-
size);
2096+
auto fut = ObjectDataHandler::clone_iertr::now();
2097+
auto objctx = ObjectDataHandler::context_t{
2098+
*transaction_manager,
2099+
*ctx.transaction,
2100+
onode,
2101+
};
2102+
if (onode.need_cow()) {
2103+
fut = objhandler.copy_on_write(objctx);
2104+
}
2105+
return fut.si_then([&objhandler, objctx, size] {
2106+
return objhandler.truncate(objctx, size);
2107+
});
20892108
});
20902109
}
20912110

0 commit comments

Comments
 (0)