Skip to content

Commit

Permalink
osd: prevent deleting object (has manifest) if the object is referenced
Browse files Browse the repository at this point in the history
Signed-off-by: Myoungwon Oh <omwmw@sk.com>
  • Loading branch information
myoungwon committed Jan 15, 2018
1 parent 4728ce7 commit d5e5e56
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/osd/PrimaryLogPG.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3406,6 +3406,41 @@ void PrimaryLogPG::refcount_manifest(ObjectContextRef obc, object_locator_t oloc
flags, new C_OnFinisher(cb, osd->objecter_finishers[n]));
}

int PrimaryLogPG::read_refcount_manifest(OpContext *ctx)
{
ClassHandler::ClassData *cls;
int result = osd->class_handler->open_class("refcount", &cls);
assert(result == 0); // init_op_flags() already verified this works.
ClassHandler::ClassMethod *method = cls->get_method("read");
if (!method) {
dout(10) << "call method does not exist" << dendl;
return -EOPNOTSUPP;
}
bufferlist outdata, indata;
int prev_rd = ctx->num_read;
int flags = method->get_flags();
assert(flags & CLS_METHOD_RD);
result = method->exec((cls_method_context_t)&ctx, indata, outdata);

if (ctx->num_read > prev_rd) {
derr << "method " << " tried to read object but is not completed" << dendl;
result = -EIO;
}
if (result > 0) {
return result;
}

cls_refcount_read_ret ret;
try {
bufferlist::iterator iter = outdata.begin();
decode(ret, iter);
} catch (buffer::error& err) {
return -EIO;
}
list<string> refs = ret.refs;
return refs.size();
}

void PrimaryLogPG::do_proxy_chunked_read(OpRequestRef op, ObjectContextRef obc, int op_index,
uint64_t chunk_index, uint64_t req_offset, uint64_t req_length,
uint64_t req_total_len, bool write_ordered)
Expand Down Expand Up @@ -6475,6 +6510,14 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
++ctx->num_write;
tracepoint(osd, do_osd_op_pre_delete, soid.oid.name.c_str(), soid.snap.val);
{
if (ctx->obc->obs.oi.has_manifest()) {
int ref = read_refcount_manifest(ctx);
if (ref) {
result = 0;
dout(10) << " refcount is " << ref << dendl;
break;
}
}
result = _delete_oid(ctx, false, ctx->ignore_cache);
}
break;
Expand Down
1 change: 1 addition & 0 deletions src/osd/PrimaryLogPG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,7 @@ class PrimaryLogPG : public PG, public PGBackend::Listener {
uint64_t offset, uint64_t last_offset);
void refcount_manifest(ObjectContextRef obc, object_locator_t oloc, hobject_t soid,
SnapContext snapc, string method, Context *cb);
int read_refcount_manifest(OpContext *ctx);

friend struct C_ProxyChunkRead;
friend class PromoteManifestCallback;
Expand Down

0 comments on commit d5e5e56

Please sign in to comment.