From b2fbbf0f7e59a2da89476b771cbd935360f13e91 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 20 Sep 2011 21:34:42 -0700 Subject: [PATCH] rgw: implement rgw_rados helpers for class calls --- src/cls_rgw.cc | 6 +-- src/rgw/rgw_cls_api.h | 3 -- src/rgw/rgw_rados.cc | 88 +++++++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_rados.h | 6 +++ 4 files changed, 97 insertions(+), 6 deletions(-) diff --git a/src/cls_rgw.cc b/src/cls_rgw.cc index 7d1b91666bb88..a59633973a954 100644 --- a/src/cls_rgw.cc +++ b/src/cls_rgw.cc @@ -96,7 +96,7 @@ int rgw_bucket_modify(cls_method_context_t hctx, bufferlist *in, bufferlist *out CLS_LOG("ERROR: rgw_bucket_modify(): failed to decode request\n"); return -EINVAL; } - CLS_LOG("rgw_bucket_modify(): request: op=%d name=%s epoch=%lld\n", op.op, op.entry.name.c_str(), op.epoch); + CLS_LOG("rgw_bucket_modify(): request: op=%d name=%s epoch=%lld\n", op.op, op.entry.name.c_str(), op.entry.epoch); std::map::iterator miter = dir.m.find(op.entry.name); @@ -131,8 +131,8 @@ void __cls_init() CLS_LOG("Loaded rgw class!"); cls_register("rgw", &h_class); - cls_register_cxx_method(h_class, "rgw_bucket_list", CLS_METHOD_RD | CLS_METHOD_PUBLIC, rgw_bucket_list, &h_rgw_bucket_list); - cls_register_cxx_method(h_class, "rgw_bucket_modify", CLS_METHOD_RD | CLS_METHOD_WR | CLS_METHOD_PUBLIC, rgw_bucket_modify, &h_rgw_bucket_modify); + cls_register_cxx_method(h_class, "bucket_list", CLS_METHOD_RD | CLS_METHOD_PUBLIC, rgw_bucket_list, &h_rgw_bucket_list); + cls_register_cxx_method(h_class, "bucket_modify", CLS_METHOD_RD | CLS_METHOD_WR | CLS_METHOD_PUBLIC, rgw_bucket_modify, &h_rgw_bucket_modify); return; } diff --git a/src/rgw/rgw_cls_api.h b/src/rgw/rgw_cls_api.h index 1db96e546b07e..5ca4bc7a1b222 100644 --- a/src/rgw/rgw_cls_api.h +++ b/src/rgw/rgw_cls_api.h @@ -75,21 +75,18 @@ enum modify_op { struct rgw_cls_obj_op { uint8_t op; - uint64_t epoch; struct rgw_bucket_dir_entry entry; void encode(bufferlist &bl) const { __u8 struct_v = 1; ::encode(struct_v, bl); ::encode(op, bl); - ::encode(epoch, bl); ::encode(entry, bl); } void decode(bufferlist::iterator &bl) { __u8 struct_v; ::decode(struct_v, bl); ::decode(op, bl); - ::decode(epoch, bl); ::decode(entry, bl); } }; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index d7c81a5a9ffc5..c18e88ec065aa 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -6,6 +6,8 @@ #include "rgw_rados.h" #include "rgw_acl.h" +#include "rgw_cls_api.h" + #include "include/rados/librados.hpp" using namespace librados; @@ -1760,3 +1762,89 @@ int RGWRados::distribute(bufferlist& bl) int r = control_pool_ctx.notify(notify_oid, 0, bl); return r; } + +int RGWRados::cls_obj_op(rgw_bucket& bucket, uint8_t op, uint64_t epoch, + string& name, uint64_t size, utime_t& mtime) +{ + librados::IoCtx io_ctx; + int r = open_bucket_ctx(bucket, io_ctx); + if (r < 0) + return r; + + if (bucket.marker.empty()) { + RGW_LOG(0) << "ERROR: empty marker for cls_rgw bucket operation" << dendl; + return -EIO; + } + + string oid = ".dir."; + oid.append(bucket.marker); + + bufferlist in, out; + struct rgw_cls_obj_op call; + call.op = op; + call.entry.name = name; + call.entry.size = size; + call.entry.mtime = mtime; + call.entry.epoch = epoch; + ::encode(call, in); + r = io_ctx.exec(oid, "rgw", "bucket_modify", in, out); + return r; +} + +int RGWRados::cls_obj_add(rgw_bucket& bucket, uint64_t epoch, string& name, uint64_t size, utime_t& mtime) +{ + return cls_obj_op(bucket, CLS_RGW_OP_ADD, epoch, name, size, mtime); +} + +int RGWRados::cls_obj_del(rgw_bucket& bucket, uint64_t epoch, string& name) +{ + utime_t mtime; + return cls_obj_op(bucket, CLS_RGW_OP_DEL, epoch, name, 0, mtime); +} + +int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, map& m) +{ + librados::IoCtx io_ctx; + int r = open_bucket_ctx(bucket, io_ctx); + if (r < 0) + return r; + + if (bucket.marker.empty()) { + RGW_LOG(0) << "ERROR: empty marker for cls_rgw bucket operation" << dendl; + return -EIO; + } + + string oid = ".dir."; + oid.append(bucket.marker); + + bufferlist in, out; + struct rgw_cls_list_op call; + call.start_obj = start; + call.num_entries = num; + ::encode(call, in); + r = io_ctx.exec(oid, "rgw", "bucket_list", in, out); + if (r < 0) + return r; + + struct rgw_cls_list_ret ret; + try { + bufferlist::iterator iter = out.begin(); + ::decode(ret, iter); + } catch (buffer::error& err) { + RGW_LOG(0) << "ERROR: failed to decode bucket_list returned buffer" << dendl; + return -EIO; + } + + struct rgw_bucket_dir& dir = ret.dir; + map::iterator miter; + for (miter = dir.m.begin(); miter != dir.m.end(); ++miter) { + RGWObjEnt e; + rgw_bucket_dir_entry& dirent = miter->second; + e.name = dirent.name; + e.size = dirent.size; + e.mtime = dirent.mtime; + m[e.name] = e; + } + + return m.size(); +} diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 3c22f6bf2800f..95393097e023d 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -276,6 +276,12 @@ public: } int get_bucket_stats(rgw_bucket& bucket, map& stats); + + int cls_obj_op(rgw_bucket& bucket, uint8_t op, uint64_t epoch, + string& name, uint64_t size, utime_t& mtime); + int cls_obj_add(rgw_bucket& bucket, uint64_t epoch, string& name, uint64_t size, utime_t& mtime); + int cls_obj_del(rgw_bucket& bucket, uint64_t epoch, string& name); + int cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, map& m); }; #endif -- 2.39.5