From d4edd17cc40c1c694333f9c0a6be3c97c174b6a9 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 2 Jun 2011 16:58:27 -0700 Subject: [PATCH] rgw: multipart: use locator on created parts --- src/rgw/rgw_access.h | 16 ++++++++-------- src/rgw/rgw_admin.cc | 2 +- src/rgw/rgw_fs.cc | 16 ++++++++-------- src/rgw/rgw_fs.h | 10 +++++----- src/rgw/rgw_op.cc | 25 +++++++++++++------------ src/rgw/rgw_rados.cc | 30 ++++++++++++++++++++---------- src/rgw/rgw_rados.h | 10 +++++----- src/rgw/rgw_user.cc | 10 +++++----- 8 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/rgw/rgw_access.h b/src/rgw/rgw_access.h index 3baeeb3c9a306..7338884428ee2 100644 --- a/src/rgw/rgw_access.h +++ b/src/rgw/rgw_access.h @@ -46,16 +46,16 @@ public: virtual int create_bucket(std::string& id, std::string& bucket, map& attrs, 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, std::string& bucket, std::string& obj, time_t *mtime, + virtual int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, std::string& loc, time_t *mtime, map& attrs, bool exclusive) = 0; - virtual int put_obj_data(std::string& id, std::string& bucket, std::string& obj, const char *data, + virtual int put_obj_data(std::string& id, std::string& bucket, std::string& obj, std::string& loc, const char *data, off_t ofs, size_t len, time_t *mtime) = 0; - int put_obj(std::string& id, std::string& bucket, std::string& obj, const char *data, size_t len, + int put_obj(std::string& id, std::string& bucket, std::string& obj, std::string& loc, const char *data, size_t len, time_t *mtime, map& attrs) { - int ret = put_obj_meta(id, bucket, obj, NULL, attrs, false); + int ret = put_obj_meta(id, bucket, obj, loc, NULL, attrs, false); if (ret >= 0) { - ret = put_obj_data(id, bucket, obj, data, -1, len, mtime); + ret = put_obj_data(id, bucket, obj, loc, data, -1, len, mtime); } return ret; } @@ -121,7 +121,7 @@ public: * (if get_data==true) length of read data, * (if get_data==false) length of the object */ - virtual int prepare_get_obj(std::string& bucket, std::string& obj, + virtual int prepare_get_obj(std::string& bucket, std::string& obj, std::string& loc, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -133,7 +133,7 @@ public: void **handle, struct rgw_err *err) = 0; - virtual int get_obj(void **handle, std::string& bucket, std::string& oid, + virtual int get_obj(void **handle, std::string& bucket, std::string& oid, std::string& loc, char **data, off_t ofs, off_t end) = 0; virtual void finish_get_obj(void **handle) = 0; @@ -151,7 +151,7 @@ public: * dest: bufferlist to store the result in * Returns: 0 on success, -ERR# otherwise. */ - virtual int get_attr(std::string& bucket, std::string& obj, + virtual int get_attr(std::string& bucket, std::string& obj, std::string& loc, const char *name, bufferlist& dest) = 0; /** * Set an attr on an object. diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 381a7cb678394..ed54e0d9eba14 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -549,7 +549,7 @@ int main(int argc, char **argv) object = ""; string bucket_str(bucket); string object_str(object); - int ret = store->get_attr(bucket_str, object_str, + int ret = store->get_attr(bucket_str, object_str, object_str, RGW_ATTR_ACL, bl); RGWAccessControlPolicy policy; diff --git a/src/rgw/rgw_fs.cc b/src/rgw/rgw_fs.cc index c20a0e8fa36fd..9dbb3949b2473 100644 --- a/src/rgw/rgw_fs.cc +++ b/src/rgw/rgw_fs.cc @@ -185,7 +185,7 @@ int RGWFS::create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive) { int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1; @@ -230,7 +230,7 @@ done_err: return -errno; } -int RGWFS::put_obj_data(std::string& id, std::string& bucket, std::string& obj, const char *data, +int RGWFS::put_obj_data(std::string& id, std::string& bucket, std::string& obj, std::string& loc, const char *data, off_t ofs, size_t size, time_t *mtime) { int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1; @@ -295,13 +295,13 @@ int RGWFS::copy_obj(std::string& id, std::string& dest_bucket, std::string& dest time_t lastmod; map attrset; - ret = prepare_get_obj(src_bucket, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod, + ret = prepare_get_obj(src_bucket, src_obj, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &handle, err); if (ret < 0) return ret; do { - ret = get_obj(&handle, src_bucket, src_obj, &data, ofs, end); + ret = get_obj(&handle, src_bucket, src_obj, src_obj, &data, ofs, end); if (ret < 0) return ret; ofs += ret; @@ -313,7 +313,7 @@ int RGWFS::copy_obj(std::string& id, std::string& dest_bucket, std::string& dest } attrs = attrset; - ret = put_obj(id, dest_bucket, dest_obj, data, ret, mtime, attrs); + ret = put_obj(id, dest_bucket, dest_obj, dest_obj, data, ret, mtime, attrs); return ret; } @@ -397,7 +397,7 @@ int RGWFS::get_attr(const char *name, const char *path, char **attr) return attr_len; } -int RGWFS::get_attr(std::string& bucket, std::string& obj, +int RGWFS::get_attr(std::string& bucket, std::string& obj, std::string& loc, const char *name, bufferlist& dest) { int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1; @@ -434,7 +434,7 @@ int RGWFS::set_attr(std::string& bucket, std::string& obj, return ret; } -int RGWFS::prepare_get_obj(std::string& bucket, std::string& obj, +int RGWFS::prepare_get_obj(std::string& bucket, std::string& obj, std::string& loc, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -536,7 +536,7 @@ done_err: return r; } -int RGWFS::get_obj(void **handle, std::string& bucket, std::string& obj, +int RGWFS::get_obj(void **handle, std::string& bucket, std::string& obj, std::string& loc, char **data, off_t ofs, off_t end) { uint64_t len; diff --git a/src/rgw/rgw_fs.h b/src/rgw/rgw_fs.h index 1120f5d7012fc..f4b37c57ac75e 100644 --- a/src/rgw/rgw_fs.h +++ b/src/rgw/rgw_fs.h @@ -19,9 +19,9 @@ public: bool get_content_type); int create_bucket(std::string& id, std::string& bucket, map& attrs, uint64_t auid=0); - int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, time_t *mtime, + int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, std::string& loc, time_t *mtime, map& attrs, bool exclusive); - int put_obj_data(std::string& id, std::string& bucket, std::string& obj, const char *data, + int put_obj_data(std::string& id, std::string& bucket, std::string& obj, std::string& loc, const char *data, off_t ofs, size_t size, time_t *mtime); int copy_obj(std::string& id, std::string& dest_bucket, std::string& dest_obj, std::string& src_bucket, std::string& src_obj, @@ -37,12 +37,12 @@ public: int get_attr(const char *name, int fd, char **attr); int get_attr(const char *name, const char *path, char **attr); - int get_attr(std::string& bucket, std::string& obj, + int get_attr(std::string& bucket, std::string& obj, std::string& loc, const char *name, bufferlist& dest); int set_attr(std::string& bucket, std::string& obj, const char *name, bufferlist& bl); - int prepare_get_obj(std::string& bucket, std::string& obj, + int prepare_get_obj(std::string& bucket, std::string& obj, std::string& loc, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -54,7 +54,7 @@ public: void **handle, struct rgw_err *err); - int get_obj(void **handle, std::string& bucket, std::string& obj, + int get_obj(void **handle, std::string& bucket, std::string& obj, std::string& loc, char **data, off_t ofs, off_t end); void finish_get_obj(void **handle); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index ad1d3890c1e87..99e2813e861ce 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -84,13 +84,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, string& bucket, string& object) +static int get_policy_from_attr(RGWAccessControlPolicy *policy, string& bucket, string& object, string& loc) { bufferlist bl; int ret = 0; if (bucket.size()) { - ret = rgwstore->get_attr(bucket, object, + ret = rgwstore->get_attr(bucket, object, loc, RGW_ATTR_ACL, bl); if (ret >= 0) { @@ -111,19 +111,20 @@ int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, string& bucke { string upload_id = s->args.get("uploadId"); string obj = object; + string loc = object; if (!obj.empty() && !upload_id.empty()) { obj.append("."); obj.append(upload_id); } - int ret = get_policy_from_attr(policy, bucket, obj); + int ret = get_policy_from_attr(policy, bucket, obj, loc); 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; - ret = get_policy_from_attr(&bucket_policy, bucket, no_object); + ret = get_policy_from_attr(&bucket_policy, bucket, no_object, no_object); if (ret < 0) return ret; @@ -180,7 +181,7 @@ void RGWGetObj::execute() init_common(); - ret = rgwstore->prepare_get_obj(s->bucket_str, s->object_str, ofs, &end, &attrs, mod_ptr, + ret = rgwstore->prepare_get_obj(s->bucket_str, s->object_str, s->object_str, ofs, &end, &attrs, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &handle, &s->err); if (ret < 0) goto done; @@ -191,7 +192,7 @@ void RGWGetObj::execute() goto done; while (ofs <= end) { - ret = rgwstore->get_obj(&handle, s->bucket_str, s->object_str, &data, ofs, end); + ret = rgwstore->get_obj(&handle, s->bucket_str, s->object_str, s->object_str, &data, ofs, end); if (ret < 0) { goto done; } @@ -319,7 +320,7 @@ void RGWCreateBucket::execute() bool existed; bool pol_ret; - int r = get_policy_from_attr(&old_policy, rgw_root_bucket, s->bucket_str); + int r = get_policy_from_attr(&old_policy, rgw_root_bucket, s->bucket_str, s->bucket_str); if (r >= 0) { if (old_policy.get_owner().get_id().compare(s->user.user_id) != 0) { ret = -EEXIST; @@ -447,7 +448,7 @@ void RGWPutObj::execute() // For the first call to put_obj_data, pass -1 as the offset to // do a write_full. ret = rgwstore->put_obj_data(s->user.user_id, s->bucket_str, - obj, data, + obj, s->object_str, data, ((ofs == 0) ? -1 : ofs), len, NULL); free(data); if (ret < 0) @@ -484,7 +485,7 @@ void RGWPutObj::execute() get_request_metadata(s, attrs); - ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, obj, NULL, attrs, false); + ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, obj, s->object_str, NULL, attrs, false); if (ret < 0) goto done; @@ -502,7 +503,7 @@ void RGWPutObj::execute() RGW_LOG(0) << "JJJ name=" << p << "bl.length()=" << bl.length() << dendl; meta_attrs[p] = bl; - ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, multipart_meta_obj, NULL, meta_attrs, false); + ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, multipart_meta_obj, s->object_str, NULL, meta_attrs, false); } } done: @@ -866,7 +867,7 @@ void RGWInitMultipart::execute() tmp_obj_name.append("."); tmp_obj_name.append(upload_id); - ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, tmp_obj_name, NULL, attrs, true); + ret = rgwstore->put_obj_meta(s->user.user_id, s->bucket_str, tmp_obj_name, s->object_str, NULL, attrs, true); } while (ret == -EEXIST); done: send_response(); @@ -879,7 +880,7 @@ static int get_multiparts_info(struct req_state *s, string& obj, map attrs; map::iterator iter; - int ret = rgwstore->prepare_get_obj(s->bucket_str, obj, 0, NULL, &attrs, NULL, + int ret = rgwstore->prepare_get_obj(s->bucket_str, obj, s->object_str, 0, NULL, &attrs, NULL, NULL, NULL, NULL, NULL, NULL, &handle, &s->err); rgwstore->finish_get_obj(&handle); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 888eb48fce7f3..3315dd065c0d5 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -256,7 +256,7 @@ int RGWRados::create_bucket(std::string& id, std::string& bucket, map& attrs, bool exclusive) { librados::IoCtx io_ctx; @@ -265,6 +265,8 @@ int RGWRados::put_obj_meta(std::string& id, std::string& bucket, std::string& oi if (r < 0) return r; + io_ctx.locator_set_key(loc); + if (exclusive) { r = io_ctx.create(oid, true); if (r < 0) @@ -305,7 +307,7 @@ int RGWRados::put_obj_meta(std::string& id, std::string& bucket, std::string& oi * 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, std::string& bucket, std::string& oid, +int RGWRados::put_obj_data(std::string& id, std::string& bucket, std::string& oid, std::string& loc, const char *data, off_t ofs, size_t len, time_t *mtime) { librados::IoCtx io_ctx; @@ -314,6 +316,8 @@ int RGWRados::put_obj_data(std::string& id, std::string& bucket, std::string& oi if (r < 0) return r; + io_ctx.locator_set_key(loc); + bufferlist bl; bl.append(data, len); if (ofs == -1) { @@ -371,7 +375,7 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d void *handle = NULL; map attrset; - ret = prepare_get_obj(src_bucket, src_obj, 0, &end, &attrset, + ret = prepare_get_obj(src_bucket, src_obj, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &handle, err); if (ret < 0) @@ -379,13 +383,13 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d off_t ofs = 0; do { - ret = get_obj(&handle, src_bucket, src_obj, &data, ofs, end); + ret = get_obj(&handle, src_bucket, src_obj, 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, dest_bucket, dest_obj, data, + r = put_obj_data(id, dest_bucket, dest_obj, dest_obj, data, ((ofs == 0) ? -1 : ofs), ret, NULL); free(data); if (r < 0) @@ -399,7 +403,7 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d } attrs = attrset; - ret = put_obj_meta(id, dest_bucket, dest_obj, mtime, attrs, false); + ret = put_obj_meta(id, dest_bucket, dest_obj, dest_obj, mtime, attrs, false); finish_get_obj(&handle); @@ -472,7 +476,7 @@ int RGWRados::delete_obj(std::string& id, std::string& bucket, std::string& oid) * dest: bufferlist to store the result in * Returns: 0 on success, -ERR# otherwise. */ -int RGWRados::get_attr(std::string& bucket, std::string& obj, +int RGWRados::get_attr(std::string& bucket, std::string& obj, std::string& loc, const char *name, bufferlist& dest) { librados::IoCtx io_ctx; @@ -488,6 +492,8 @@ int RGWRados::get_attr(std::string& bucket, std::string& obj, if (r < 0) return r; + io_ctx.locator_set_key(loc); + r = io_ctx.getxattr(actual_obj, name, dest); if (r < 0) return r; @@ -549,7 +555,7 @@ int RGWRados::set_attr(std::string& bucket, std::string& oid, * (if get_data==true) length of read data, * (if get_data==false) length of the object */ -int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid, +int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid, std::string& loc, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -581,6 +587,8 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid, if (r < 0) goto done_err; + state->io_ctx.locator_set_key(loc); + if (total_size || end) { r = state->io_ctx.stat(oid, &size, &mtime); if (r < 0) @@ -621,7 +629,7 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid, } } if (if_match || if_nomatch) { - r = get_attr(bucket, oid, RGW_ATTR_ETAG, etag); + r = get_attr(bucket, oid, loc, RGW_ATTR_ETAG, etag); if (r < 0) goto done_err; @@ -662,7 +670,7 @@ done_err: } int RGWRados::get_obj(void **handle, - std::string& bucket, std::string& oid, + std::string& bucket, std::string& oid, string& loc, char **data, off_t ofs, off_t end) { uint64_t len; @@ -678,6 +686,8 @@ int RGWRados::get_obj(void **handle, if (len > RGW_MAX_CHUNK_SIZE) len = RGW_MAX_CHUNK_SIZE; + state->io_ctx.locator_set_key(loc); + RGW_LOG(20) << "rados->read ofs=" << ofs << " len=" << len << dendl; int r = state->io_ctx.read(oid, bl, len, ofs); RGW_LOG(20) << "rados->read r=" << r << dendl; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 05933931f9a7f..f82d347c420e4 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -42,9 +42,9 @@ public: virtual int create_bucket(std::string& id, std::string& bucket, map& attrs, uint64_t auid=0); /** Write/overwrite an object to the bucket storage. */ - virtual int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, time_t *mtime, + virtual int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, std::string& loc, time_t *mtime, map& attrs, bool exclusive); - virtual int put_obj_data(std::string& id, std::string& bucket, std::string& obj, const char *data, + virtual int put_obj_data(std::string& id, std::string& bucket, std::string& obj, std::string& loc, const char *data, off_t ofs, size_t len, time_t *mtime); /** Copy an object, with many extra options */ virtual int copy_obj(std::string& id, std::string& dest_bucket, std::string& dest_obj, @@ -63,7 +63,7 @@ public: virtual int delete_obj(std::string& id, std::string& bucket, std::string& obj); /** Get the attributes for an object.*/ - virtual int get_attr(std::string& bucket, std::string& obj, + virtual int get_attr(std::string& bucket, std::string& obj, std::string& loc, const char *name, bufferlist& dest); /** Set an attr on an object. */ @@ -71,7 +71,7 @@ public: const char *name, bufferlist& bl); /** Get data about an object out of RADOS and into memory. */ - virtual int prepare_get_obj(std::string& bucket, std::string& obj, + virtual int prepare_get_obj(std::string& bucket, std::string& obj, std::string& loc, off_t ofs, off_t *end, map *attrs, const time_t *mod_ptr, @@ -83,7 +83,7 @@ public: void **handle, struct rgw_err *err); - virtual int get_obj(void **handle, std::string& bucket, std::string& oid, + virtual int get_obj(void **handle, std::string& bucket, std::string& oid, std::string& loc, char **data, off_t ofs, off_t end); virtual void finish_get_obj(void **handle); diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 85c690265d811..45cda0d12e06c 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -35,12 +35,12 @@ static int put_obj(string& uid, string& bucket, string& oid, const char *data, s { map attrs; - int ret = rgwstore->put_obj(uid, bucket, oid, data, size, NULL, attrs); + int ret = rgwstore->put_obj(uid, bucket, oid, oid, data, size, NULL, attrs); if (ret == -ENOENT) { ret = rgwstore->create_bucket(uid, bucket, attrs); if (ret >= 0) - ret = rgwstore->put_obj(uid, bucket, oid, data, size, NULL, attrs); + ret = rgwstore->put_obj(uid, bucket, oid, oid, data, size, NULL, attrs); } return ret; @@ -124,13 +124,13 @@ int rgw_get_user_info_from_index(string& key, string& bucket, RGWUserInfo& info) void *handle = NULL; bufferlist::iterator iter; int request_len = READ_CHUNK_LEN; - ret = rgwstore->prepare_get_obj(bucket, key, 0, NULL, NULL, NULL, + ret = rgwstore->prepare_get_obj(bucket, key, key, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &handle, &err); if (ret < 0) return ret; do { - ret = rgwstore->get_obj(&handle, bucket, key, &data, 0, request_len - 1); + ret = rgwstore->get_obj(&handle, bucket, key, key, &data, 0, request_len - 1); if (ret < 0) goto done; if (ret < request_len) @@ -198,7 +198,7 @@ static void get_buckets_obj(string& user_id, string& buckets_obj_id) static int rgw_read_buckets_from_attr(string& user_id, RGWUserBuckets& buckets) { bufferlist bl; - int ret = rgwstore->get_attr(ui_uid_bucket, user_id, RGW_ATTR_BUCKETS, bl); + int ret = rgwstore->get_attr(ui_uid_bucket, user_id, user_id, RGW_ATTR_BUCKETS, bl); if (ret) return ret; -- 2.39.5