]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: reify root handles
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 26 Oct 2015 21:18:06 +0000 (17:18 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:05:08 +0000 (12:05 -0500)
Reify root handle, remove traces of legacy (counter) handles.

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/include/rados/rgw_file.h
src/rgw/librgw.cc
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/rgw/rgw_lib.h

index c803f2b6849db3047106d05593d877c5e6666cf4..4b7c01f2fad21bd27b32f26293267ceceb0d6d77 100644 (file)
@@ -43,7 +43,6 @@ struct rgw_file_handle
     uint64_t bucket;
     uint64_t object;
   } fh_hk;
-  uint64_t handle; // XXX deprecating
   void *fh_private; /* librgw private data */
   /* object type */
   enum rgw_fh_type fh_type;
@@ -73,16 +72,6 @@ struct rgw_statvfs {
     uint64_t     f_namemax;  /* maximum filename length */
 };
 
-/*
-  get entity handle
-*/
-int rgw_get_handle(const char *uri, struct rgw_file_handle *handle);
-
-/*
-  check handle
-*/
-int rgw_check_handle(const struct rgw_file_handle *handle);
-
 /*
  attach rgw namespace
 */
@@ -99,7 +88,7 @@ int rgw_umount(struct rgw_fs *rgw_fs);
   get filesystem attributes
 */
 int rgw_statfs(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *parent_handle,
+              struct rgw_file_handle *parent_fh,
               struct rgw_statvfs *vfs_st);
 
 
@@ -107,30 +96,30 @@ int rgw_statfs(struct rgw_fs *rgw_fs,
   create file
 */
 int rgw_create(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *parent_handle,
+              struct rgw_file_handle *parent_fh,
               const char *name, mode_t mode, struct stat *st,
-              struct rgw_file_handle *handle);
+              struct rgw_file_handle *fh);
 
 /*
   create a new directory
 */
 int rgw_mkdir(struct rgw_fs *rgw_fs,
-             const struct rgw_file_handle *parent_handle,
+             struct rgw_file_handle *parent_fh,
              const char *name, mode_t mode, struct stat *st,
-             struct rgw_file_handle *handle);
+             struct rgw_file_handle *fh);
 
 /*
   rename object
 */
 int rgw_rename(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *olddir, const char* old_name,
-              const struct rgw_file_handle *newdir, const char* new_name);
+              struct rgw_file_handle *olddir, const char* old_name,
+              struct rgw_file_handle *newdir, const char* new_name);
 
 /*
   remove file or directory
 */
 int rgw_unlink(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *parent_fh, const char* path);
+              struct rgw_file_handle *parent_fh, const char* path);
 
 /*
   lookup a directory or file
@@ -151,7 +140,7 @@ int rgw_fh_rele(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
 typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset);
 
 int rgw_readdir(struct rgw_fs *rgw_fs,
-               const struct rgw_file_handle *parent_fh, uint64_t *offset,
+               struct rgw_file_handle *parent_fh, uint64_t *offset,
                rgw_readdir_cb rcb, void *cb_arg, bool *eof);
 
 /* XXX (get|set)attr mask bits */
@@ -167,20 +156,20 @@ int rgw_readdir(struct rgw_fs *rgw_fs,
    get unix attributes for object
 */
 int rgw_getattr(struct rgw_fs *rgw_fs,
-               struct rgw_file_handle *handle, struct stat *st);
+               struct rgw_file_handle *fh, struct stat *st);
 
 /*
    set unix attributes for object
 */
 int rgw_setattr(struct rgw_fs *rgw_fs,
-               struct rgw_file_handle *handle, struct stat *st,
+               struct rgw_file_handle *fh, struct stat *st,
                uint32_t mask);
 
 /*
    truncate file
 */
 int rgw_truncate(struct rgw_fs *rgw_fs,
-                struct rgw_file_handle *handle, uint64_t size);
+                struct rgw_file_handle *fh, uint64_t size);
 
 /*
    open file
@@ -229,17 +218,19 @@ int rgw_writev(struct rgw_fs *rgw_fs,
 */
 int rgw_fsync(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh);
 
+/* XXXX not implemented (needed?) */
+
 int set_user_permissions(const char *uid);
 
 int get_user_permissions(const char *uid);
 
-int set_dir_permissions(const struct rgw_file_handle *handle);
+int set_dir_permissions(const struct rgw_file_handle *fh);
 
-int get_dir_permissions(const struct rgw_file_handle *handle);
+int get_dir_permissions(const struct rgw_file_handle *fh);
 
-int set_file_permissions(const struct rgw_file_handle *handle);
+int set_file_permissions(const struct rgw_file_handle *fh);
 
-int get_file_permissions(const struct rgw_file_handle *handle);
+int get_file_permissions(const struct rgw_file_handle *fh);
 
 int rgw_acl2perm();
 
index dc2f5dffc22ee3ed88ab72dcf5c9ef1caa049f83..45259f4ca0a95ba746d0326471053a646a61ff13 100644 (file)
@@ -390,37 +390,6 @@ int RGWLib::stop()
   return 0;
 } /* RGWLib::stop() */
 
-int RGWLib::get_uri(const uint64_t handle, string& uri)
-{
-  ceph::unordered_map<uint64_t, string>::iterator i = handles_map.find(handle);
-  if (i != handles_map.end()) {
-    uri =  i->second;
-    return 0;
-  }
-  return -1;
-}
-
-uint64_t RGWLib::get_handle(const string& uri)
-{
-  ceph::unordered_map<string, uint64_t>::iterator i =
-    allocated_objects_handles.find(uri);
-  if (i != allocated_objects_handles.end()) {
-    return i->second;
-  }
-
-  allocated_objects_handles[uri] = last_allocated_handle.inc();
-  handles_map[last_allocated_handle.read()] = uri;
-
-  return last_allocated_handle.read();
-}
-
-int RGWLib::check_handle(uint64_t handle)
-{
-  ceph::unordered_map<uint64_t, string>::const_iterator i =
-    handles_map.find(handle);
-  return (i != handles_map.end());
-}
-
 int RGWLibIO::set_uid(RGWRados *store, const rgw_user& uid)
 {
   int ret = rgw_get_user_info_by_uid(store, uid, user_info, NULL);
index 08067ca8e835da0956e848f24046758460f495b3..a2e5083a9baf88de387d14e6ca8af57cc620d936 100644 (file)
 
 extern RGWLib librgw;
 
-bool is_root(const string& uri)
-{
-  return (uri == "");
-}
-
-bool is_bucket(const string& uri)
-{
-  /* XXX */
-  int pos = uri.find('/');
-  return (pos < 0);
-}
-
 const string RGWFileHandle::root_name = "/";
 
-/*
-  get generate rgw_file_handle
-*/
-int rgw_get_handle(const char* uri, struct rgw_file_handle* handle)
-{
-  handle->handle = librgw.get_handle(uri);
-  return 0;
-}
-
-/*
-  check rgw_file_handle
-*/
-int rgw_check_handle(const struct rgw_file_handle* handle)
-{
-  return librgw.check_handle(handle->handle);
-}
-
 /* librgw */
 extern "C" {
 
@@ -81,12 +52,8 @@ extern "C" {
   struct rgw_fs *fs = new_fs->get_fs();;
   fs->rgw = rgw;
 
-  /* stash the root */
-  rc = rgw_get_handle("", &fs->root_fh);
-  if (rc != 0) {
-    delete new_fs;
-    return -EINVAL;
-  }
+  /* XXX we no longer assume "/" is unique, but we aren't tracking the
+   * roots atm */
 
   *rgw_fs = fs;
 
@@ -107,7 +74,7 @@ int rgw_umount(struct rgw_fs *rgw_fs)
   get filesystem attributes
 */
 int rgw_statfs(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *parent_handle,
+              struct rgw_file_handle *parent_fh,
               struct rgw_statvfs *vfs_st)
 {
   memset(vfs_st, 0, sizeof(struct rgw_statvfs));
@@ -118,51 +85,41 @@ int rgw_statfs(struct rgw_fs *rgw_fs,
   generic create
 */
 int rgw_create(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *parent_handle,
+              struct rgw_file_handle *parent_fh,
               const char *name, mode_t mode, struct stat *st,
               struct rgw_file_handle *handle)
 {
-  string uri;
-  int rc;
-
-  rc = librgw.get_uri(parent_handle->handle, uri);
-  if (rc < 0 ) { /* invalid parent */
-    return rc;
-  }
-
-  uri += "\\";
-  uri += name;
-
-  /* TODO: implement */
-
-  return rgw_get_handle(uri.c_str(), handle);
+  return 0;
 }
 
 /*
   create a new directory
 */
 int rgw_mkdir(struct rgw_fs *rgw_fs,
-             const struct rgw_file_handle *parent_handle,
+             struct rgw_file_handle *parent_fh,
              const char *name, mode_t mode, struct stat *st,
              struct rgw_file_handle *handle)
 {
   int rc;
-  string uri;
 
-  rc = librgw.get_uri(parent_handle->handle, uri);
-  if (rc < 0 ) { /* invalid parent */
-    return rc;
-  }
+  /* XXXX remove uri, deal with bucket names */
+  string uri;
 
   RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
   CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
 
-  /* cannot create a bucket in a bucket */
-  if (! is_root(uri)) {
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if (! parent) {
+    /* bad parent */
     return EINVAL;
   }
 
-  // fix this
+  if (! parent->is_root()) {
+    /* cannot create a bucket in a bucket */
+    return ENOTDIR;
+  }
+
+  // XXXX fix this
   uri += "/";
   uri += name;
   RGWCreateBucketRequest req(cct, fs->get_user(), uri);
@@ -175,8 +132,8 @@ int rgw_mkdir(struct rgw_fs *rgw_fs,
   rename object
 */
 int rgw_rename(struct rgw_fs *rgw_fs,
-              const struct rgw_file_handle *olddir, const char* old_name,
-              const struct rgw_file_handle *newdir, const char* new_name)
+              struct rgw_file_handle *olddir, const char* old_name,
+              struct rgw_file_handle *newdir, const char* new_name)
 {
   /* -ENOTSUP */
   return -EINVAL;
@@ -185,9 +142,10 @@ int rgw_rename(struct rgw_fs *rgw_fs,
 /*
   remove file or directory
 */
-int rgw_unlink(struct rgw_fs *rgw_fs, const struct rgw_file_handle* parent,
+int rgw_unlink(struct rgw_fs *rgw_fs, struct rgw_file_handle* parent,
              const char* path)
 {
+  /* XXXX remove uri and deal with bucket and object names */
   string uri;
   int rc = 0;
 
@@ -204,11 +162,6 @@ int rgw_unlink(struct rgw_fs *rgw_fs, const struct rgw_file_handle* parent,
     /*
      * object
      */
-      rc = librgw.get_uri(parent->handle, uri);
-      if (rc < 0 ) { /* invalid parent */
-       return rc;
-      }
-      uri += path;
       /* TODO: implement
        * RGWDeleteObjectRequest req(cct, fs->get_user(), uri);
       */
@@ -224,33 +177,21 @@ int rgw_lookup(struct rgw_fs *rgw_fs,
              struct rgw_file_handle *parent_fh, const char* path,
              struct rgw_file_handle **fh, uint32_t flags)
 {
-  string uri;
-  int rc;
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
 
-  rc = librgw.get_uri(parent_fh->handle, uri);
-  if (rc < 0 ) { /* invalid parent */
-    return rc;
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if (! parent) {
+    /* bad parent */
+    return EINVAL;
   }
 
-  #warning get_bucket and ?get_object? unimplemented
-  /* TODO: implement */
-  if (is_root(uri)) {
-    //librgw.get_bucket(uri);
-  } else if (0 /* is_bucket(uri) */) {
-    /* get the object */
-  } else { /* parent cannot be an object */
-    return -1;
+  RGWFileHandle* rgw_fh = new RGWFileHandle(fs, parent, path);
+  if (! rgw_fh) {
+    /* not found */
+    return ENOENT;
   }
 
-  uri += "/";
-  uri += path;
-
-  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 */
-  rfh->handle = librgw.get_handle(uri);
   *fh = rfh;
 
   return 0;
@@ -274,14 +215,6 @@ int rgw_fh_rele(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
 int rgw_getattr(struct rgw_fs *rgw_fs,
                struct rgw_file_handle *fh, struct stat *st)
 {
-  string uri;
-  int rc;
-
-  rc = librgw.get_uri(fh->handle, uri);
-  if (rc < 0 ) { /* invalid parent */
-    return rc;
-  }
-
   return 0;
 }
 
@@ -333,16 +266,13 @@ int rgw_close(struct rgw_fs *rgw_fs,
 }
 
 int rgw_readdir(struct rgw_fs *rgw_fs,
-               const struct rgw_file_handle *parent_fh, uint64_t *offset,
+               struct rgw_file_handle *parent_fh, uint64_t *offset,
                rgw_readdir_cb rcb, void *cb_arg, bool *eof)
 {
   int rc;
-  string uri;
 
-  rc = librgw.get_uri(parent_fh->handle, uri);
-  if (rc < 0 ) { /* invalid parent */
-    return rc;
-  }
+  /* XXXX remove uri, deal with bucket and object names */
+  string uri;
 
   RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
   CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
@@ -352,8 +282,13 @@ int rgw_readdir(struct rgw_fs *rgw_fs,
    * deal with authorization
    * consider non-default tenancy/user and bucket layouts
    */
-  if (is_root(uri)) {
-    /* for now, root always contains one user's bucket namespace */
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if (! parent) {
+    /* bad parent */
+    return EINVAL;
+  }
+
+  if (parent->is_root()) {
     RGWListBucketsRequest req(cct, fs->get_user(), rcb, cb_arg, offset);
     rc = librgw.get_fe()->execute_req(&req);
   } else {
index 2ab69d223b473ac02f3ba44406ebe8383176a588..54d535053e96b9b4aa83c956564319198c172946 100644 (file)
@@ -13,7 +13,9 @@
 #include "xxhash.h"
 #include "include/buffer.h"
 
+class RGWLibFS;
 class RGWFileHandle;
+
 typedef boost::intrusive_ptr<RGWFileHandle> RGWFHRef;
 
 class RGWFileHandle
@@ -21,22 +23,33 @@ 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:
+  const static string root_name;
+
   static constexpr uint32_t FLAG_NONE = 0x0000;
   static constexpr uint32_t FLAG_OPEN = 0x0001;
   static constexpr uint32_t FLAG_ROOT = 0x0002;
   
-  RGWFileHandle(RGWFileHandle* _parent, const char* _name)
+  RGWFileHandle(RGWLibFS* fs, 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;
+    if (parent) {
+      fh.fh_type = parent->is_root() ?
+       RGW_FS_TYPE_DIRECTORY : RGW_FS_TYPE_FILE;
+      /* content-addressable hash (bucket part) */
+      fh.fh_hk.bucket = parent->get_fh()->fh_hk.object;
+    } else {
+      /* root */
+      fh.fh_type = RGW_FS_TYPE_DIRECTORY;
+      /* XXX give root buckets a locally-unique bucket hash part */
+      fh.fh_hk.bucket = XXH64(reinterpret_cast<char*>(fs), 8, 8675309);
+      flags |= FLAG_ROOT;
+    }
+    /* content-addressable hash (object part) */
     fh.fh_hk.object = XXH64(name.c_str(), name.length(), 8675309 /* XXX */);
+    fh.fh_private = this;
   }
 
   struct rgw_file_handle* get_fh() { return &fh; }
@@ -52,10 +65,10 @@ public:
 
   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); }
+  bool is_open() const { return flags & FLAG_OPEN; }
+  bool is_root() const { return flags & FLAG_ROOT; }
+  bool is_bucket() const { return (fh.fh_type == RGW_FS_TYPE_DIRECTORY); }
+  bool is_object() const { return (fh.fh_type == RGW_FS_TYPE_FILE); }
 
   void open() {
     flags |= FLAG_OPEN;
@@ -72,7 +85,9 @@ public:
   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;
+      /* root handles are expanded in RGWLibFS */
+      if (! const_cast<RGWFileHandle*>(fh)->is_root())
+       delete fh;
     }
   }
 
@@ -88,6 +103,7 @@ static inline RGWFileHandle* get_rgwfh(struct rgw_file_handle* fh) {
 class RGWLibFS
 {
   struct rgw_fs fs;
+  RGWFileHandle root_fh;
 
   std::string uid; // should match user.user_id, iiuc
 
@@ -96,7 +112,8 @@ class RGWLibFS
 
 public:
   RGWLibFS(const char *_uid, const char *_user_id, const char* _key)
-    : uid(_uid), key(_user_id, _key) {
+    : root_fh(this, nullptr, RGWFileHandle::root_name.c_str()), uid(_uid),
+      key(_user_id, _key) {
     fs.fs_private = this;
   }
 
index 6bec854efd8f68fa7995d8130e8698048b848d86..546d3b395cb691f48a2505fd501831e758fbfedf 100644 (file)
@@ -24,9 +24,7 @@ class RGWLib {
   RGWREST rest; // XXX needed for RGWProcessEnv
   RGWProcessEnv env;
   RGWRados* store;
-  ceph::unordered_map<string, uint64_t> allocated_objects_handles;
-  ceph::unordered_map<uint64_t, string> handles_map;
-  atomic64_t last_allocated_handle;
+
 public:
   RGWLib() {}
   ~RGWLib() {}
@@ -38,15 +36,6 @@ public:
   int init();
   int init(vector<const char *>& args);
   int stop();
-
-  /* generate dynamic handle currently unique per librgw object */
-  uint64_t get_handle(const string& url);
-
-  /* look for a matching handle (by number) */
-  int check_handle(uint64_t handle);
-
-  /* return the saved uri corresponding to handle */
-  int get_uri(const uint64_t handle, string &uri);
 };
 
 /* request interface */