From: Matt Benjamin Date: Mon, 26 Oct 2015 20:36:56 +0000 (-0400) Subject: librgw: incremental RGWPutObj work and almost-complete RGWFH refactor. X-Git-Tag: v10.1.0~382^2~195 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1e7539bed85f223c758ddb10d37d4b24b77fcb7a;p=ceph.git librgw: incremental RGWPutObj work and almost-complete RGWFH refactor. Signed-off-by: Matt Benjamin --- diff --git a/src/include/rados/rgw_file.h b/src/include/rados/rgw_file.h index b8c788315388..c803f2b6849d 100644 --- a/src/include/rados/rgw_file.h +++ b/src/include/rados/rgw_file.h @@ -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); /* diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 75fb342f1457..08067ca8e835 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -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(rgw_fs->rgw); + RGWLibFS *fs = static_cast(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(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; } /* diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 609a6697c8f3..2ab69d223b47 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -8,31 +8,77 @@ /* internal header */ +#include +#include +#include "xxhash.h" +#include "include/buffer.h" + +class RGWFileHandle; +typedef boost::intrusive_ptr RGWFHRef; + 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: - 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 */ diff --git a/src/rgw/rgw_os_lib.cc b/src/rgw/rgw_os_lib.cc index 6431919fe45a..6e6453a04de3 100644 --- a/src/rgw/rgw_os_lib.cc +++ b/src/rgw/rgw_os_lib.cc @@ -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; +} diff --git a/src/rgw/rgw_os_lib.h b/src/rgw/rgw_os_lib.h index a21e3858d9f2..f5a329af615e 100644 --- a/src/rgw/rgw_os_lib.h +++ b/src/rgw/rgw_os_lib.h @@ -71,7 +71,6 @@ public: RGWPutObj_OS_Lib() {} ~RGWPutObj_OS_Lib() {} - virtual int verify_params(); virtual int get_params(); }; /* RGWPutObj_OS_Lib */