diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-17 21:06:19 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-17 21:06:19 -0700 |
commit | fbe816a1351a36fe23aa79f2895f205cf412190b (patch) | |
tree | 5026d68e72acb9008b9327f3d68d645e89fa2064 | |
parent | 7669662b6200b8837ca695099fae395dcce86517 (diff) | |
download | ceph-fbe816a1351a36fe23aa79f2895f205cf412190b.tar.gz |
cls_statelog: fixes and changes to api
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/cls/statelog/cls_statelog.cc | 81 | ||||
-rw-r--r-- | src/cls/statelog/cls_statelog_ops.h | 18 |
2 files changed, 63 insertions, 36 deletions
diff --git a/src/cls/statelog/cls_statelog.cc b/src/cls/statelog/cls_statelog.cc index c17527ceea6..8daaa415447 100644 --- a/src/cls/statelog/cls_statelog.cc +++ b/src/cls/statelog/cls_statelog.cc @@ -66,6 +66,46 @@ static void get_index_by_object(cls_statelog_entry& entry, string& index) get_index_by_object(entry.object, entry.op_id, index); } +static int get_existing_entry(cls_method_context_t hctx, const string& client_id, + const string& op_id, const string& object, + cls_statelog_entry& entry) +{ + if ((object.empty() && client_id.empty()) || op_id.empty()) { + return -EINVAL; + } + + string obj_index; + if (!object.empty()) { + get_index_by_object(object, op_id, obj_index); + } else { + get_index_by_client(client_id, op_id, obj_index); + } + + bufferlist bl; + int rc = cls_cxx_map_get_val(hctx, obj_index, &bl); + if (rc < 0) { + CLS_LOG(0, "could not find entry %s", obj_index.c_str()); + return rc; + } + try { + bufferlist::iterator iter = bl.begin(); + ::decode(entry, iter); + } catch (buffer::error& err) { + CLS_LOG(0, "ERROR: failed to decode entry %s", obj_index.c_str()); + return -EIO; + } + + if ((!object.empty() && entry.object != object) || + (!client_id.empty() && entry.client_id != client_id)){ + /* ouch, we were passed inconsistent client_id / object */ + CLS_LOG(0, "data mismatch: object=%s client_id=%s entry: object=%s client_id=%s", + object.c_str(), client_id.c_str(), entry.object.c_str(), entry.client_id.c_str()); + return -EINVAL; + } + + return 0; +} + static int cls_statelog_add(cls_method_context_t hctx, bufferlist *in, bufferlist *out) { bufferlist::iterator in_iter = in->begin(); @@ -192,39 +232,24 @@ static int cls_statelog_remove(cls_method_context_t hctx, bufferlist *in, buffer return -EINVAL; } - if (op.object.empty() || op.op_id.empty()) { - CLS_LOG(0, "object name or op id not specified"); - return -EINVAL; - } + cls_statelog_entry entry; + + int rc = get_existing_entry(hctx, op.client_id, op.op_id, op.object, entry); + if (rc < 0) + return rc; string obj_index; - get_index_by_object(op.object, op.op_id, obj_index); + get_index_by_object(entry.object, entry.op_id, obj_index); - bufferlist bl; - int rc = cls_cxx_map_get_val(hctx, obj_index, &bl); + rc = cls_cxx_map_remove_key(hctx, obj_index); if (rc < 0) { - CLS_LOG(0, "could not find entry %s", obj_index.c_str()); + CLS_LOG(0, "ERROR: failed to remove key"); return rc; } - cls_statelog_entry entry; - - try { - bufferlist::iterator iter = bl.begin(); - ::decode(entry, iter); - } catch (buffer::error& err) { - CLS_LOG(0, "ERROR: failed to decode entry %s", obj_index.c_str()); - return -EIO; - } - string client_index; get_index_by_client(entry.client_id, entry.op_id, client_index); - rc = cls_cxx_map_remove_key(hctx, obj_index); - if (rc < 0) { - CLS_LOG(0, "ERROR: failed to remove key"); - return rc; - } rc = cls_cxx_map_remove_key(hctx, client_index); if (rc < 0) { CLS_LOG(0, "ERROR: failed to remove key"); @@ -263,13 +288,9 @@ static int cls_statelog_check_state(cls_method_context_t hctx, bufferlist *in, b cls_statelog_entry entry; - try { - bufferlist::iterator iter = bl.begin(); - ::decode(entry, iter); - } catch (buffer::error& err) { - CLS_LOG(0, "ERROR: failed to decode entry %s", obj_index.c_str()); - return -EIO; - } + rc = get_existing_entry(hctx, op.client_id, op.op_id, op.object, entry); + if (rc < 0) + return rc; if (entry.state != op.state) return -ECANCELED; diff --git a/src/cls/statelog/cls_statelog_ops.h b/src/cls/statelog/cls_statelog_ops.h index aa5f7885bb6..725fa863df7 100644 --- a/src/cls/statelog/cls_statelog_ops.h +++ b/src/cls/statelog/cls_statelog_ops.h @@ -89,46 +89,52 @@ WRITE_CLASS_ENCODER(cls_statelog_list_ret) * -ENODATA when done, so caller needs to repeat sending request until that. */ struct cls_statelog_remove_op { - string object; + string client_id; string op_id; + string object; cls_statelog_remove_op() {} void encode(bufferlist& bl) const { ENCODE_START(1, 1, bl); - ::encode(object, bl); + ::encode(client_id, bl); ::encode(op_id, bl); + ::encode(object, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { DECODE_START(1, bl); - ::decode(object, bl); + ::decode(client_id, bl); ::decode(op_id, bl); + ::decode(object, bl); DECODE_FINISH(bl); } }; WRITE_CLASS_ENCODER(cls_statelog_remove_op) struct cls_statelog_check_state_op { - string object; + string client_id; string op_id; + string object; uint32_t state; cls_statelog_check_state_op() {} void encode(bufferlist& bl) const { ENCODE_START(1, 1, bl); - ::encode(object, bl); + ::encode(client_id, bl); ::encode(op_id, bl); + ::encode(object, bl); ::encode(state, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { DECODE_START(1, bl); - ::decode(object, bl); + ::decode(client_id, bl); ::decode(op_id, bl); + ::decode(object, bl); ::decode(state, bl); DECODE_FINISH(bl); } |