]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: class for bucket directory
authorYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Tue, 20 Sep 2011 05:44:35 +0000 (22:44 -0700)
committerYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Tue, 20 Sep 2011 05:44:35 +0000 (22:44 -0700)
doesn't compile yet

src/cls_rgw.cc [new file with mode: 0644]

diff --git a/src/cls_rgw.cc b/src/cls_rgw.cc
new file mode 100644 (file)
index 0000000..f89b702
--- /dev/null
@@ -0,0 +1,166 @@
+
+
+
+#include <iostream>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "include/types.h"
+#include "objclass/objclass.h"
+
+CLS_VER(1,0)
+CLS_NAME(rgw)
+
+cls_handle_t h_class;
+cls_method_handle_t h_rgw_bucket_list;
+cls_method_handle_t h_rgw_bucket_add;
+cls_method_handle_t h_rgw_bucket_del;
+cls_method_handle_t h_rgw_bucket_info;
+
+struct rgw_bucket_dir_entry {
+  uint64_t epoch;
+  string name;
+  uint64_t size;
+  utime_t mtime;
+};
+
+struct rgw_bucket_dir_header {
+  uint64_t total_size;
+  uint64_t num_entries;
+};
+
+struct rgw_bucket_dir {
+  struct rgw_bucket_dir_header header;
+  map<string, struct rgw_bucket_dir_entry> m;
+};
+
+enum modify_op {
+  CLS_RGW_OP_ADD = 0,
+  CLS_RGW_OP_DEL = 1,
+};
+
+static int read_bucket_dir(cls_method_context_t hctx, struct rgw_bucket_dir& dir)
+{
+  bufferlist bl;
+  bufferlist::iterator iter;
+
+  rc = cls_cxx_read(hctx, 0, (uint64_t)-1, &bl);
+  if (rc < 0)
+    return rc;
+
+  try {
+    bufferlist::iterator iter = bl.begin();
+    ::decode(dir, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG("ERROR: rgw_bucket_list(): failed to decode buffer\n");
+    return -EIO;
+  }
+
+  return 0;
+}
+
+static int write_bucket_dir(cls_method_context_t hctx, struct rgw_bucket_dir& dir)
+{
+  bufferlist bl;
+
+  ::encode(dir, bl);
+
+  int rc = cls_cxx_write_full(hctx, &bl);
+  return rc;
+}
+
+int rgw_bucket_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  bufferlist bl;
+  struct rbd_bucket_dir dir;
+  int rc = read_bucket_dir(hctx, header);
+  if (rc < 0)
+    return rc;
+
+  bufferlist::iterator iter = in->begin();
+  string start_obj;
+  uint32_t num_entries;
+
+  try {
+    ::decode(start_obj, iter);
+    ::decode(num_entries, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG("ERROR: rgw_bucket_list(): failed to decode request\n");
+    return -EINVAL;
+  }
+
+  struct rbd_bucket_dir new_dir;
+  new_dir.header = dir.header;
+  map<string, struct rgw_bucket_dir_entry>& m = new_dir.m;
+  map<string, struct rgw_bucket_dir_entry>::iterator miter;
+  uint32_t i;
+  for (i = 0, miter = dir.m.begin(); i !=num_entries && miter != dir.m.end(); ++i, ++miter) {
+    m.insert(miter);
+  }
+  ::encode(new_dir, *out);
+
+  return 0;
+}
+
+int rgw_bucket_modify(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  bufferlist bl;
+  struct rbd_bucket_dir dir;
+  int rc = read_bucket_dir(hctx, dir);
+  if (rc < 0)
+    return rc;
+
+  uint8_t op;
+  uint64_t epoch;
+  struct rbd_bucket_dir_entry entry;
+
+  bufferlist::iterator iter = in->begin();
+  try {
+    ::decode(op, iter);
+    ::decode(epoch, iter);
+    ::decode(entry, iter);
+  } catch (buffer::error& err) {
+    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, entry.name.c_str(), epoch);
+
+  map<string, struct rgw_bucket_dir_entry>::iterator miter = dir.m.find(entry.name);
+
+  if (miter != dir.m.end()) {
+    CLS_LOG("rgw_bucket_modify(): existing entry: epoch=%lld\n", entry.epoch);
+    if (entry.epoch >= epoch) {
+      CLS_LOG("rgw_bucket_modify(): skipping request, old epoch\n");
+      return 0;
+    }
+  }
+
+  switch (op) {
+  case RGW_OP_DEL:
+    if (miter != dir.m.end())
+      dir.erase(miter);
+    else
+      return -ENOENT;
+    break;
+  case RGW_OP_ADD:
+    dir[entry.name] = entry;
+    break;
+  }
+
+  rc = write_bucket_dir(hctx, dir);
+
+  return rc;
+}
+
+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, snapshots_list, &h_snapshots_list);
+  cls_register_cxx_method(h_class, "rgw_bucket_modify", CLS_METHOD_RD | CLS_METHOD_WR | CLS_METHOD_PUBLIC, snapshot_add, &h_snapshot_add);
+
+  return;
+}
+