From: Yehuda Sadeh Date: Tue, 2 Aug 2011 23:29:16 +0000 (-0700) Subject: rgw: introduce context to specific access calls X-Git-Tag: v0.34~131^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8d63e140777bbdd061baa6845d57e6c3cc771f76;p=ceph.git rgw: introduce context to specific access calls --- diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index d891fe8944fe..6fd78ef68a6c 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -121,7 +121,7 @@ namespace librados void zero(uint64_t off, uint64_t len); void rmxattr(const char *name); void setxattr(const char *name, const bufferlist& bl); - void cmpxattr(const char *name, const bufferlist& val, int op, int mode); + void cmpxattr(const char *name, const bufferlist& bl); void tmap_update(const bufferlist& cmdbl); void clone_range(uint64_t dst_off, const std::string& src_oid, uint64_t src_off, diff --git a/src/librados.cc b/src/librados.cc index 2c6acee08782..5986544f9eab 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -190,10 +190,10 @@ void librados::ObjectOperation::setxattr(const char *name, const bufferlist& v) o->setxattr(name, v); } -void librados::ObjectOperation::cmpxattr(const char *name, const bufferlist& v, int op, int mode) +void librados::ObjectOperation::cmpxattr(const char *name, const bufferlist& v) { ::ObjectOperation *o = (::ObjectOperation *)impl; - o->cmpxattr(name, v, op, mode); + o->cmpxattr(name, v); } void librados::ObjectOperation::tmap_update(const bufferlist& cmdbl) diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index dd45660fd164..873ef68b74c4 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -198,6 +198,9 @@ struct ObjectOperation { bl.append(s); add_xattr(CEPH_OSD_OP_SETXATTR, name, bl); } + void cmpxattr(const char *name, const bufferlist& bl) { + add_xattr(CEPH_OSD_OP_CMPXATTR, name, bl); + } void rmxattr(const char *name) { bufferlist bl; add_xattr(CEPH_OSD_OP_RMXATTR, name, bl); diff --git a/src/rgw/rgw_access.h b/src/rgw/rgw_access.h index a232a5e8db65..8b59ce6fcda1 100644 --- a/src/rgw/rgw_access.h +++ b/src/rgw/rgw_access.h @@ -60,18 +60,18 @@ public: virtual int create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive = true, uint64_t auid = 0) = 0; /** write an object to the storage device in the appropriate pool with the given stats */ - virtual int put_obj_meta(std::string& id, rgw_obj& obj, time_t *mtime, + virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, time_t *mtime, map& attrs, bool exclusive) = 0; - virtual int put_obj_data(std::string& id, rgw_obj& obj, const char *data, + virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len) = 0; - virtual int aio_put_obj_data(std::string& id, rgw_obj& obj, const char *data, + virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len, void **handle) { return -ENOTSUP; } - int put_obj(std::string& id, rgw_obj& obj, const char *data, size_t len, + int put_obj(void *ctx, std::string& id, rgw_obj& obj, const char *data, size_t len, time_t *mtime, map& attrs) { - int ret = put_obj_data(id, obj, data, -1, len); + int ret = put_obj_data(ctx, id, obj, data, -1, len); if (ret >= 0) { - ret = put_obj_meta(id, obj, mtime, attrs, false); + ret = put_obj_meta(ctx, id, obj, mtime, attrs, false); } return ret; } @@ -96,7 +96,7 @@ public: * err: stores any errors resulting from the get of the original object * Returns: 0 on success, -ERR# otherwise. */ - virtual int copy_obj(std::string& id, rgw_obj& dest_obj, + virtual int copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, const time_t *mod_ptr, @@ -128,7 +128,7 @@ public: * obj: name of the object to delete * Returns: 0 on success, -ERR# otherwise. */ - virtual int delete_obj(std::string& id, rgw_obj& obj, bool sync = true) = 0; + virtual int delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync = true) = 0; /** * Get data about an object out of RADOS and into memory. @@ -152,7 +152,8 @@ public: * (if get_data==true) length of read data, * (if get_data==false) length of the object */ - virtual int prepare_get_obj(rgw_obj& obj, + virtual int prepare_get_obj(void *ctx, + rgw_obj& obj, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -165,16 +166,16 @@ public: void **handle, struct rgw_err *err) = 0; - virtual int get_obj(void **handle, rgw_obj& obj, + virtual int get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end) = 0; virtual void finish_get_obj(void **handle) = 0; - virtual int clone_range(rgw_obj& dst_obj, off_t dst_ofs, + virtual int clone_range(void *ctx, rgw_obj& dst_obj, off_t dst_ofs, rgw_obj& src_obj, off_t src_ofs, uint64_t size) = 0; - virtual int clone_obj(rgw_obj& dst_obj, off_t dst_ofs, + virtual int clone_obj(void *ctx, rgw_obj& dst_obj, off_t dst_ofs, rgw_obj& src_obj, off_t src_ofs, uint64_t size, map attrs) { RGWCloneRangeInfo info; @@ -184,16 +185,16 @@ public: info.dst_ofs = dst_ofs; info.len = size; v.push_back(info); - return clone_objs(dst_obj, v, attrs, true); + return clone_objs(ctx, dst_obj, v, attrs, true); } - virtual int clone_objs(rgw_obj& dst_obj, + virtual int clone_objs(void *ctx, rgw_obj& dst_obj, vector& ranges, map attrs, bool truncate_dest) { return -ENOTSUP; } /** * a simple object read without keeping state */ - virtual int read(rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) = 0; + virtual int read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) = 0; /** * Get the attributes for an object. @@ -203,7 +204,7 @@ public: * dest: bufferlist to store the result in * Returns: 0 on success, -ERR# otherwise. */ - virtual int get_attr(rgw_obj& obj, const char *name, bufferlist& dest) = 0; + virtual int get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest) = 0; /** * Set an attr on an object. @@ -213,14 +214,14 @@ public: * bl: the contents of the attr * Returns: 0 on success, -ERR# otherwise. */ - virtual int set_attr(rgw_obj& obj, const char *name, bufferlist& bl) = 0; + virtual int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl) = 0; virtual int get_bucket_id(std::string& bucket) { return -ENOTSUP; } /** * stat an object */ - virtual int obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime) = 0; + virtual int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime) = 0; virtual bool supports_tmap() { return false; } @@ -240,6 +241,9 @@ public: static RGWAccess *init_storage_provider(const char *type, CephContext *cct); static void close_storage(); static RGWAccess *store; + + virtual void *create_context() { return NULL; } + virtual void destroy_context(void *ctx) {} }; class RGWStoreManager { diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 91ff18a693bf..e796225a71ca 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -300,7 +300,7 @@ static int create_bucket(string& bucket, string& user_id, string& display_name, if (ret && ret != -EEXIST) goto done; - ret = rgwstore->set_attr(obj, RGW_ATTR_ACL, aclbl); + ret = rgwstore->set_attr(NULL, obj, RGW_ATTR_ACL, aclbl); if (ret < 0) { cerr << "couldn't set acl on bucket" << std::endl; } @@ -702,7 +702,7 @@ int main(int argc, char **argv) string bucket_str(bucket); string object_str(object); rgw_obj obj(bucket_str, object_str); - int ret = store->get_attr(obj, RGW_ATTR_ACL, bl); + int ret = store->get_attr(NULL, obj, RGW_ATTR_ACL, bl); RGWAccessControlPolicy policy; if (ret >= 0) { @@ -755,7 +755,7 @@ int main(int argc, char **argv) bufferlist aclbl; rgw_obj obj(bucket_str, no_oid); - int r = rgwstore->get_attr(obj, RGW_ATTR_ACL, aclbl); + int r = rgwstore->get_attr(NULL, obj, RGW_ATTR_ACL, aclbl); if (r >= 0) { RGWAccessControlPolicy policy; ACLOwner owner; @@ -816,14 +816,14 @@ int main(int argc, char **argv) uint64_t size; rgw_obj obj(log_bucket, oid); - int r = store->obj_stat(obj, &size, NULL); + int r = store->obj_stat(NULL, obj, &size, NULL); if (r < 0) { cerr << "error while doing stat on " << log_bucket << ":" << oid << " " << cpp_strerror(-r) << std::endl; return -r; } bufferlist bl; - r = store->read(obj, 0, size, bl); + r = store->read(NULL, obj, 0, size, bl); if (r < 0) { cerr << "error while reading from " << log_bucket << ":" << oid << " " << cpp_strerror(-r) << std::endl; @@ -923,7 +923,7 @@ int main(int argc, char **argv) bufferlist bl; rgw_obj obj(bucket_str, no_object); - ret = rgwstore->get_attr(obj, RGW_ATTR_ACL, bl); + ret = rgwstore->get_attr(NULL, obj, RGW_ATTR_ACL, bl); if (ret < 0) { RGW_LOG(0) << "can't read bucket acls: " << ret << dendl; return ret; diff --git a/src/rgw/rgw_cache.h b/src/rgw/rgw_cache.h index 24860f80a09e..9bd8af9cfc96 100644 --- a/src/rgw/rgw_cache.h +++ b/src/rgw/rgw_cache.h @@ -149,23 +149,23 @@ class RGWCache : public T public: RGWCache() {} - int put_obj_data(std::string& id, rgw_obj& obj, const char *data, + int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len); - int get_obj(void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end); + int get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end); - int obj_stat(std::string& bucket, std::string& obj, uint64_t *psize, time_t *pmtime); + int obj_stat(void *ctx, std::string& bucket, std::string& obj, uint64_t *psize, time_t *pmtime); - int delete_obj(std::string& id, rgw_obj& obj, bool sync); + int delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync); }; template -int RGWCache::delete_obj(std::string& id, rgw_obj& obj, bool sync) +int RGWCache::delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync) { string& bucket = obj.bucket; if (bucket[0] != '.') - return T::delete_obj(id, obj, sync); + return T::delete_obj(ctx, id, obj, sync); string name = normal_name(obj); cache.remove(name); @@ -173,15 +173,15 @@ int RGWCache::delete_obj(std::string& id, rgw_obj& obj, bool sync) ObjectCacheInfo info; distribute(obj, info, REMOVE_OBJ); - return T::delete_obj(id, obj, sync); + return T::delete_obj(ctx, id, obj, sync); } template -int RGWCache::get_obj(void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end) +int RGWCache::get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end) { string& bucket = obj.bucket; if (bucket[0] != '.' || ofs != 0) - return T::get_obj(handle, obj, data, ofs, end); + return T::get_obj(ctx, handle, obj, data, ofs, end); string& oid = obj.object; string name = normal_name(bucket, oid); @@ -197,7 +197,7 @@ int RGWCache::get_obj(void **handle, rgw_obj& obj, char **data, off_t ofs, of memcpy(*data, bl.c_str(), bl.length()); return bl.length(); } - int r = T::get_obj(handle, obj, data, ofs, end); + int r = T::get_obj(ctx, handle, obj, data, ofs, end); if (r < 0) { if (r == -ENOENT) { // only update ENOENT, we'd rather retry other errors info.status = r; @@ -218,7 +218,7 @@ int RGWCache::get_obj(void **handle, rgw_obj& obj, char **data, off_t ofs, of } template -int RGWCache::put_obj_data(std::string& id, rgw_obj& obj, const char *data, +int RGWCache::put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len) { string& bucket = obj.bucket; @@ -236,7 +236,7 @@ int RGWCache::put_obj_data(std::string& id, rgw_obj& obj, const char *data, info.status = 0; info.flags = CACHE_FLAG_DATA; } - int ret = T::put_obj_data(id, obj, data, ofs, len); + int ret = T::put_obj_data(ctx, id, obj, data, ofs, len); if (cacheable) { if (ret >= 0) { cache.put(name, info); @@ -252,10 +252,10 @@ int RGWCache::put_obj_data(std::string& id, rgw_obj& obj, const char *data, } template -int RGWCache::obj_stat(std::string& bucket, std::string& obj, uint64_t *psize, time_t *pmtime) +int RGWCache::obj_stat(void *ctx, std::string& bucket, std::string& obj, uint64_t *psize, time_t *pmtime) { if (bucket[0] != '.') - return T::obj_stat(bucket, obj, psize, pmtime); + return T::obj_stat(ctx, bucket, obj, psize, pmtime); string name = normal_name(bucket, obj); @@ -274,7 +274,7 @@ int RGWCache::obj_stat(std::string& bucket, std::string& obj, uint64_t *psize mtime = info.meta.mtime; goto done; } - r = T::obj_stat(bucket, obj, &size, &mtime); + r = T::obj_stat(ctx, bucket, obj, &size, &mtime); if (r < 0) { if (r == -ENOENT) { info.status = r; diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 8b8c7e2113b7..4574f4a7b734 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -66,7 +66,6 @@ req_state::req_state(struct RGWEnv *e) : acl(NULL), os_auth_token(NULL), os_user } req_state::~req_state() { - delete acl; delete formatter; free(os_user); free(os_groups); diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 1cbe42801230..677b25ef1353 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -47,6 +47,7 @@ extern string rgw_root_bucket; #define RGW_ATTR_BUCKETS RGW_ATTR_PREFIX "buckets" #define RGW_ATTR_META_PREFIX RGW_ATTR_PREFIX "x-amz-meta-" #define RGW_ATTR_CONTENT_TYPE RGW_ATTR_PREFIX "content_type" +#define RGW_ATTR_ID_TAG RGW_ATTR_PREFIX "idtag" #define RGW_BUCKETS_OBJ_PREFIX ".buckets" @@ -416,6 +417,8 @@ struct req_state { struct RGWEnv *env; + void *obj_ctx; + req_state(struct RGWEnv *e); ~req_state(); }; @@ -629,6 +632,12 @@ public: ::decode(ns, bl); ::decode(object, bl); } + + bool operator<(const rgw_obj& o) const { + return (bucket.compare(o.bucket) < 0) || + (object.compare(o.object) < 0) || + (ns.compare(o.ns) < 0); + } }; WRITE_CLASS_ENCODER(rgw_obj) diff --git a/src/rgw/rgw_fs.cc b/src/rgw/rgw_fs.cc index c8e9ad7619cd..d584f990b9af 100644 --- a/src/rgw/rgw_fs.cc +++ b/src/rgw/rgw_fs.cc @@ -89,7 +89,7 @@ int RGWFS::list_buckets_next(string& id, RGWObjEnt& obj, RGWAccessHandle *handle } } -int RGWFS::obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime) +int RGWFS::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime) { return -ENOTSUP; } @@ -203,7 +203,7 @@ int RGWFS::create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive) { std::string& bucket = obj.bucket; @@ -250,7 +250,7 @@ done_err: return -errno; } -int RGWFS::put_obj_data(std::string& id, rgw_obj& obj, const char *data, +int RGWFS::put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t size) { std::string& bucket = obj.bucket; @@ -291,7 +291,7 @@ done_err: return r; } -int RGWFS::copy_obj(std::string& id, rgw_obj& dest_obj, +int RGWFS::copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, const time_t *mod_ptr, @@ -309,13 +309,13 @@ int RGWFS::copy_obj(std::string& id, rgw_obj& dest_obj, time_t lastmod; map attrset; - ret = prepare_get_obj(src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod, + ret = prepare_get_obj(ctx, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &obj_size, &handle, err); if (ret < 0) return ret; do { - ret = get_obj(&handle, src_obj, &data, ofs, end); + ret = get_obj(ctx, &handle, src_obj, &data, ofs, end); if (ret < 0) return ret; ofs += ret; @@ -327,7 +327,7 @@ int RGWFS::copy_obj(std::string& id, rgw_obj& dest_obj, } attrs = attrset; - ret = put_obj(id, dest_obj, data, ret, mtime, attrs); + ret = put_obj(ctx, id, dest_obj, data, ret, mtime, attrs); return ret; } @@ -345,7 +345,7 @@ int RGWFS::delete_bucket(std::string& id, std::string& bucket) } -int RGWFS::delete_obj(std::string& id, rgw_obj& obj, bool sync) +int RGWFS::delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync) { std::string& bucket = obj.bucket; std::string& oid = obj.object; @@ -413,7 +413,7 @@ int RGWFS::get_attr(const char *name, const char *path, char **attr) return attr_len; } -int RGWFS::get_attr(rgw_obj& obj, const char *name, bufferlist& dest) +int RGWFS::get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest) { std::string& bucket = obj.bucket; std::string& oid = obj.object; @@ -434,7 +434,7 @@ done: return r; } -int RGWFS::set_attr(rgw_obj& obj, +int RGWFS::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl) { std::string& bucket = obj.bucket; @@ -453,7 +453,8 @@ int RGWFS::set_attr(rgw_obj& obj, return ret; } -int RGWFS::prepare_get_obj(rgw_obj& obj, +int RGWFS::prepare_get_obj(void *ctx, + rgw_obj& obj, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -561,7 +562,7 @@ done_err: return r; } -int RGWFS::get_obj(void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end) +int RGWFS::get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end) { uint64_t len; bufferlist bl; @@ -616,7 +617,7 @@ void RGWFS::finish_get_obj(void **handle) } } -int RGWFS::read(rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) +int RGWFS::read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) { std::string& bucket = obj.bucket; std::string& oid = obj.object; diff --git a/src/rgw/rgw_fs.h b/src/rgw/rgw_fs.h index a69456dea7dd..27ac43310f60 100644 --- a/src/rgw/rgw_fs.h +++ b/src/rgw/rgw_fs.h @@ -19,13 +19,13 @@ public: bool get_content_type, string& ns, bool *is_truncated, RGWAccessListFilter *filter); int create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive, uint64_t auid=0); - int put_obj_meta(std::string& id, rgw_obj& obj, time_t *mtime, + int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, time_t *mtime, map& attrs, bool exclusive); - int put_obj_data(std::string& id, rgw_obj& obj, const char *data, + int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t size); - int clone_range(rgw_obj& dst_obj, off_t dst_ofs, + int clone_range(void *ctx, rgw_obj& dst_obj, off_t dst_ofs, rgw_obj& src_obj, off_t src_ofs, uint64_t size) { return -ENOTSUP; } - int copy_obj(std::string& id, rgw_obj& dest_obj, + int copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, const time_t *mod_ptr, @@ -35,14 +35,15 @@ public: map& attrs, struct rgw_err *err); int delete_bucket(std::string& id, std::string& bucket); - int delete_obj(std::string& id, rgw_obj& obj, bool sync); + int delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync); int get_attr(const char *name, int fd, char **attr); int get_attr(const char *name, const char *path, char **attr); - int get_attr(rgw_obj& obj, const char *name, bufferlist& dest); - int set_attr(rgw_obj& obj, const char *name, bufferlist& bl); + int get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest); + int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl); - int prepare_get_obj(rgw_obj& obj, + int prepare_get_obj(void *ctx, + rgw_obj& obj, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -55,11 +56,11 @@ public: void **handle, struct rgw_err *err); - int get_obj(void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end); + int get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end); void finish_get_obj(void **handle); - int read(rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl); - int obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime); + int read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl); + int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime); }; #endif diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index 7313d9049ee3..c8915b8fb98c 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -153,6 +153,7 @@ void RGWProcess::handle_request(FCGX_Request *fcgx) rgw_env.init(fcgx->envp); struct req_state *s = new req_state(&rgw_env); + s->obj_ctx = rgwstore->create_context(); RGWOp *op = NULL; int init_error = 0; @@ -201,6 +202,7 @@ done: int http_ret = s->err.http_ret; handler->put_op(op); + rgwstore->destroy_context(s->obj_ctx); delete s; FCGX_Finish_r(fcgx); delete fcgx; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index ead6b96c45bb..c02d167de02d 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -137,13 +137,13 @@ void get_request_metadata(struct req_state *s, map& attrs) * object: name of the object to get the ACL for. * Returns: 0 on success, -ERR# otherwise. */ -static int get_policy_from_attr(RGWAccessControlPolicy *policy, rgw_obj& obj) +static int get_policy_from_attr(void *ctx, RGWAccessControlPolicy *policy, rgw_obj& obj) { bufferlist bl; int ret = 0; if (obj.bucket.size()) { - ret = rgwstore->get_attr(obj, RGW_ATTR_ACL, bl); + ret = rgwstore->get_attr(ctx, obj, RGW_ATTR_ACL, bl); if (ret >= 0) { bufferlist::iterator iter = bl.begin(); @@ -182,14 +182,14 @@ int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, string& bucke } obj.init(bucket, oid, object); - int ret = get_policy_from_attr(policy, obj); + int ret = get_policy_from_attr(s->obj_ctx, policy, obj); if (ret == -ENOENT && object.size()) { /* object does not exist checking the bucket's ACL to make sure that we send a proper error code */ RGWAccessControlPolicy bucket_policy; string no_object; rgw_obj no_obj(bucket, no_object); - ret = get_policy_from_attr(&bucket_policy, no_obj); + ret = get_policy_from_attr(s->obj_ctx, &bucket_policy, no_obj); if (ret < 0) return ret; @@ -251,7 +251,7 @@ void RGWGetObj::execute() init_common(); obj.init(s->bucket_str, s->object_str); - ret = rgwstore->prepare_get_obj(obj, ofs, &end, &attrs, mod_ptr, + ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, ofs, &end, &attrs, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &s->obj_size, &handle, &s->err); if (ret < 0) goto done; @@ -260,7 +260,7 @@ void RGWGetObj::execute() goto done; while (ofs <= end) { - ret = rgwstore->get_obj(&handle, obj, &data, ofs, end); + ret = rgwstore->get_obj(s->obj_ctx, &handle, obj, &data, ofs, end); if (ret < 0) { goto done; } @@ -419,7 +419,7 @@ void RGWCreateBucket::execute() rgw_obj obj(rgw_root_bucket, s->bucket_str); - int r = get_policy_from_attr(&old_policy, obj); + int r = get_policy_from_attr(s->obj_ctx, &old_policy, obj); if (r >= 0) { if (old_policy.get_owner().get_id().compare(s->user.user_id) != 0) { ret = -EEXIST; @@ -621,7 +621,7 @@ void RGWPutObj::execute() // For the first call to put_obj_data, pass -1 as the offset to // do a write_full. void *handle; - ret = rgwstore->aio_put_obj_data(s->user.user_id, obj, + ret = rgwstore->aio_put_obj_data(s->obj_ctx, s->user.user_id, obj, data, ((ofs == 0) ? -1 : ofs), len, &handle); if (ret < 0) @@ -689,16 +689,16 @@ void RGWPutObj::execute() if (!multipart) { rgw_obj dst_obj(s->bucket_str, s->object_str); - ret = rgwstore->clone_obj(dst_obj, 0, obj, 0, s->obj_size, attrs); + ret = rgwstore->clone_obj(s->obj_ctx, dst_obj, 0, obj, 0, s->obj_size, attrs); if (ret < 0) goto done_err; if (created_obj) { - ret = rgwstore->delete_obj(s->user.user_id, obj); + ret = rgwstore->delete_obj(s->obj_ctx, s->user.user_id, obj); if (ret < 0) goto done; } } else { - ret = rgwstore->put_obj_meta(s->user.user_id, obj, NULL, attrs, false); + ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, NULL, attrs, false); if (ret < 0) goto done_err; @@ -716,7 +716,7 @@ void RGWPutObj::execute() rgw_obj meta_obj(s->bucket_str, multipart_meta_obj, s->object_str, mp_ns); - ret = rgwstore->put_obj_meta(s->user.user_id, meta_obj, NULL, meta_attrs, false); + ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, meta_obj, NULL, meta_attrs, false); } } done: @@ -726,7 +726,7 @@ done: done_err: if (created_obj) - rgwstore->delete_obj(s->user.user_id, obj); + rgwstore->delete_obj(s->obj_ctx, s->user.user_id, obj); drain_pending(pending); send_response(); } @@ -744,7 +744,7 @@ void RGWDeleteObj::execute() ret = -EINVAL; rgw_obj obj(s->bucket_str, s->object_str); if (s->object) { - ret = rgwstore->delete_obj(s->user.user_id, obj); + ret = rgwstore->delete_obj(s->obj_ctx, s->user.user_id, obj); } send_response(); @@ -850,7 +850,7 @@ void RGWCopyObj::execute() src_obj.init(src_bucket, src_object); dst_obj.init(s->bucket_str, s->object_str); - ret = rgwstore->copy_obj(s->user.user_id, + ret = rgwstore->copy_obj(s->obj_ctx, s->user.user_id, dst_obj, src_obj, &mtime, @@ -1064,7 +1064,7 @@ void RGWPutACLs::execute() new_policy.encode(bl); obj.init(s->bucket_str, s->object_str); - ret = rgwstore->set_attr(obj, RGW_ATTR_ACL, bl); + ret = rgwstore->set_attr(s->obj_ctx, obj, RGW_ATTR_ACL, bl); done: free(orig_data); @@ -1122,7 +1122,7 @@ void RGWInitMultipart::execute() tmp_obj_name = mp.get_meta(); obj.init(s->bucket_str, tmp_obj_name, s->object_str, mp_ns); - ret = rgwstore->put_obj_meta(s->user.user_id, obj, NULL, attrs, true); + ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, NULL, attrs, true); } while (ret == -EEXIST); done: send_response(); @@ -1137,7 +1137,7 @@ static int get_multiparts_info(struct req_state *s, string& meta_oid, mapbucket_str, meta_oid, s->object_str, mp_ns); - int ret = rgwstore->prepare_get_obj(obj, 0, NULL, &attrs, NULL, + int ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, 0, NULL, &attrs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &handle, &s->err); rgwstore->finish_get_obj(&handle); @@ -1262,7 +1262,7 @@ void RGWCompleteMultipart::execute() attrs[RGW_ATTR_ETAG] = etag_bl; target_obj.init(s->bucket_str, s->object_str); - ret = rgwstore->put_obj_meta(s->user.user_id, target_obj, NULL, attrs, false); + ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, NULL, attrs, false); if (ret < 0) goto done; @@ -1279,7 +1279,7 @@ void RGWCompleteMultipart::execute() ofs += obj_iter->second.size; } - ret = rgwstore->clone_objs(target_obj, ranges, attrs, true); + ret = rgwstore->clone_objs(s->obj_ctx, target_obj, ranges, attrs, true); if (ret < 0) goto done; @@ -1287,11 +1287,11 @@ void RGWCompleteMultipart::execute() for (obj_iter = obj_parts.begin(); obj_iter != obj_parts.end(); ++obj_iter) { string oid = mp.get_part(obj_iter->second.num); rgw_obj obj(s->bucket_str, oid, s->object_str, mp_ns); - rgwstore->delete_obj(s->user.user_id, obj); + rgwstore->delete_obj(s->obj_ctx, s->user.user_id, obj); } // and also remove the metadata obj meta_obj.init(s->bucket_str, meta_oid, s->object_str, mp_ns); - rgwstore->delete_obj(s->user.user_id, meta_obj); + rgwstore->delete_obj(s->obj_ctx, s->user.user_id, meta_obj); done: send_response(); @@ -1331,13 +1331,13 @@ void RGWAbortMultipart::execute() for (obj_iter = obj_parts.begin(); obj_iter != obj_parts.end(); ++obj_iter) { string oid = mp.get_part(obj_iter->second.num); rgw_obj obj(s->bucket_str, oid, s->object_str, mp_ns); - ret = rgwstore->delete_obj(s->user.user_id, obj); + ret = rgwstore->delete_obj(s->obj_ctx, s->user.user_id, obj); if (ret < 0 && ret != -ENOENT) goto done; } // and also remove the metadata obj meta_obj.init(s->bucket_str, meta_oid, s->object_str, mp_ns); - ret = rgwstore->delete_obj(s->user.user_id, meta_obj); + ret = rgwstore->delete_obj(s->obj_ctx, s->user.user_id, meta_obj); if (ret == -ENOENT) { ret = -ERR_NO_SUCH_BUCKET; } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 227d1cf1c96f..b9a9501aecd9 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1,5 +1,6 @@ #include #include +#include #include "rgw_access.h" #include "rgw_rados.h" @@ -333,7 +334,7 @@ int RGWRados::create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive) { std::string& bucket = obj.bucket; @@ -385,17 +386,17 @@ int RGWRados::put_obj_meta(std::string& id, rgw_obj& obj, * attrs: all the given attrs are written to bucket storage for the given object * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::put_obj_data(std::string& id, rgw_obj& obj, +int RGWRados::put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len) { void *handle; - int r = aio_put_obj_data(id, obj, data, ofs, len, &handle); + int r = aio_put_obj_data(ctx, id, obj, data, ofs, len, &handle); if (r < 0) return r; return aio_wait(handle); } -int RGWRados::aio_put_obj_data(std::string& id, rgw_obj& obj, +int RGWRados::aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len, void **handle) { @@ -458,7 +459,7 @@ bool RGWRados::aio_completed(void *handle) * err: stores any errors resulting from the get of the original object * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::copy_obj(std::string& id, rgw_obj& dest_obj, +int RGWRados::copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, const time_t *mod_ptr, @@ -488,7 +489,7 @@ int RGWRados::copy_obj(std::string& id, rgw_obj& dest_obj, void *handle = NULL; map attrset; - ret = prepare_get_obj(src_obj, 0, &end, &attrset, + ret = prepare_get_obj(ctx, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &obj_size, &handle, err); if (ret < 0) @@ -496,13 +497,13 @@ int RGWRados::copy_obj(std::string& id, rgw_obj& dest_obj, off_t ofs = 0; do { - ret = get_obj(&handle, src_obj, &data, ofs, end); + ret = get_obj(ctx, &handle, src_obj, &data, ofs, end); if (ret < 0) return ret; // In the first call to put_obj_data, we pass ofs == -1 so that it will do // a write_full, wiping out whatever was in the object before this - r = put_obj_data(id, tmp_obj, data, ((ofs == 0) ? -1 : ofs), ret); + r = put_obj_data(ctx, id, tmp_obj, data, ((ofs == 0) ? -1 : ofs), ret); free(data); if (r < 0) goto done_err; @@ -515,11 +516,11 @@ int RGWRados::copy_obj(std::string& id, rgw_obj& dest_obj, } attrs = attrset; - ret = clone_obj(dest_obj, 0, tmp_obj, 0, end + 1, attrs); + ret = clone_obj(ctx, dest_obj, 0, tmp_obj, 0, end + 1, attrs); if (mtime) - obj_stat(tmp_obj, NULL, mtime); + obj_stat(ctx, tmp_obj, NULL, mtime); - r = rgwstore->delete_obj(id, tmp_obj, false); + r = rgwstore->delete_obj(ctx, id, tmp_obj, false); if (r < 0) RGW_LOG(0) << "ERROR: could not remove " << tmp_obj << dendl; @@ -527,7 +528,7 @@ int RGWRados::copy_obj(std::string& id, rgw_obj& dest_obj, return ret; done_err: - rgwstore->delete_obj(id, tmp_obj, false); + rgwstore->delete_obj(ctx, id, tmp_obj, false); finish_get_obj(&handle); return r; } @@ -553,7 +554,7 @@ int RGWRados::delete_bucket(std::string& id, std::string& bucket) return r; rgw_obj obj(rgw_root_bucket, bucket); - r = delete_obj(id, obj, true); + r = delete_obj(NULL, id, obj, true); if (r < 0) return r; @@ -585,7 +586,7 @@ int RGWRados::purge_buckets(std::string& id, vector& buckets) } rgw_obj obj(rgw_root_bucket, bucket); - r = delete_obj(id, obj, true); + r = delete_obj(NULL, id, obj, true); if (r < 0) { RGW_LOG(0) << "WARNING: could not remove bucket object: " << RGW_ROOT_BUCKET << ":" << bucket << dendl; ret = r; @@ -667,7 +668,7 @@ int RGWRados::bucket_suspended(std::string& bucket, bool *suspended) * obj: name of the object to delete * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::delete_obj(std::string& id, rgw_obj& obj, bool sync) +int RGWRados::delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync) { std::string& bucket = obj.bucket; std::string& oid = obj.object; @@ -692,6 +693,23 @@ int RGWRados::delete_obj(std::string& id, rgw_obj& obj, bool sync) return 0; } +int RGWRados::get_obj_state(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, RGWObjState **state) +{ + RGWObjState *s = rctx->get_state(obj); + if (s->has_attrs) + return 0; + + *state = s; + + int r = io_ctx.getxattrs(actual_obj, s->attrset); + if (r < 0) + return r; + + s->has_attrs = true; + s->ver = io_ctx.get_last_version(); + return 0; +} + /** * Get the attributes for an object. * bucket: name of the bucket holding the object. @@ -700,13 +718,14 @@ int RGWRados::delete_obj(std::string& id, rgw_obj& obj, bool sync) * dest: bufferlist to store the result in * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::get_attr(rgw_obj& obj, const char *name, bufferlist& dest) +int RGWRados::get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest) { std::string& bucket = obj.bucket; std::string& oid = obj.object; librados::IoCtx io_ctx; string actual_bucket = bucket; string actual_obj = oid; + RGWRadosCtx *rctx = (RGWRadosCtx *)ctx; if (actual_obj.size() == 0) { actual_obj = bucket; @@ -719,6 +738,16 @@ int RGWRados::get_attr(rgw_obj& obj, const char *name, bufferlist& dest) io_ctx.locator_set_key(obj.key); + if (rctx) { + RGWObjState *state; + r = get_obj_state(rctx, obj, io_ctx, actual_obj, &state); + if (r < 0) + return r; + if (state->get_attr(name, dest)) + return 0; + return -ENODATA; + } + r = io_ctx.getxattr(actual_obj, name, dest); if (r < 0) return r; @@ -734,13 +763,14 @@ int RGWRados::get_attr(rgw_obj& obj, const char *name, bufferlist& dest) * bl: the contents of the attr * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::set_attr(rgw_obj& obj, const char *name, bufferlist& bl) +int RGWRados::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl) { std::string& bucket = obj.bucket; std::string& oid = obj.object; librados::IoCtx io_ctx; string actual_bucket = bucket; string actual_obj = oid; + RGWRadosCtx *rctx = (RGWRadosCtx *)ctx; if (actual_obj.size() == 0) { actual_obj = bucket; @@ -753,7 +783,25 @@ int RGWRados::set_attr(rgw_obj& obj, const char *name, bufferlist& bl) io_ctx.locator_set_key(obj.key); - r = io_ctx.setxattr(actual_obj, name, bl); + if (rctx) { + RGWObjState *state; + r = get_obj_state(rctx, obj, io_ctx, actual_obj, &state); + if (r < 0) + return r; + ObjectOperation op; + if (state->obj_tag.length() > 0) // check for backward compatibility + op.cmpxattr(RGW_ATTR_ID_TAG, state->obj_tag); + op.setxattr(name, bl); + + bufferlist outbl; + r = io_ctx.operate(actual_obj, &op, &outbl); + + if (r >= 0) + state->attrset[name] = bl; + } else { + r = io_ctx.setxattr(actual_obj, name, bl); + } + if (r < 0) return r; @@ -783,7 +831,7 @@ int RGWRados::set_attr(rgw_obj& obj, const char *name, bufferlist& bl) * (if get_data==true) length of read data, * (if get_data==false) length of the object */ -int RGWRados::prepare_get_obj(rgw_obj& obj, +int RGWRados::prepare_get_obj(void *ctx, rgw_obj& obj, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -827,7 +875,7 @@ int RGWRados::prepare_get_obj(rgw_obj& obj, } if (attrs) { - r = state->io_ctx.getxattrs(oid, *attrs); + r = state->io_ctx.getxattrs(oid, *attrs); /* FIXME: should be get_xattrs(), using ctx */ if (g_conf->rgw_log >= 20) { for (iter = attrs->begin(); iter != attrs->end(); ++iter) { RGW_LOG(20) << "Read xattr: " << iter->first << dendl; @@ -860,7 +908,7 @@ int RGWRados::prepare_get_obj(rgw_obj& obj, } } if (if_match || if_nomatch) { - r = get_attr(obj, RGW_ATTR_ETAG, etag); + r = get_attr(ctx, obj, RGW_ATTR_ETAG, etag); if (r < 0) goto done_err; @@ -902,7 +950,7 @@ done_err: return r; } -int RGWRados::clone_range(rgw_obj& dst_obj, off_t dst_ofs, +int RGWRados::clone_range(void *ctx, rgw_obj& dst_obj, off_t dst_ofs, rgw_obj& src_obj, off_t src_ofs, uint64_t size) { std::string& bucket = dst_obj.bucket; @@ -919,7 +967,7 @@ int RGWRados::clone_range(rgw_obj& dst_obj, off_t dst_ofs, return io_ctx.clone_range(dst_oid, dst_ofs, src_oid, src_ofs, size); } -int RGWRados::clone_objs(rgw_obj& dst_obj, +int RGWRados::clone_objs(void *ctx, rgw_obj& dst_obj, vector& ranges, map attrs, bool truncate_dest) @@ -968,7 +1016,7 @@ int RGWRados::clone_objs(rgw_obj& dst_obj, return ret; } -int RGWRados::get_obj(void **handle, rgw_obj& obj, +int RGWRados::get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end) { std::string& oid = obj.object; @@ -1014,7 +1062,7 @@ void RGWRados::finish_get_obj(void **handle) } /* a simple object read */ -int RGWRados::read(rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) +int RGWRados::read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) { std::string& bucket = obj.bucket; std::string& oid = obj.object; @@ -1029,7 +1077,7 @@ int RGWRados::read(rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl) return r; } -int RGWRados::obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime) +int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime) { std::string& bucket = obj.bucket; std::string& oid = obj.object; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 035f3ff45af1..890e3eed7481 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -7,6 +7,32 @@ class RGWWatcher; +struct RGWObjState { + bool is_atomic; + uint64_t ver; + bool has_attrs; + bufferlist obj_tag; + + map attrset; + RGWObjState() : is_atomic(false), ver(0), has_attrs(0) {} + + bool get_attr(string name, bufferlist& dest) { + map::iterator iter = attrset.find(name); + if (iter != attrset.end()) { + dest = iter->second; + return true; + } + return false; + } +}; + +struct RGWRadosCtx { + map objs_state; + RGWObjState *get_state(rgw_obj& obj) { + return &objs_state[obj]; + } +}; + class RGWRados : public RGWAccess { /** Open the pool used as root for this gateway */ @@ -28,6 +54,7 @@ class RGWRados : public RGWAccess librados::IoCtx root_pool_ctx; librados::IoCtx control_pool_ctx; + int get_obj_state(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, RGWObjState **state); public: RGWRados() : watcher(NULL), watch_handle(0) {} @@ -53,22 +80,22 @@ public: virtual int create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive = true, uint64_t auid = 0); /** Write/overwrite an object to the bucket storage. */ - virtual int put_obj_meta(std::string& id, rgw_obj& obj, time_t *mtime, + virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, time_t *mtime, map& attrs, bool exclusive); - virtual int put_obj_data(std::string& id, rgw_obj& obj, const char *data, + virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len); - virtual int aio_put_obj_data(std::string& id, rgw_obj& obj, const char *data, + virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data, off_t ofs, size_t len, void **handle); virtual int aio_wait(void *handle); virtual bool aio_completed(void *handle); - virtual int clone_range(rgw_obj& dst_obj, off_t dst_ofs, + virtual int clone_range(void *ctx, rgw_obj& dst_obj, off_t dst_ofs, rgw_obj& src_obj, off_t src_ofs, uint64_t size); - virtual int clone_objs(rgw_obj& dst_obj, + virtual int clone_objs(void *ctx, rgw_obj& dst_obj, vector& ranges, map attrs, bool truncate_dest); /** Copy an object, with many extra options */ - virtual int copy_obj(std::string& id, rgw_obj& dest_obj, + virtual int copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, const time_t *mod_ptr, @@ -86,16 +113,16 @@ public: virtual int bucket_suspended(std::string& bucket, bool *suspended); /** Delete an object.*/ - virtual int delete_obj(std::string& id, rgw_obj& src_obj, bool sync); + virtual int delete_obj(void *ctx, std::string& id, rgw_obj& src_obj, bool sync); /** Get the attributes for an object.*/ - virtual int get_attr(rgw_obj& obj, const char *name, bufferlist& dest); + virtual int get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest); /** Set an attr on an object. */ - virtual int set_attr(rgw_obj& obj, const char *name, bufferlist& bl); + virtual int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl); /** Get data about an object out of RADOS and into memory. */ - virtual int prepare_get_obj(rgw_obj& obj, + virtual int prepare_get_obj(void *ctx, rgw_obj& obj, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -108,14 +135,14 @@ public: void **handle, struct rgw_err *err); - virtual int get_obj(void **handle, rgw_obj& obj, + virtual int get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end); virtual void finish_get_obj(void **handle); - virtual int read(rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl); + virtual int read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl); - virtual int obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime); + virtual int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime); virtual int get_bucket_id(std::string& bucket); @@ -130,6 +157,15 @@ public: virtual void finalize_watch(); virtual int distribute(bufferlist& bl); virtual int watch_cb(int opcode, uint64_t ver, bufferlist& bl) { return 0; } + + void *create_context() { + return new RGWRadosCtx(); + } + void destroy_context(void *ctx) { + delete (RGWRadosCtx *)ctx; + } + + void set_atomic_ops(void *ctx, rgw_obj& obj); }; #endif diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index f9835c6457b1..b92bea81c254 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -44,12 +44,12 @@ static int put_obj(string& uid, string& bucket, string& oid, const char *data, s rgw_obj obj(bucket, oid); - int ret = rgwstore->put_obj(uid, obj, data, size, NULL, attrs); + int ret = rgwstore->put_obj(NULL, uid, obj, data, size, NULL, attrs); if (ret == -ENOENT) { ret = rgwstore->create_bucket(uid, bucket, attrs); if (ret >= 0) - ret = rgwstore->put_obj(uid, obj, data, size, NULL, attrs); + ret = rgwstore->put_obj(NULL, uid, obj, data, size, NULL, attrs); } return ret; @@ -65,13 +65,13 @@ static int get_obj(string& bucket, string& key, bufferlist& bl) bufferlist::iterator iter; int request_len = READ_CHUNK_LEN; rgw_obj obj(bucket, key); - ret = rgwstore->prepare_get_obj(obj, 0, NULL, NULL, NULL, + ret = rgwstore->prepare_get_obj(NULL, obj, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &handle, &err); if (ret < 0) return ret; do { - ret = rgwstore->get_obj(&handle, obj, &data, 0, request_len - 1); + ret = rgwstore->get_obj(NULL, &handle, obj, &data, 0, request_len - 1); if (ret < 0) goto done; if (ret < request_len) @@ -220,7 +220,7 @@ static int rgw_read_buckets_from_attr(string& user_id, RGWUserBuckets& buckets) { bufferlist bl; rgw_obj obj(ui_uid_bucket, user_id); - int ret = rgwstore->get_attr(obj, RGW_ATTR_BUCKETS, bl); + int ret = rgwstore->get_attr(NULL, obj, RGW_ATTR_BUCKETS, bl); if (ret) return ret; @@ -258,7 +258,7 @@ int rgw_read_user_buckets(string user_id, RGWUserBuckets& buckets, bool need_sta rgw_obj obj(ui_uid_bucket, buckets_obj_id); do { - ret = rgwstore->read(obj, 0, len, bl); + ret = rgwstore->read(NULL, obj, 0, len, bl); if (ret == -ENOENT) { /* try to read the old format */ ret = rgw_read_buckets_from_attr(user_id, buckets); @@ -329,7 +329,7 @@ int rgw_write_buckets_attr(string user_id, RGWUserBuckets& buckets) rgw_obj obj(ui_uid_bucket, user_id); - int ret = rgwstore->set_attr(obj, RGW_ATTR_BUCKETS, bl); + int ret = rgwstore->set_attr(NULL, obj, RGW_ATTR_BUCKETS, bl); return ret; } @@ -420,28 +420,28 @@ int rgw_remove_bucket(string user_id, string bucket_name, bool purge_data) int rgw_remove_key_index(RGWAccessKey& access_key) { rgw_obj obj(ui_key_bucket, access_key.id); - int ret = rgwstore->delete_obj(access_key.id, obj); + int ret = rgwstore->delete_obj(NULL, access_key.id, obj); return ret; } int rgw_remove_uid_index(string& uid) { rgw_obj obj(ui_uid_bucket, uid); - int ret = rgwstore->delete_obj(uid, obj); + int ret = rgwstore->delete_obj(NULL, uid, obj); return ret; } int rgw_remove_email_index(string& uid, string& email) { rgw_obj obj(ui_email_bucket, email); - int ret = rgwstore->delete_obj(uid, obj); + int ret = rgwstore->delete_obj(NULL, uid, obj); return ret; } int rgw_remove_openstack_name_index(string& uid, string& openstack_name) { rgw_obj obj(ui_openstack_bucket, openstack_name); - int ret = rgwstore->delete_obj(uid, obj); + int ret = rgwstore->delete_obj(NULL, uid, obj); return ret; } @@ -473,20 +473,20 @@ int rgw_delete_user(RGWUserInfo& info, bool purge_data) { } rgw_obj uid_obj(ui_uid_bucket, info.user_id); - ret = rgwstore->delete_obj(info.user_id, uid_obj); + ret = rgwstore->delete_obj(NULL, info.user_id, uid_obj); if (ret < 0 && ret != -ENOENT) RGW_LOG(0) << "ERROR: could not remove " << info.user_id << ":" << uid_obj << ", should be fixed manually (err=" << ret << ")" << dendl; string buckets_obj_id; get_buckets_obj(info.user_id, buckets_obj_id); rgw_obj uid_bucks(ui_uid_bucket, buckets_obj_id); - ret = rgwstore->delete_obj(info.user_id, uid_bucks); + ret = rgwstore->delete_obj(NULL, info.user_id, uid_bucks); if (ret < 0 && ret != -ENOENT) RGW_LOG(0) << "ERROR: could not remove " << info.user_id << ":" << uid_bucks << ", should be fixed manually (err=" << ret << ")" << dendl; rgw_obj email_obj(ui_email_bucket, info.user_email); - ret = rgwstore->delete_obj(info.user_id, email_obj); + ret = rgwstore->delete_obj(NULL, info.user_id, email_obj); if (ret < 0 && ret != -ENOENT) RGW_LOG(0) << "ERROR: could not remove " << info.user_id << ":" << email_obj << ", should be fixed manually (err=" << ret << ")" << dendl;