From e562357bba913ce07dadaec21a4c177f7633eb00 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Mon, 26 Oct 2015 17:18:06 -0400 Subject: [PATCH] librgw: reify root handles Reify root handle, remove traces of legacy (counter) handles. Signed-off-by: Matt Benjamin --- src/include/rados/rgw_file.h | 45 +++++------ src/rgw/librgw.cc | 31 -------- src/rgw/rgw_file.cc | 145 ++++++++++------------------------- src/rgw/rgw_file.h | 41 +++++++--- src/rgw/rgw_lib.h | 13 +--- 5 files changed, 88 insertions(+), 187 deletions(-) diff --git a/src/include/rados/rgw_file.h b/src/include/rados/rgw_file.h index c803f2b6849db..4b7c01f2fad21 100644 --- a/src/include/rados/rgw_file.h +++ b/src/include/rados/rgw_file.h @@ -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(); diff --git a/src/rgw/librgw.cc b/src/rgw/librgw.cc index dc2f5dffc22ee..45259f4ca0a95 100644 --- a/src/rgw/librgw.cc +++ b/src/rgw/librgw.cc @@ -390,37 +390,6 @@ int RGWLib::stop() return 0; } /* RGWLib::stop() */ -int RGWLib::get_uri(const uint64_t handle, string& uri) -{ - ceph::unordered_map::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::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::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); diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 08067ca8e835d..a2e5083a9baf8 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -26,37 +26,8 @@ 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(rgw_fs->fs_private); CephContext* cct = static_cast(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(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(rgw_fs->fs_private); CephContext* cct = static_cast(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 { diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 2ab69d223b473..54d535053e96b 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -13,7 +13,9 @@ #include "xxhash.h" #include "include/buffer.h" +class RGWLibFS; class RGWFileHandle; + typedef boost::intrusive_ptr RGWFHRef; class RGWFileHandle @@ -21,22 +23,33 @@ class RGWFileHandle struct rgw_file_handle fh; mutable std::atomic 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(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(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; } diff --git a/src/rgw/rgw_lib.h b/src/rgw/rgw_lib.h index 6bec854efd8f6..546d3b395cb69 100644 --- a/src/rgw/rgw_lib.h +++ b/src/rgw/rgw_lib.h @@ -24,9 +24,7 @@ class RGWLib { RGWREST rest; // XXX needed for RGWProcessEnv RGWProcessEnv env; RGWRados* store; - ceph::unordered_map allocated_objects_handles; - ceph::unordered_map handles_map; - atomic64_t last_allocated_handle; + public: RGWLib() {} ~RGWLib() {} @@ -38,15 +36,6 @@ public: int init(); int init(vector& 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 */ -- 2.39.5