]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: incremental RGWPutObj work and almost-complete RGWFH refactor.
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 26 Oct 2015 20:36:56 +0000 (16:36 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:05:07 +0000 (12:05 -0500)
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/include/rados/rgw_file.h
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/rgw/rgw_os_lib.cc
src/rgw/rgw_os_lib.h

index b8c7883153884b8b6b1ef755e1d4f34ccfd93073..c803f2b6849db3047106d05593d877c5e6666cf4 100644 (file)
@@ -38,13 +38,13 @@ enum rgw_fh_type {
  */
 struct rgw_file_handle
 {
+  /* content-addressable hash */
+  struct {
+    uint64_t bucket;
+    uint64_t object;
+  } fh_hk;
   uint64_t handle; // XXX deprecating
   void *fh_private; /* librgw private data */
-  /* opaque content-addressable name */
-  struct {
-    void *data;
-    uint16_t len;
-  } fh_name;
   /* object type */
   enum rgw_fh_type fh_type;
 };
@@ -136,7 +136,7 @@ int rgw_unlink(struct rgw_fs *rgw_fs,
   lookup a directory or file
 */
 int rgw_lookup(struct rgw_fs *rgw_fs,
-             const struct rgw_file_handle *parent_fh, const char *path,
+             struct rgw_file_handle *parent_fh, const char *path,
              struct rgw_file_handle **fh, uint32_t flags);
 
 /*
index 75fb342f14579077745470882cc31fbfe3f42c44..08067ca8e835da0956e848f24046758460f495b3 100644 (file)
@@ -38,6 +38,8 @@ bool is_bucket(const string& uri)
   return (pos < 0);
 }
 
+const string RGWFileHandle::root_name = "/";
+
 /*
   get generate rgw_file_handle
 */
@@ -219,7 +221,7 @@ int rgw_unlink(struct rgw_fs *rgw_fs, const struct rgw_file_handle* parent,
   lookup a directory or file
 */
 int rgw_lookup(struct rgw_fs *rgw_fs,
-             const struct rgw_file_handle *parent_fh, const char* path,
+             struct rgw_file_handle *parent_fh, const char* path,
              struct rgw_file_handle **fh, uint32_t flags)
 {
   string uri;
@@ -243,7 +245,8 @@ int rgw_lookup(struct rgw_fs *rgw_fs,
   uri += "/";
   uri += path;
 
-  RGWFileHandle* rgw_fh = new RGWFileHandle();
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  RGWFileHandle* rgw_fh = new RGWFileHandle(parent, path);
   struct rgw_file_handle *rfh = rgw_fh->get_fh();
 
   /* find or create a handle for the object or bucket */
@@ -386,9 +389,24 @@ int rgw_write(struct rgw_fs *rgw_fs,
              struct rgw_file_handle *fh, uint64_t offset,
              size_t length, void *buffer)
 {
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
   RGWFileHandle* rgw_fh = get_rgwfh(fh);
 
-  return 0;
+  if (! rgw_fh->is_object())
+    return EINVAL;
+
+  /* XXXX testing only */
+  buffer::list bl;
+  bl.push_back(
+    buffer::create_static(length /* XXX size */, static_cast<char*>(buffer)));
+
+  /* XXX */
+  RGWPutObjRequest req(cct, fs->get_user(), rgw_fh->bucket_name(),
+                     rgw_fh->object_name(), bl);
+  int rc = librgw.get_fe()->execute_req(&req);
+
+  return rc;
 }
 
 /*
index 609a6697c8f34a9ccb172c5680bb13dcf4e61a96..2ab69d223b473ac02f3ba44406ebe8383176a588 100644 (file)
@@ -8,31 +8,77 @@
 
 /* internal header */
 
+#include <atomic>
+#include <boost/intrusive_ptr.hpp>
+#include "xxhash.h"
+#include "include/buffer.h"
+
+class RGWFileHandle;
+typedef boost::intrusive_ptr<RGWFileHandle> RGWFHRef;
+
 class RGWFileHandle
 {
   struct rgw_file_handle fh;
+  mutable std::atomic<uint64_t> refcnt;
+  RGWFHRef parent;
+  const static string root_name;
+  string name; /* XXX file or bucket name */
   uint32_t flags;
+
 public:
-  static constexpr uint32_t FLAG_NONE = 0;
-  static constexpr uint32_t FLAG_OPEN = 1;
+  static constexpr uint32_t FLAG_NONE = 0x0000;
+  static constexpr uint32_t FLAG_OPEN = 0x0001;
+  static constexpr uint32_t FLAG_ROOT = 0x0002;
   
-  RGWFileHandle() {
+  RGWFileHandle(RGWFileHandle* _parent, const char* _name)
+    : parent(_parent), name(_name), flags(FLAG_NONE) {
+    fh.fh_type = parent->is_root() ? RGW_FS_TYPE_DIRECTORY : RGW_FS_TYPE_FILE;
     fh.fh_private = this;
+    /* content-addressable hash */
+    fh.fh_hk.bucket = (parent) ? parent->get_fh()->fh_hk.object : 0;
+    fh.fh_hk.object = XXH64(name.c_str(), name.length(), 8675309 /* XXX */);
   }
 
+  struct rgw_file_handle* get_fh() { return &fh; }
+
+  const std::string& bucket_name() {
+    if (is_root())
+      return root_name;
+    if (is_object()) {
+      return parent->object_name();
+    }
+    return name;
+  }
+
+  const std::string& object_name() { return name; }
+
   bool is_open() { return flags & FLAG_OPEN; }
+  bool is_root() { return flags & FLAG_ROOT; }
+  bool is_bucket() { return (fh.fh_type == RGW_FS_TYPE_DIRECTORY); }
+  bool is_object() { return (fh.fh_type == RGW_FS_TYPE_FILE); }
 
-  void open() { flags |= FLAG_OPEN; }
+  void open() {
+    flags |= FLAG_OPEN;
+  }
 
-  void close() { flags &= ~FLAG_OPEN; }
+  void close() {
+    flags &= ~FLAG_OPEN;
+  }
 
-  void rele() {
-    /* XXX intrusive refcnt */
-    assert(! is_open());
-    delete this;
+  friend void intrusive_ptr_add_ref(const RGWFileHandle* fh) {
+    fh->refcnt.fetch_add(1, std::memory_order_relaxed);
   }
 
-  struct rgw_file_handle* get_fh() { return &fh; }
+  friend void intrusive_ptr_release(const RGWFileHandle* fh) {
+    if (fh->refcnt.fetch_sub(1, std::memory_order_release) == 1) {
+      std::atomic_thread_fence(std::memory_order_acquire);
+      delete fh;
+    }
+  }
+
+  inline void rele() {
+    intrusive_ptr_release(this);
+  }
 }; /* RGWFileHandle */
 
 static inline RGWFileHandle* get_rgwfh(struct rgw_file_handle* fh) {
@@ -312,12 +358,12 @@ class RGWPutObjRequest : public RGWLibRequest,
                         public RGWPutObj_OS_Lib /* RGWOp */
 {
 public:
-  std::string& bucket_name;
-  std::string& obj_name;
+  const std::string& bucket_name;
+  const std::string& obj_name;
   buffer::list& bl; /* XXX */
 
   RGWPutObjRequest(CephContext* _cct, RGWUserInfo *_user,
-                 std::string& _bname, std::string& _oname,
+                 const std::string& _bname, const std::string& _oname,
                  buffer::list& _bl)
     : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname),
       bl(_bl) {
@@ -357,7 +403,21 @@ public:
 
     return 0;
   }
-}; /* RGWPubObjRequest */
 
+  virtual int get_data(buffer::list& _bl) {
+    /* XXX for now, use sharing semantics */
+    _bl = bl;
+    return _bl.length();
+  }
+
+  virtual void send_response() {}
+
+  virtual int verify_params() {
+    if (bl.length() > cct->_conf->rgw_max_put_size)
+      return -ERR_TOO_LARGE;
+    return 0;
+  }
+
+}; /* RGWPubObjRequest */
 
 #endif /* RGW_FILE_H */
index 6431919fe45a5d0ad8a7d179beb09b84a0847022..6e6453a04de36138f7a51e59550892025e2903f1 100644 (file)
@@ -136,3 +136,13 @@ void RGWCreateBucket_OS_Lib::send_response()
 {
   /* TODO: something (maybe) */
 }
+
+int RGWPutObj_OS_Lib::get_params()
+{
+  RGWAccessControlPolicy_S3 s3policy(s->cct);
+
+  /* we don't have (any) headers, so just create canned ACLs */
+  int ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
+  policy = s3policy;
+  return ret;
+}
index a21e3858d9f272846a6947eaa42d7c9fa94224cf..f5a329af615ef1774b7288fc0e788eff087a68c1 100644 (file)
@@ -71,7 +71,6 @@ public:
   RGWPutObj_OS_Lib() {}
   ~RGWPutObj_OS_Lib() {}
 
-  virtual int verify_params();
   virtual int get_params();
 
 }; /* RGWPutObj_OS_Lib */