From be6d5636534ffa6e9badca7ddb7d73ad01663f48 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 24 Oct 2012 12:56:59 -0700 Subject: [PATCH] rgw: don't reset multipart parts when updating their metadata Fixes: #3401 The problem was that put_obj_meta() was assuming object is going to be reset, so it was resetting the object anyway. This is not true when dealing with the immutable multipart upload parts. Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_op.cc | 12 ++++++------ src/rgw/rgw_rados.cc | 17 ++++++++++------- src/rgw/rgw_rados.h | 12 ++++++++++-- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f227aa3208c05..05038bfa9899c 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -912,7 +912,7 @@ int RGWPutObjProcessor_Plain::handle_data(bufferlist& bl, off_t _ofs, void **pha int RGWPutObjProcessor_Plain::complete(string& etag, map& attrs) { int r = store->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs, - RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL, NULL); + RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, &data, NULL, NULL); return r; } @@ -1075,7 +1075,7 @@ int RGWPutObjProcessor_Atomic::complete(string& etag, map& a store->set_atomic(s->obj_ctx, head_obj); int r = store->put_obj_meta(s->obj_ctx, head_obj, obj_len, NULL, attrs, - RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest, NULL); + RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, &first_chunk, &manifest, NULL); return r; } @@ -1113,7 +1113,7 @@ int RGWPutObjProcessor_Multipart::prepare(RGWRados *store, struct req_state *s) int RGWPutObjProcessor_Multipart::complete(string& etag, map& attrs) { - int r = store->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL); + int r = store->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, 0, NULL, NULL, NULL, NULL); if (r < 0) return r; @@ -1656,7 +1656,7 @@ void RGWInitMultipart::execute() obj.init_ns(s->bucket, tmp_obj_name, mp_ns); // the meta object will be indexed with 0 size, we c - ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL, NULL); + ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL, NULL, NULL, NULL, NULL); } while (ret == -EEXIST); } @@ -1821,7 +1821,7 @@ void RGWCompleteMultipart::execute() target_obj.init(s->bucket, s->object_str); store->set_atomic(s->obj_ctx, target_obj); - ret = store->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL); + ret = store->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, NULL, NULL, NULL); if (ret < 0) return; @@ -1844,7 +1844,7 @@ void RGWCompleteMultipart::execute() store->set_atomic(s->obj_ctx, target_obj); ret = store->put_obj_meta(s->obj_ctx, target_obj, ofs, NULL, attrs, - RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest, NULL); + RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, NULL, &manifest, NULL); if (ret < 0) return; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 583992def6ea0..b468b6f042f59 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -999,7 +999,7 @@ int RGWRados::create_pools(vector& names, vector& retcodes) */ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime, map& attrs, - RGWObjCategory category, bool exclusive, + RGWObjCategory category, int flags, map* rmattrs, const bufferlist *data, RGWObjManifest *manifest, @@ -1022,12 +1022,15 @@ int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, RGWObjState *state = NULL; - if (!exclusive) { - r = prepare_atomic_for_write(rctx, obj, op, &state, true, ptag); + if (flags & PUT_OBJ_EXCL) { + if (!(flags & PUT_OBJ_CREATE)) + return -EINVAL; + op.create(true); // exclusive create + } else { + bool reset_obj = (flags & PUT_OBJ_CREATE) != 0; + r = prepare_atomic_for_write(rctx, obj, op, &state, reset_obj, ptag); if (r < 0) return r; - } else { - op.create(true); // exclusive create } if (data) { @@ -1323,7 +1326,7 @@ int RGWRados::copy_obj(void *ctx, manifest.obj_size = total_len; - ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest, &tag); + ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, PUT_OBJ_CREATE, NULL, &first_chunk, &manifest, &tag); if (mtime) obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL); @@ -1412,7 +1415,7 @@ int RGWRados::copy_obj_data(void *ctx, } manifest.obj_size = ofs; - ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest, NULL); + ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, PUT_OBJ_CREATE, NULL, &first_chunk, &manifest, NULL); if (mtime) obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 4a932224a9211..101ce7db2a2e3 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -12,6 +12,11 @@ class SafeTimer; class ACLOwner; class RGWGC; +/* flags for put_obj_meta() */ +#define PUT_OBJ_CREATE 0x01 +#define PUT_OBJ_EXCL 0x02 +#define PUT_OBJ_CREATE_EXCL (PUT_OBJ_CREATE | PUT_OBJ_EXCL) + static inline void prepend_bucket_marker(rgw_bucket& bucket, string& orig_oid, string& oid) { if (bucket.marker.empty() || orig_oid.empty()) { @@ -413,7 +418,7 @@ public: /** Write/overwrite an object to the bucket storage. */ virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime, - map& attrs, RGWObjCategory category, bool exclusive, + map& attrs, RGWObjCategory category, int flags, map* rmattrs, const bufferlist *data, RGWObjManifest *manifest, const string *ptag); virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data, @@ -425,7 +430,10 @@ public: time_t *mtime, map& attrs) { bufferlist bl; bl.append(data, len); - int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, exclusive, NULL, &bl, NULL, NULL); + int flags = PUT_OBJ_CREATE; + if (exclusive) + flags |= PUT_OBJ_EXCL; + int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, flags, NULL, &bl, NULL, NULL); return ret; } virtual int aio_wait(void *handle); -- 2.39.5