mirror of
https://github.com/ceph/ceph
synced 2024-12-29 23:12:27 +00:00
osd,librados: a rados op to create chunked object
Signed-off-by: Myoungwon Oh <omwmw@sk.com>
This commit is contained in:
parent
e968c64795
commit
bb6f5dc173
@ -310,6 +310,7 @@ extern int ceph_release_from_features(uint64_t features);
|
||||
\
|
||||
/* Extensible */ \
|
||||
f(SET_REDIRECT, __CEPH_OSD_OP(WR, DATA, 39), "set-redirect") \
|
||||
f(SET_CHUNK, __CEPH_OSD_OP(WR, DATA, 40), "set-chunk") \
|
||||
\
|
||||
/** attrs **/ \
|
||||
/* read */ \
|
||||
|
@ -471,6 +471,9 @@ namespace librados
|
||||
*/
|
||||
void set_redirect(const std::string& tgt_obj, const IoCtx& tgt_ioctx,
|
||||
uint64_t tgt_version);
|
||||
void set_chunk(uint64_t src_offset, uint64_t src_length, const IoCtx& tgt_ioctx,
|
||||
std::string tgt_oid, uint64_t tgt_offset);
|
||||
|
||||
|
||||
friend class IoCtx;
|
||||
};
|
||||
|
@ -614,6 +614,17 @@ void librados::ObjectWriteOperation::set_redirect(const std::string& tgt_obj,
|
||||
tgt_ioctx.io_ctx_impl->oloc, tgt_version);
|
||||
}
|
||||
|
||||
void librados::ObjectWriteOperation::set_chunk(uint64_t src_offset,
|
||||
uint64_t src_length,
|
||||
const IoCtx& tgt_ioctx,
|
||||
string tgt_oid,
|
||||
uint64_t tgt_offset)
|
||||
{
|
||||
::ObjectOperation *o = &impl->o;
|
||||
o->set_chunk(src_offset, src_length,
|
||||
tgt_ioctx.io_ctx_impl->oloc, object_t(tgt_oid), tgt_offset);
|
||||
}
|
||||
|
||||
void librados::ObjectWriteOperation::tmap_put(const bufferlist &bl)
|
||||
{
|
||||
::ObjectOperation *o = &impl->o;
|
||||
|
@ -6105,6 +6105,68 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||
|
||||
break;
|
||||
|
||||
case CEPH_OSD_OP_SET_CHUNK:
|
||||
++ctx->num_write;
|
||||
{
|
||||
if (pool.info.is_tier()) {
|
||||
result = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (!obs.exists) {
|
||||
result = -ENOENT;
|
||||
break;
|
||||
}
|
||||
if (get_osdmap()->require_osd_release < CEPH_RELEASE_LUMINOUS) {
|
||||
result = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
object_locator_t tgt_oloc;
|
||||
uint64_t src_offset, src_length, tgt_offset;
|
||||
object_t tgt_name;
|
||||
try {
|
||||
::decode(src_offset, bp);
|
||||
::decode(src_length, bp);
|
||||
::decode(tgt_oloc, bp);
|
||||
::decode(tgt_name, bp);
|
||||
::decode(tgt_offset, bp);
|
||||
}
|
||||
catch (buffer::error& e) {
|
||||
result = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!src_length) {
|
||||
result = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!oi.manifest.is_chunked()) {
|
||||
oi.manifest.clear();
|
||||
}
|
||||
|
||||
pg_t raw_pg;
|
||||
chunk_info_t chunk_info;
|
||||
hobject_t target(tgt_name, tgt_oloc.key, snapid_t(),
|
||||
raw_pg.ps(), raw_pg.pool(),
|
||||
tgt_oloc.nspace);
|
||||
get_osdmap()->object_locator_to_pg(tgt_name, tgt_oloc, raw_pg);
|
||||
chunk_info.flags = chunk_info_t::FLAG_MISSING;
|
||||
chunk_info.oid = target;
|
||||
chunk_info.offset = tgt_offset;
|
||||
chunk_info.length= src_length;
|
||||
oi.manifest.chunk_map[src_offset] = chunk_info;
|
||||
|
||||
oi.set_flag(object_info_t::FLAG_MANIFEST);
|
||||
oi.manifest.type = object_manifest_t::TYPE_CHUNKED;
|
||||
ctx->modify = true;
|
||||
|
||||
dout(10) << "set-chunked oid:" << oi.soid << " user_version: " << oi.user_version
|
||||
<< " chunk_info: " << chunk_info << dendl;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// -- object attrs --
|
||||
|
||||
case CEPH_OSD_OP_SETXATTR:
|
||||
|
@ -4548,7 +4548,7 @@ struct chunk_info_t {
|
||||
hobject_t oid;
|
||||
uint32_t flags; // FLAG_*
|
||||
|
||||
chunk_info_t() : length(0), flags(0) { }
|
||||
chunk_info_t() : offset(0), length(0), flags(0) { }
|
||||
|
||||
static string get_flag_string(uint64_t flags) {
|
||||
string r;
|
||||
|
@ -1141,6 +1141,16 @@ struct ObjectOperation {
|
||||
::encode(tgt_oloc, osd_op.indata);
|
||||
}
|
||||
|
||||
void set_chunk(uint64_t src_offset, uint64_t src_length, object_locator_t tgt_oloc,
|
||||
object_t tgt_oid, uint64_t tgt_offset) {
|
||||
OSDOp& osd_op = add_op(CEPH_OSD_OP_SET_CHUNK);
|
||||
::encode(src_offset, osd_op.indata);
|
||||
::encode(src_length, osd_op.indata);
|
||||
::encode(tgt_oloc, osd_op.indata);
|
||||
::encode(tgt_oid, osd_op.indata);
|
||||
::encode(tgt_offset, osd_op.indata);
|
||||
}
|
||||
|
||||
void set_alloc_hint(uint64_t expected_object_size,
|
||||
uint64_t expected_write_size,
|
||||
uint32_t flags) {
|
||||
|
@ -122,6 +122,10 @@ void usage(ostream& out)
|
||||
" listwatchers <obj-name> list the watchers of this object\n"
|
||||
" set-alloc-hint <obj-name> <expected-object-size> <expected-write-size>\n"
|
||||
" set allocation hint for an object\n"
|
||||
" set-redirect <object A> --target-pool <caspool> <target object A>\n"
|
||||
" set redirect target\n"
|
||||
" set-chunk <object A> <offset> <length> --target-pool <caspool> <target object A> <taget-offset>\n"
|
||||
" convert an object to chunked object\n"
|
||||
"\n"
|
||||
"IMPORT AND EXPORT\n"
|
||||
" export [filename]\n"
|
||||
@ -3486,6 +3490,54 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
|
||||
cerr << "error set-redirect " << pool_name << "/" << nargs[1] << " => " << target << "/" << target_obj << ": " << cpp_strerror(ret) << std::endl;
|
||||
goto out;
|
||||
}
|
||||
} else if (strcmp(nargs[0], "set-chunk") == 0) {
|
||||
if (!pool_name)
|
||||
usage_exit();
|
||||
|
||||
const char *target = target_pool_name;
|
||||
if (!target)
|
||||
target = pool_name;
|
||||
|
||||
uint64_t offset;
|
||||
uint64_t length;
|
||||
uint64_t tgt_offset;
|
||||
string tgt_oid;
|
||||
if (nargs.size() < 6) {
|
||||
usage_exit();
|
||||
} else {
|
||||
char* endptr = NULL;
|
||||
offset = strtoull(nargs[2], &endptr, 10);
|
||||
if (*endptr) {
|
||||
cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
length = strtoull(nargs[3], &endptr, 10);
|
||||
if (*endptr) {
|
||||
cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
tgt_oid = string(nargs[4]);
|
||||
tgt_offset = strtoull(nargs[5], &endptr, 10);
|
||||
if (*endptr) {
|
||||
cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
IoCtx target_ctx;
|
||||
ret = rados.ioctx_create(target, target_ctx);
|
||||
ObjectWriteOperation op;
|
||||
op.set_chunk(offset, length, target_ctx, tgt_oid, tgt_offset);
|
||||
ret = io_ctx.operate(nargs[1], &op);
|
||||
if (ret < 0) {
|
||||
cerr << "error set-chunk " << pool_name << "/" << nargs[1] << " " << " offset " << offset
|
||||
<< " length " << length << " target_pool " << target
|
||||
<< "tgt_offset: " << tgt_offset << " : " << cpp_strerror(ret) << std::endl;
|
||||
goto out;
|
||||
}
|
||||
} else if (strcmp(nargs[0], "export") == 0) {
|
||||
// export [filename]
|
||||
if (!pool_name || nargs.size() > 2) {
|
||||
|
Loading…
Reference in New Issue
Block a user