From 4ac04e8978315859c31b383888330609aafed061 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 23 Dec 2011 12:46:05 -0800 Subject: [PATCH] rgw: write bucket info in one operation --- src/rgw/rgw_access.h | 12 ++++++------ src/rgw/rgw_admin.cc | 8 ++++---- src/rgw/rgw_fs.cc | 6 +++--- src/rgw/rgw_fs.h | 4 ++-- src/rgw/rgw_op.cc | 2 +- src/rgw/rgw_rados.cc | 41 +++++++++++++++++++++++------------------ src/rgw/rgw_rados.h | 8 ++++---- src/rgw/rgw_tools.cc | 6 +++--- src/rgw/rgw_tools.h | 2 +- src/rgw/rgw_user.cc | 10 +++++----- src/rgw/rgw_user.h | 2 +- 11 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/rgw/rgw_access.h b/src/rgw/rgw_access.h index 071fba65a1b34..e0928c1f58b19 100644 --- a/src/rgw/rgw_access.h +++ b/src/rgw/rgw_access.h @@ -74,15 +74,15 @@ public: map& attrs, RGWObjCategory category, bool exclusive, map* rmattrs) = 0; virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data, - off_t ofs, size_t len) = 0; + off_t ofs, size_t len, bool exclusive) = 0; virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, const char *data, - off_t ofs, size_t len, void **handle) { return -ENOTSUP; } + off_t ofs, size_t len, bool exclusive, void **handle) { return -ENOTSUP; } /* note that put_obj doesn't set category on an object, only use it for none user objects */ - int put_obj(void *ctx, rgw_obj& obj, const char *data, size_t len, + int put_obj(void *ctx, rgw_obj& obj, const char *data, size_t len, bool exclusive, time_t *mtime, map& attrs) { - int ret = put_obj_data(ctx, obj, data, -1, len); - if (ret >= 0) { + int ret = put_obj_data(ctx, obj, data, -1, len, exclusive); + if (ret >= 0 && (attrs.size() || mtime)) { ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false, NULL); } return ret; @@ -265,7 +265,7 @@ public: /* The bucket here can either be the bucket name identifier, or the ID * in period format: ".123" */ virtual int get_bucket_info(void *ctx, string& bucket, RGWBucketInfo& info) = 0; - virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info) = 0; + virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive) = 0; virtual int remove_temp_objects(string date, string time) { diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index c0377dc70375a..8582e0ab56fbc 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -835,7 +835,7 @@ int main(int argc, char **argv) info.subusers[subuser] = u; } - if ((err = rgw_store_user_info(info)) < 0) { + if ((err = rgw_store_user_info(info, false)) < 0) { cerr << "error storing user info: " << cpp_strerror(-err) << std::endl; break; } @@ -861,7 +861,7 @@ int main(int argc, char **argv) keys_map->erase(kiter); } } - if ((err = rgw_store_user_info(info)) < 0) { + if ((err = rgw_store_user_info(info, false)) < 0) { cerr << "error storing user info: " << cpp_strerror(-err) << std::endl; break; } @@ -885,7 +885,7 @@ int main(int argc, char **argv) } else { rgw_remove_key_index(kiter->second); keys_map->erase(kiter); - if ((err = rgw_store_user_info(info)) < 0) { + if ((err = rgw_store_user_info(info, false)) < 0) { cerr << "error storing user info: " << cpp_strerror(-err) << std::endl; break; } @@ -1261,7 +1261,7 @@ next: int ret; info.suspended = disable; - ret = rgw_store_user_info(info); + ret = rgw_store_user_info(info, false); if (ret < 0) { cerr << "ERROR: failed to store user info user=" << user_id << " ret=" << ret << std::endl; return 1; diff --git a/src/rgw/rgw_fs.cc b/src/rgw/rgw_fs.cc index 21b82f6568039..3fbed040338ad 100644 --- a/src/rgw/rgw_fs.cc +++ b/src/rgw/rgw_fs.cc @@ -254,7 +254,7 @@ done_err: } int RGWFS::put_obj_data(void *ctx, rgw_obj& obj, const char *data, - off_t ofs, size_t size) + off_t ofs, size_t size, bool exclusive) { rgw_bucket& bucket = obj.bucket; std::string& oid = obj.object; @@ -331,7 +331,7 @@ int RGWFS::copy_obj(void *ctx, rgw_obj& dest_obj, } attrs = attrset; - ret = put_obj(ctx, dest_obj, data, ret, mtime, attrs); + ret = put_obj(ctx, dest_obj, data, ret, false, mtime, attrs); return ret; } @@ -694,7 +694,7 @@ int RGWFS::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info) return -ENOTSUP; } -int RGWFS::put_bucket_info(string& bucket_name, RGWBucketInfo& info) +int RGWFS::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive) { return -ENOTSUP; } diff --git a/src/rgw/rgw_fs.h b/src/rgw/rgw_fs.h index 96ea95c3d35d3..c78d53035e02a 100644 --- a/src/rgw/rgw_fs.h +++ b/src/rgw/rgw_fs.h @@ -23,7 +23,7 @@ public: map& attrs, RGWObjCategory category, bool exclusive, map *rmattrs); int put_obj_data(void *ctx, rgw_obj& obj, const char *data, - off_t ofs, size_t size); + off_t ofs, size_t size, bool exclusive); int copy_obj(void *ctx, rgw_obj& dest_obj, rgw_obj& src_obj, time_t *mtime, @@ -63,7 +63,7 @@ public: int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map *attrs); virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info); - virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info); + virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive); }; #endif diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 12fd5aa0478ac..fd18d0933305c 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -738,7 +738,7 @@ void RGWPutObj::execute() void *handle; ret = rgwstore->aio_put_obj_data(s->obj_ctx, obj, data, - ((ofs == 0) ? -1 : ofs), len, &handle); + ((ofs == 0) ? -1 : ofs), len, false, &handle); if (ret < 0) goto done_err; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index c960af5fc0690..69057456cf4ff 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -474,7 +474,7 @@ int RGWRados::create_bucket(string& owner, rgw_bucket& bucket, RGWBucketInfo info; info.bucket = bucket; info.owner = owner; - ret = store_bucket_info(info); + ret = store_bucket_info(info, exclusive); if (ret < 0) { dout(0) << "failed to store bucket info, removing bucket" << dendl; delete_bucket(bucket); @@ -486,19 +486,23 @@ int RGWRados::create_bucket(string& owner, rgw_bucket& bucket, return ret; } -int RGWRados::store_bucket_info(RGWBucketInfo& info) +int RGWRados::store_bucket_info(RGWBucketInfo& info, bool exclusive) { bufferlist bl; ::encode(info, bl); - int ret = rgw_put_obj(info.owner, pi_buckets_rados, info.bucket.name, bl.c_str(), bl.length()); + int ret = rgw_put_obj(info.owner, pi_buckets_rados, info.bucket.name, bl.c_str(), bl.length(), exclusive); if (ret < 0) return ret; char bucket_char[16]; snprintf(bucket_char, sizeof(bucket_char), ".%lld", (long long unsigned)info.bucket.bucket_id); string bucket_id_string(bucket_char); - ret = rgw_put_obj(info.owner, pi_buckets_rados, bucket_id_string, bl.c_str(), bl.length()); + ret = rgw_put_obj(info.owner, pi_buckets_rados, bucket_id_string, bl.c_str(), bl.length(), false); + if (ret < 0) { + dout(0) << "ERROR: failed to store " << pi_buckets_rados << ":" << bucket_id_string << " ret=" << ret << dendl; + return ret; + } dout(0) << "store_bucket_info: bucket=" << info.bucket << " owner " << info.owner << dendl; return 0; @@ -692,17 +696,17 @@ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, * Returns: 0 on success, -ERR# otherwise. */ int RGWRados::put_obj_data(void *ctx, rgw_obj& obj, - const char *data, off_t ofs, size_t len) + const char *data, off_t ofs, size_t len, bool exclusive) { void *handle; - int r = aio_put_obj_data(ctx, obj, data, ofs, len, &handle); + int r = aio_put_obj_data(ctx, obj, data, ofs, len, exclusive, &handle); if (r < 0) return r; return aio_wait(handle); } int RGWRados::aio_put_obj_data(void *ctx, rgw_obj& obj, - const char *data, off_t ofs, size_t len, + const char *data, off_t ofs, size_t len, bool exclusive, void **handle) { rgw_bucket bucket; @@ -722,16 +726,17 @@ int RGWRados::aio_put_obj_data(void *ctx, rgw_obj& obj, AioCompletion *c = librados::Rados::aio_create_completion(NULL, NULL, NULL); *handle = c; + ObjectWriteOperation op; - if (ofs == -1) { - // write_full wants to write the complete bufferlist, not part of it - assert(bl.length() == len); + if (exclusive) + op.create(true); - r = io_ctx.aio_write_full(oid, c, bl); - } - else { - r = io_ctx.aio_write(oid, c, bl, len, ofs); + if (ofs == -1) { + op.write_full(bl); + } else { + op.write(ofs, bl); } + r = io_ctx.aio_operate(oid, c, &op); if (r < 0) return r; @@ -810,7 +815,7 @@ int RGWRados::copy_obj(void *ctx, // 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(ctx, tmp_obj, data, ((ofs == 0) ? -1 : ofs), ret); + r = put_obj_data(ctx, tmp_obj, data, ((ofs == 0) ? -1 : ofs), ret, false); free(data); if (r < 0) goto done_err; @@ -908,7 +913,7 @@ int RGWRados::set_buckets_enabled(vector& buckets, bool enabled) info.flags |= BUCKET_SUSPENDED; } - r = put_bucket_info(bucket.name, info); + r = put_bucket_info(bucket.name, info, false); if (r < 0) { dout(0) << "put_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl; ret = r; @@ -1816,7 +1821,7 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf return 0; } -int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info) +int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive) { bufferlist bl; @@ -1824,7 +1829,7 @@ int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info) string unused; - int ret = rgw_put_obj(unused, pi_buckets_rados, bucket_name, bl.c_str(), bl.length()); + int ret = rgw_put_obj(unused, pi_buckets_rados, bucket_name, bl.c_str(), bl.length(), exclusive); return ret; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index a77d3fc099c4d..e33dcdf3e517c 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -134,7 +134,7 @@ class RGWRados : public RGWAccess int delete_obj_impl(void *ctx, rgw_obj& src_obj, bool sync); int select_bucket_placement(std::string& bucket_name, rgw_bucket& bucket); - int store_bucket_info(RGWBucketInfo& info); + int store_bucket_info(RGWBucketInfo& info, bool exclusive); public: RGWRados() : lock("rados_timer_lock"), timer(NULL), watcher(NULL), watch_handle(0) {} @@ -184,9 +184,9 @@ public: map& attrs, RGWObjCategory category, bool exclusive, map* rmattrs); virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data, - off_t ofs, size_t len); + off_t ofs, size_t len, bool exclusive); virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, const char *data, - off_t ofs, size_t len, void **handle); + off_t ofs, size_t len, bool exclusive, void **handle); virtual int aio_wait(void *handle); virtual bool aio_completed(void *handle); virtual int clone_objs(void *ctx, rgw_obj& dst_obj, @@ -307,7 +307,7 @@ public: int decode_policy(bufferlist& bl, ACLOwner *owner); int get_bucket_stats(rgw_bucket& bucket, map& stats); virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info); - virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info); + virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive); int cls_rgw_init_index(rgw_bucket& bucket, string& oid); int cls_obj_prepare_op(rgw_bucket& bucket, uint8_t op, string& tag, diff --git a/src/rgw/rgw_tools.cc b/src/rgw/rgw_tools.cc index eca5ce1f699f0..81f89eb2eec59 100644 --- a/src/rgw/rgw_tools.cc +++ b/src/rgw/rgw_tools.cc @@ -14,18 +14,18 @@ static map ext_mime_map; -int rgw_put_obj(string& uid, rgw_bucket& bucket, string& oid, const char *data, size_t size) +int rgw_put_obj(string& uid, rgw_bucket& bucket, string& oid, const char *data, size_t size, bool exclusive) { map attrs; rgw_obj obj(bucket, oid); - int ret = rgwstore->put_obj(NULL, obj, data, size, NULL, attrs); + int ret = rgwstore->put_obj(NULL, obj, data, size, exclusive, NULL, attrs); if (ret == -ENOENT) { ret = rgwstore->create_bucket(uid, bucket, attrs, true); //all callers are using system buckets if (ret >= 0) - ret = rgwstore->put_obj(NULL, obj, data, size, NULL, attrs); + ret = rgwstore->put_obj(NULL, obj, data, size, exclusive, NULL, attrs); } return ret; diff --git a/src/rgw/rgw_tools.h b/src/rgw/rgw_tools.h index 5174d419c7a63..c3230f859faf5 100644 --- a/src/rgw/rgw_tools.h +++ b/src/rgw/rgw_tools.h @@ -7,7 +7,7 @@ #include "rgw_common.h" -int rgw_put_obj(string& uid, rgw_bucket& bucket, string& oid, const char *data, size_t size); +int rgw_put_obj(string& uid, rgw_bucket& bucket, string& oid, const char *data, size_t size, bool exclusive); int rgw_get_obj(void *ctx, rgw_bucket& bucket, string& key, bufferlist& bl); int rgw_tools_init(CephContext *cct); diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 6430092b1ad86..6088834f0aac3 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -40,7 +40,7 @@ bool rgw_user_is_authenticated(RGWUserInfo& info) * Save the given user information to storage. * Returns: 0 on success, -ERR# on failure. */ -int rgw_store_user_info(RGWUserInfo& info) +int rgw_store_user_info(RGWUserInfo& info, bool exclusive) { bufferlist bl; info.encode(bl); @@ -80,12 +80,12 @@ int rgw_store_user_info(RGWUserInfo& info) ::encode(ui, uid_bl); ::encode(info, uid_bl); - ret = rgw_put_obj(info.user_id, ui_uid_bucket, info.user_id, uid_bl.c_str(), uid_bl.length()); + ret = rgw_put_obj(info.user_id, ui_uid_bucket, info.user_id, uid_bl.c_str(), uid_bl.length(), exclusive); if (ret < 0) return ret; if (info.user_email.size()) { - ret = rgw_put_obj(info.user_id, ui_email_bucket, info.user_email, uid_bl.c_str(), uid_bl.length()); + ret = rgw_put_obj(info.user_id, ui_email_bucket, info.user_email, uid_bl.c_str(), uid_bl.length(), exclusive); if (ret < 0) return ret; } @@ -94,7 +94,7 @@ int rgw_store_user_info(RGWUserInfo& info) map::iterator iter = info.access_keys.begin(); for (; iter != info.access_keys.end(); ++iter) { RGWAccessKey& k = iter->second; - ret = rgw_put_obj(k.id, ui_key_bucket, k.id, uid_bl.c_str(), uid_bl.length()); + ret = rgw_put_obj(k.id, ui_key_bucket, k.id, uid_bl.c_str(), uid_bl.length(), exclusive); if (ret < 0) return ret; } @@ -103,7 +103,7 @@ int rgw_store_user_info(RGWUserInfo& info) map::iterator siter; for (siter = info.swift_keys.begin(); siter != info.swift_keys.end(); ++siter) { RGWAccessKey& k = siter->second; - ret = rgw_put_obj(info.user_id, ui_swift_bucket, k.id, uid_bl.c_str(), uid_bl.length()); + ret = rgw_put_obj(info.user_id, ui_swift_bucket, k.id, uid_bl.c_str(), uid_bl.length(), exclusive); if (ret < 0) return ret; } diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h index 51294d0597091..6c2cb807cd219 100644 --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@ -44,7 +44,7 @@ extern bool rgw_user_is_authenticated(RGWUserInfo& info); * Save the given user information to storage. * Returns: 0 on success, -ERR# on failure. */ -extern int rgw_store_user_info(RGWUserInfo& info); +extern int rgw_store_user_info(RGWUserInfo& info, bool exclusive); /** * Given an email, finds the user info associated with it. * returns: 0 on success, -ERR# on failure (including nonexistence) -- 2.39.5