diff options
author | Kefu Chai <kchai@redhat.com> | 2020-08-04 04:37:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-04 04:37:12 +0200 |
commit | 69c70bd96f6481175ceaab4fc09416ca9febc0ad (patch) | |
tree | 85fad301955af2822c4bf33ff4eb24a8d31a16f8 | |
parent | Merge pull request #36398 from jdurgin/wip-pg-log-doc (diff) | |
parent | crimson/osd: add support for CEPH_OSD_OP_TRUNCATE. (diff) | |
download | ceph-69c70bd96f6481175ceaab4fc09416ca9febc0ad.tar.xz ceph-69c70bd96f6481175ceaab4fc09416ca9febc0ad.zip |
Merge pull request #36442 from rzarzynski/wip-crimson-op_truncate
crimson/osd: add support for CEPH_OSD_OP_TRUNCATE.
Reviewed-by: Kefu Chai <kchai@redhat.com>
-rw-r--r-- | src/crimson/common/errorator.h | 2 | ||||
-rw-r--r-- | src/crimson/osd/ops_executer.cc | 7 | ||||
-rw-r--r-- | src/crimson/osd/ops_executer.h | 2 | ||||
-rw-r--r-- | src/crimson/osd/pg_backend.cc | 61 | ||||
-rw-r--r-- | src/crimson/osd/pg_backend.h | 8 |
5 files changed, 80 insertions, 0 deletions
diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 95454ca424c..52ade2dde1f 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -964,6 +964,8 @@ namespace ct_error { using value_too_large = ct_error_code<std::errc::value_too_large>; using eagain = ct_error_code<std::errc::resource_unavailable_try_again>; + using file_too_large = + ct_error_code<std::errc::file_too_large>; struct pass_further_all { template <class ErrorT> diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index 739b7c65e33..a313beaf348 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -709,6 +709,13 @@ OpsExecuter::execute_osd_op(OSDOp& osd_op) osd_op_params = osd_op_params_t(); return backend.writefull(os, osd_op, txn, *osd_op_params); }, true); + case CEPH_OSD_OP_TRUNCATE: + return do_write_op([this, &osd_op] (auto& backend, auto& os, auto& txn) { + // FIXME: rework needed. Move this out to do_write_op(), introduce + // do_write_op_no_user_modify()... + osd_op_params = osd_op_params_t(); + return backend.truncate(os, osd_op, txn, *osd_op_params); + }, true); case CEPH_OSD_OP_SETALLOCHINT: return osd_op_errorator::now(); case CEPH_OSD_OP_SETXATTR: diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index 8c5168dc8bb..036c02632c0 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -45,6 +45,7 @@ class OpsExecuter { crimson::ct_error::input_output_error, crimson::ct_error::value_too_large>; using read_errorator = PGBackend::read_errorator; + using write_ertr = PGBackend::write_ertr; using get_attr_errorator = PGBackend::get_attr_errorator; using watch_errorator = crimson::errorator< crimson::ct_error::enoent, @@ -62,6 +63,7 @@ public: using osd_op_errorator = crimson::compound_errorator_t< call_errorator, read_errorator, + write_ertr, get_attr_errorator, watch_errorator, PGBackend::stat_errorator>; diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 2daecc49acb..bb1e36c7684 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -250,6 +250,21 @@ bool PGBackend::maybe_create_new_object( return true; } +static bool is_offset_and_length_valid( + const std::uint64_t offset, + const std::uint64_t length) +{ + if (const std::uint64_t max = local_conf()->osd_max_object_size; + offset >= max || length > max || offset + length > max) { + logger().debug("{} osd_max_object_size: {}, offset: {}, len: {}; " + "Hard limit of object size is 4GB", + __func__, max, offset, length); + return false; + } else { + return true; + } +} + seastar::future<> PGBackend::write( ObjectState& os, const OSDOp& osd_op, @@ -340,6 +355,52 @@ seastar::future<> PGBackend::writefull( return seastar::now(); } +PGBackend::write_ertr::future<> PGBackend::truncate( + ObjectState& os, + const OSDOp& osd_op, + ceph::os::Transaction& txn, + osd_op_params_t& osd_op_params) +{ + if (!os.exists || os.oi.is_whiteout()) { + logger().debug("{} object dne, truncate is a no-op", __func__); + return write_ertr::now(); + } + const ceph_osd_op& op = osd_op.op; + if (!is_offset_and_length_valid(op.extent.offset, op.extent.length)) { + return crimson::ct_error::file_too_large::make(); + } + if (op.extent.truncate_seq) { + assert(op.extent.offset == op.extent.truncate_size); + if (op.extent.truncate_seq <= os.oi.truncate_seq) { + logger().debug("{} truncate seq {} <= current {}, no-op", + __func__, op.extent.truncate_seq, os.oi.truncate_seq); + return write_ertr::make_ready_future<>(); + } else { + logger().debug("{} truncate seq {} > current {}, truncating", + __func__, op.extent.truncate_seq, os.oi.truncate_seq); + os.oi.truncate_seq = op.extent.truncate_seq; + os.oi.truncate_size = op.extent.truncate_size; + } + } + maybe_create_new_object(os, txn); + txn.truncate(coll->get_cid(), + ghobject_t{os.oi.soid}, op.extent.offset); + if (os.oi.size > op.extent.offset) { + // TODO: modified_ranges.union_of(trim); + osd_op_params.clean_regions.mark_data_region_dirty(op.extent.offset, + os.oi.size - op.extent.offset); + } else if (os.oi.size < op.extent.offset) { + osd_op_params.clean_regions.mark_data_region_dirty(os.oi.size, + op.extent.offset - os.oi.size); + } + // TODO: truncate_update_size_and_usage() + // TODO: ctx->delta_stats.num_wr++; + // ---- + // do no set exists, or we will break above DELETE -> TRUNCATE munging. + os.oi.clear_data_digest(); + return write_ertr::now(); +} + seastar::future<> PGBackend::create( ObjectState& os, const OSDOp& osd_op, diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index 88fe608722f..dec58406eb3 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -68,6 +68,9 @@ public: const ObjectState& os, OSDOp& osd_op); + // TODO: switch the entire write family to errorator. + using write_ertr = crimson::errorator< + crimson::ct_error::file_too_large>; seastar::future<> create( ObjectState& os, const OSDOp& osd_op, @@ -85,6 +88,11 @@ public: const OSDOp& osd_op, ceph::os::Transaction& trans, osd_op_params_t& osd_op_params); + write_ertr::future<> truncate( + ObjectState& os, + const OSDOp& osd_op, + ceph::os::Transaction& trans, + osd_op_params_t& osd_op_params); seastar::future<crimson::osd::acked_peers_t> mutate_object( std::set<pg_shard_t> pg_shards, crimson::osd::ObjectContextRef &&obc, |