using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp;
using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
using SingleAppendOp = ceph::io_exerciser::SingleAppendOp;
+using TruncateOp = ceph::io_exerciser::TruncateOp;
namespace {
std::string value_to_string(uint64_t v) {
return std::make_unique<SingleAppendOp>(length);
}
+TruncateOp::TruncateOp(uint64_t size)
+ : TestOp<OpType::Truncate>(), size(size) {}
+
+std::unique_ptr<TruncateOp> TruncateOp::generate(uint64_t size) {
+ return std::make_unique<TruncateOp>(size);
+}
+
+std::string TruncateOp::to_string(uint64_t block_size) const {
+ return "Truncate (size=" + value_to_string(size * block_size) + ")";
+}
+
SingleFailedWriteOp::SingleFailedWriteOp(uint64_t offset, uint64_t length)
: ReadWriteOp<OpType::FailedWrite, 1>({offset}, {length}) {}
static std::unique_ptr<SingleAppendOp> generate(uint64_t length);
};
+class TruncateOp : public TestOp<OpType::Truncate> {
+ public:
+ TruncateOp(uint64_t size);
+ static std::unique_ptr<TruncateOp> generate(uint64_t size);
+ std::string to_string(uint64_t block_size) const override;
+ uint64_t size;
+};
+
class SingleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite, 1> {
public:
SingleFailedWriteOp(uint64_t offset, uint64_t length);
generate_random);
break;
+ case OpType::Truncate:
+ ceph_assert(created);
+ ceph_assert(reads.empty());
+ ceph_assert(writes.empty());
+ contents.resize(static_cast<TruncateOp&>(op).size);
+ break;
+
case OpType::Remove:
ceph_assert(created);
ceph_assert(reads.empty());
Write2, // Two writes in a single op
Write3, // Three writes in a single op
Append, // Append
+ Truncate, // Truncate
FailedWrite, // A write which should fail
FailedWrite2, // Two writes in one op which should fail
FailedWrite3, // Three writes in one op which should fail
return fmt::format_to(ctx.out(), "Write3");
case ceph::io_exerciser::OpType::Append:
return fmt::format_to(ctx.out(), "Append");
+ case ceph::io_exerciser::OpType::Truncate:
+ return fmt::format_to(ctx.out(), "Truncate");
case ceph::io_exerciser::OpType::FailedWrite:
return fmt::format_to(ctx.out(), "FailedWrite");
case ceph::io_exerciser::OpType::FailedWrite2:
break;
}
+ case OpType::Truncate: {
+ start_io();
+ uint64_t opSize = static_cast<TruncateOp&>(op).size;
+ auto op_info = std::make_shared<AsyncOpInfo<0>>();
+ librados::ObjectWriteOperation wop;
+ wop.truncate(opSize * block_size);
+ auto truncate_cb = [this](boost::system::error_code ec, version_t ver) {
+ ceph_assert(ec == boost::system::errc::success);
+ finish_io();
+ };
+ librados::async_operate(asio.get_executor(), io, oid, std::move(wop), 0,
+ nullptr, truncate_cb);
+ break;
+ }
+
case OpType::Remove: {
start_io();
auto op_info = std::make_shared<AsyncOpInfo<0>>();
using DoubleWriteOp = ceph::io_exerciser::DoubleWriteOp;
using TripleWriteOp = ceph::io_exerciser::TripleWriteOp;
using SingleAppendOp = ceph::io_exerciser::SingleAppendOp;
+using TruncateOp = ceph::io_exerciser::TruncateOp;
using SingleFailedWriteOp = ceph::io_exerciser::SingleFailedWriteOp;
using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp;
using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
} else if (op == "append") {
uint64_t length = get_numeric_token();
ioop = SingleAppendOp::generate(length);
+ } else if (op == "truncate") {
+ ioop = TruncateOp::generate(get_numeric_token());
} else if (op == "failedwrite") {
uint64_t offset = get_numeric_token();
uint64_t length = get_numeric_token();