]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw, cls_rgw: don't remove olh objects
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 2 Oct 2014 22:02:42 +0000 (15:02 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 16 Jan 2015 22:41:43 +0000 (14:41 -0800)
A single head object can contain both olh data, and object data. Don't
remove object if it has olh information on it, just reset the other
info.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/cls/rgw/cls_rgw.cc
src/cls/rgw/cls_rgw_client.cc
src/cls/rgw/cls_rgw_client.h
src/cls/rgw/cls_rgw_ops.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 9c4814c8610ed86874ab0d16c55edc82be30306f..f483bf3ffb198e9ef4aa4b0b3930838c494c5f15 100644 (file)
@@ -31,6 +31,7 @@ cls_method_handle_t h_rgw_bucket_complete_op;
 cls_method_handle_t h_rgw_bucket_link_olh;
 cls_method_handle_t h_rgw_bucket_read_olh_log;
 cls_method_handle_t h_rgw_bucket_trim_olh_log;
+cls_method_handle_t h_rgw_obj_remove;
 cls_method_handle_t h_rgw_bi_log_list_op;
 cls_method_handle_t h_rgw_dir_suggest_changes;
 cls_method_handle_t h_rgw_user_usage_log_add;
@@ -1277,6 +1278,63 @@ int rgw_dir_suggest_changes(cls_method_context_t hctx, bufferlist *in, bufferlis
   return 0;
 }
 
+static int rgw_obj_remove(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  // decode request
+  rgw_cls_obj_remove_op op;
+  bufferlist::iterator iter = in->begin();
+  try {
+    ::decode(op, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(0, "ERROR: %s(): failed to decode request", __func__);
+    return -EINVAL;
+  }
+
+  if (op.keep_attr_prefixes.empty()) {
+    return cls_cxx_remove(hctx);
+  }
+
+  map<string, bufferlist> attrset;
+  int ret = cls_cxx_getxattrs(hctx, &attrset);
+  if (ret < 0 && ret != -ENOENT) {
+    CLS_LOG(0, "ERROR: %s(): cls_cxx_getxattrs() returned %d", __func__, ret);
+    return ret;
+  }
+
+  CLS_LOG(20, "%s(): removing object", __func__);
+  ret = cls_cxx_remove(hctx);
+  if (ret < 0) {
+    CLS_LOG(0, "ERROR: %s(): cls_cxx_remove returned %d", __func__, ret);
+    return ret;
+  }
+
+  map<string, bufferlist> new_attrs;
+  for (list<string>::iterator iter = op.keep_attr_prefixes.begin();
+       iter != op.keep_attr_prefixes.end(); ++iter) {
+    string& check_prefix = *iter;
+
+    for (map<string, bufferlist>::iterator aiter = attrset.lower_bound(check_prefix);
+         aiter != attrset.end(); ++aiter) {
+      const string& attr = aiter->first;
+
+      if (attr.substr(0, check_prefix.size()) > check_prefix) {
+        break;
+      }
+
+      ret = cls_cxx_setxattr(hctx, attr.c_str(), &aiter->second);
+      CLS_LOG(20, "%s(): setting attr: %s", __func__, attr.c_str());
+      if (ret < 0) {
+        CLS_LOG(0, "ERROR: %s(): cls_cxx_setxattr (attr=%s) returned %d", __func__, attr.c_str(), ret);
+        return ret;
+      }
+    }
+  }
+
+
+
+  return 0;
+}
+
 int bi_log_record_decode(bufferlist& bl, rgw_bi_log_entry& e)
 {
   bufferlist::iterator iter = bl.begin();
@@ -2096,6 +2154,8 @@ void __cls_init()
   cls_register_cxx_method(h_class, "bucket_read_olh_log", CLS_METHOD_RD, rgw_bucket_read_olh_log, &h_rgw_bucket_read_olh_log);
   cls_register_cxx_method(h_class, "bucket_trim_olh_log", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_trim_olh_log, &h_rgw_bucket_trim_olh_log);
 
+  cls_register_cxx_method(h_class, "obj_remove", CLS_METHOD_RD | CLS_METHOD_WR, rgw_obj_remove, &h_rgw_obj_remove);
+
   cls_register_cxx_method(h_class, "bi_log_list", CLS_METHOD_RD, rgw_bi_log_list, &h_rgw_bi_log_list_op);
   cls_register_cxx_method(h_class, "bi_log_trim", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bi_log_trim, &h_rgw_bi_log_list_op);
   cls_register_cxx_method(h_class, "dir_suggest_changes", CLS_METHOD_RD | CLS_METHOD_WR, rgw_dir_suggest_changes, &h_rgw_dir_suggest_changes);
index 7b16ebc4cf2f7654f2e2b00fd3e85edb0d06f528..be9fe0e942eece4b6184ea22eb0dc4e0339b0902 100644 (file)
@@ -94,6 +94,15 @@ int cls_rgw_list_op(IoCtx& io_ctx, const string& oid,
  return r;
 }
 
+void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_attr_prefixes)
+{
+  bufferlist in;
+  struct rgw_cls_obj_remove_op call;
+  call.keep_attr_prefixes = keep_attr_prefixes;
+  ::encode(call, in);
+  o.exec("rgw", "obj_remove", in);
+}
+
 int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key,
                             bool delete_marker, const string& op_tag)
 {
index d6186d760352fe067fd9f9048d56ecd140ba264d..1d9105321c11eda7e716ab553f126c0b3bbc30ef 100644 (file)
@@ -31,6 +31,8 @@ int cls_rgw_list_op(librados::IoCtx& io_ctx, const string& oid,
                     const string& filter_prefix, uint32_t num_entries, bool list_versions,
                     rgw_bucket_dir *dir, bool *is_truncated);
 
+void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_attr_prefixes);
+
 int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key,
                             bool delete_marker, const string& op_tag);
 int cls_rgw_get_olh_log(librados::IoCtx& io_ctx, string& oid, const cls_rgw_obj_key& olh, uint64_t ver_marker,
index 7b388175aeb24f14c15bf392db586882135b6dd7..3795845586b7cc73be1c605d2f8094d092c3fb51 100644 (file)
@@ -330,6 +330,23 @@ struct rgw_cls_check_index_ret
 };
 WRITE_CLASS_ENCODER(rgw_cls_check_index_ret)
 
+struct rgw_cls_obj_remove_op {
+  list<string> keep_attr_prefixes;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(keep_attr_prefixes, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(keep_attr_prefixes, bl);
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_cls_obj_remove_op)
+
 struct rgw_cls_usage_log_add_op {
   rgw_usage_log_info info;
 
index 5f38f5ff46da82486ea205f570b827600f3b5f91..2ff8074ad181c68c5089f171e23b7ec92afd21bb 100644 (file)
@@ -3873,6 +3873,13 @@ int RGWRados::defer_gc(void *ctx, rgw_obj& obj)
   return gc->defer_chain(tag, false);
 }
 
+void RGWRados::remove_rgw_head_obj(ObjectWriteOperation& op)
+{
+  list<string> prefixes;
+  prefixes.push_back(RGW_ATTR_OLH_PREFIX);
+  cls_rgw_remove_obj(op, prefixes);
+}
+
 
 /**
  * Delete an object.
@@ -3908,7 +3915,7 @@ int RGWRados::delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& ob
     objv_tracker->prepare_op_for_write(&op);
   }
 
-  cls_refcount_put(op, tag, true);
+  remove_rgw_head_obj(op);
   r = ref.ioctx.operate(ref.oid, &op);
   bool removed = (r >= 0);
 
@@ -4224,7 +4231,7 @@ int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj,
 
     if (reset_obj) {
       op.create(false);
-      op.remove(); // we're not dropping reference here, actually removing object
+      remove_rgw_head_obj(op); // we're not dropping reference here, actually removing object
     }
 
     return 0;
@@ -4275,7 +4282,7 @@ int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj,
   if (reset_obj) {
     if (state->exists) {
       op.create(false);
-      op.remove();
+      remove_rgw_head_obj(op);
     } else {
       op.create(true);
     }
index 9a35465550d4af92c332e01ece2a452d5c639105..ef7326dc5da215ec10799836790ab1b779c0f09e 100644 (file)
@@ -1366,6 +1366,7 @@ class RGWRados
   int update_placement_map();
   int store_bucket_info(RGWBucketInfo& info, map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker, bool exclusive);
 
+  void remove_rgw_head_obj(librados::ObjectWriteOperation& op);
 protected:
   virtual int delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& src_obj, bool use_versioning, RGWObjVersionTracker *objv_tracker);