if (r < 0)
return r;
- obj_ctx.set_atomic(head_obj);
+ obj_ctx.obj.set_atomic(head_obj);
RGWRados::Object op_target(store, bucket_info, obj_ctx, head_obj);
}
};
-RGWObjState *RGWObjectCtx::get_state(rgw_obj& obj) {
- RGWObjState *result;
- map<rgw_obj, RGWObjState>::iterator iter;
- lock.get_read();
- assert (!obj.get_object().empty());
- iter = objs_state.find(obj);
- if (iter != objs_state.end()) {
- result = &iter->second;
- lock.unlock();
- } else {
- lock.unlock();
- lock.get_write();
- result = &objs_state[obj];
- lock.unlock();
- }
- return result;
-}
-
-void RGWObjectCtx::invalidate(rgw_obj& obj)
-{
- RWLock::WLocker wl(lock);
- auto iter = objs_state.find(obj);
- if (iter == objs_state.end()) {
- return;
- }
- bool is_atomic = iter->second.is_atomic;
- bool prefetch_data = iter->second.prefetch_data;
-
- objs_state.erase(iter);
-
- auto& s = objs_state[obj];
- s.is_atomic = is_atomic;
- s.prefetch_data = prefetch_data;
-}
-
-void RGWObjectCtx::set_atomic(rgw_obj& obj) {
- RWLock::WLocker wl(lock);
- assert (!obj.get_object().empty());
- objs_state[obj].is_atomic = true;
-}
-
-void RGWObjectCtx::set_prefetch_data(rgw_obj& obj) {
- RWLock::WLocker wl(lock);
- assert (!obj.get_object().empty());
- objs_state[obj].prefetch_data = true;
-}
-
class RGWMetaNotifierManager : public RGWCoroutinesManager {
RGWRados *store;
RGWHTTPManager http_manager;
return 0;
}
+void RGWRados::obj_to_raw(const rgw_obj& obj, rgw_raw_obj *raw_obj)
+{
+ get_obj_bucket_and_oid_loc(obj, raw_obj->oid, raw_obj->loc);
+
+ if (!obj.is_in_extra_data()) {
+ raw_obj->pool = obj.bucket.placement.data_pool;
+ } else {
+ raw_obj->pool = obj.bucket.placement.get_data_extra_pool();
+ }
+}
int RGWRados::get_system_obj_ref(const rgw_raw_obj& obj, rgw_rados_ref *ref, rgw_pool *pool)
{
return get_raw_obj_ref(obj, ref, pool);
return 0;
}
- obj_ctx.set_atomic(obj);
+ obj_ctx.obj.set_atomic(obj);
RGWObjState * state = nullptr;
int r = get_obj_state(&obj_ctx, obj, &state, false);
}
rgw_obj dest_obj(dest_bucket_info.bucket, buf);
- obj_ctx.set_atomic(dest_obj);
+ obj_ctx.obj.set_atomic(dest_obj);
string no_zone;
std::map<std::string, ceph::bufferlist> no_attrs;
rgw_obj archive_obj(archive_binfo.bucket, entry.key);
- obj_ctx.set_atomic(archive_obj);
- obj_ctx.set_atomic(obj);
+ obj_ctx.obj.set_atomic(archive_obj);
+ obj_ctx.obj.set_atomic(obj);
int ret = copy_obj(obj_ctx,
user,
}
if (copy_if_newer && cb.is_canceled()) {
ldout(cct, 20) << "raced with another write of obj: " << dest_obj << dendl;
- obj_ctx.invalidate(dest_obj); /* object was overwritten */
+ obj_ctx.obj.invalidate(dest_obj); /* object was overwritten */
ret = get_obj_state(&obj_ctx, dest_obj, &dest_state, false);
if (ret < 0) {
ldout(cct, 0) << "ERROR: " << __func__ << ": get_err_state() returned ret=" << ret << dendl;
string oid, loc;
get_obj_bucket_and_oid_loc(mobj, oid, loc);
cls_rgw_obj_key key(oid);
- chain->push_obj(mobj.bucket.placement.data_pool, key, loc);
+ chain->push_obj(mobj.bucket.placement.data_pool.to_str(), key, loc);
}
}
return 0;
}
-int RGWRados::get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker)
+int RGWRados::get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawObjState **state, RGWObjVersionTracker *objv_tracker)
{
- RGWObjState *s = rctx->get_state(obj);
+ RGWRawObjState *s = rctx->raw.get_state(obj);
ldout(cct, 20) << "get_system_obj_state: rctx=" << (void *)rctx << " obj=" << obj << " state=" << (void *)s << " s->prefetch_data=" << s->prefetch_data << dendl;
*state = s;
if (s->has_attrs) {
return 0;
}
-int RGWRados::get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker)
+int RGWRados::get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawObjState **state, RGWObjVersionTracker *objv_tracker)
{
int ret;
{
bool need_follow_olh = follow_olh && !obj.have_instance();
- RGWObjState *s = rctx->get_state(obj);
+ RGWObjState *s = rctx->obj.get_state(obj);
ldout(cct, 20) << "get_obj_state: rctx=" << (void *)rctx << " obj=" << obj << " state=" << (void *)s << " s->prefetch_data=" << s->prefetch_data << dendl;
*state = s;
if (s->has_attrs) {
s->obj = obj;
+ rgw_raw_obj raw_obj;
+ obj_to_raw(obj, &raw_obj);
+
int r = -ENOENT;
if (!assume_noent) {
- r = RGWRados::raw_obj_stat(obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), NULL);
+ r = RGWRados::raw_obj_stat(raw_obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), NULL);
}
+
if (r == -ENOENT) {
s->exists = false;
s->has_attrs = true;
rgw_obj& obj = source->get_obj();
RGWRados *store = source->get_store();
- RGWObjState *s = ctx.get_state(obj); /* calling this one directly because otherwise a sync request will be sent */
+ RGWObjState *s = ctx.obj.get_state(obj); /* calling this one directly because otherwise a sync request will be sent */
result.obj = obj;
if (s->has_attrs) {
state.ret = 0;
void RGWRados::Object::invalidate_state()
{
- ctx.invalidate(obj);
+ ctx.obj.invalidate(obj);
}
int RGWRados::Object::prepare_atomic_modification(ObjectWriteOperation& op, bool reset_obj, const string *ptag,
return 0;
}
-int RGWRados::SystemObject::get_state(RGWObjState **pstate, RGWObjVersionTracker *objv_tracker)
+int RGWRados::SystemObject::get_state(RGWRawObjState **pstate, RGWObjVersionTracker *objv_tracker)
{
return store->get_system_obj_state(&ctx, obj, pstate, objv_tracker);
}
uint64_t *obj_size,
RGWObjVersionTracker *objv_tracker)
{
- RGWObjState *astate = NULL;
+ RGWRawObjState *astate = NULL;
int r = get_system_obj_state(&obj_ctx, obj, &astate, objv_tracker);
if (r < 0)
#define MAX_ECANCELED_RETRY 100
for (i = 0; i < MAX_ECANCELED_RETRY; i++) {
if (ret == -ECANCELED) {
- obj_ctx.invalidate(olh_obj);
+ obj_ctx.obj.invalidate(olh_obj);
}
ret = get_obj_state(&obj_ctx, olh_obj, &state, false); /* don't follow olh */
for (i = 0; i < MAX_ECANCELED_RETRY; i++) {
if (ret == -ECANCELED) {
- obj_ctx.invalidate(olh_obj);
+ obj_ctx.obj.invalidate(olh_obj);
}
ret = get_obj_state(&obj_ctx, olh_obj, &state, false); /* don't follow olh */
}
};
+struct RGWRawObjState {
+ rgw_raw_obj obj;
+ bool has_attrs{false};
+ bool exists{false};
+ uint64_t size{0};
+ ceph::real_time mtime;
+ uint64_t epoch;
+ bufferlist obj_tag;
+ bool has_data{false};
+ bufferlist data;
+ bool prefetch_data{false};
+ uint64_t pg_ver{0};
+
+ /* important! don't forget to update copy constructor */
+
+ RGWObjVersionTracker objv_tracker;
+
+ map<string, bufferlist> attrset;
+ RGWRawObjState() {}
+ RGWRawObjState(const RGWRawObjState& rhs) : obj (rhs.obj) {
+ has_attrs = rhs.has_attrs;
+ exists = rhs.exists;
+ size = rhs.size;
+ mtime = rhs.mtime;
+ epoch = rhs.epoch;
+ if (rhs.obj_tag.length()) {
+ obj_tag = rhs.obj_tag;
+ }
+ has_data = rhs.has_data;
+ if (rhs.data.length()) {
+ data = rhs.data;
+ }
+ prefetch_data = rhs.prefetch_data;
+ pg_ver = rhs.pg_ver;
+ objv_tracker = rhs.objv_tracker;
+ }
+};
+
struct RGWPoolIterCtx {
librados::IoCtx io_ctx;
librados::NObjectIterator iter;
};
};
-
-struct RGWObjectCtx {
+template <class T, class S>
+class RGWObjectCtxImpl {
RGWRados *store;
- map<rgw_obj, RGWObjState> objs_state;
+ std::map<T, S> objs_state;
RWLock lock;
+
+public:
+ RGWObjectCtxImpl(RGWRados *_store) : store(_store), lock("RGWObjectCtxImpl") {}
+
+ S *get_state(T& obj) {
+ S *result;
+ typename std::map<T, S>::iterator iter;
+ lock.get_read();
+ assert (!obj.empty());
+ iter = objs_state.find(obj);
+ if (iter != objs_state.end()) {
+ result = &iter->second;
+ lock.unlock();
+ } else {
+ lock.unlock();
+ lock.get_write();
+ result = &objs_state[obj];
+ lock.unlock();
+ }
+ return result;
+ }
+
+ void set_atomic(T& obj) {
+ RWLock::WLocker wl(lock);
+ assert (!obj.get_object().empty());
+ objs_state[obj].is_atomic = true;
+ }
+ void set_prefetch_data(T& obj) {
+ RWLock::WLocker wl(lock);
+ assert (!obj.get_object().empty());
+ objs_state[obj].prefetch_data = true;
+ }
+ void invalidate(T& obj) {
+ RWLock::WLocker wl(lock);
+ auto iter = objs_state.find(obj);
+ if (iter == objs_state.end()) {
+ return;
+ }
+ bool is_atomic = iter->second.is_atomic;
+ bool prefetch_data = iter->second.prefetch_data;
+
+ objs_state.erase(iter);
+
+ if (is_atomic || prefetch_data) {
+ auto& s = objs_state[obj];
+ s.is_atomic = is_atomic;
+ s.prefetch_data = prefetch_data;
+ }
+ }
+};
+
+struct RGWObjectCtx {
void *user_ctx;
- explicit RGWObjectCtx(RGWRados *_store) : store(_store), lock("RGWObjectCtx"), user_ctx(NULL) { }
- RGWObjectCtx(RGWRados *_store, void *_user_ctx) : store(_store), lock("RGWObjectCtx"), user_ctx(_user_ctx) { }
+ RGWObjectCtxImpl<rgw_obj, RGWObjState> obj;
+ RGWObjectCtxImpl<rgw_raw_obj, RGWRawObjState> raw;
- RGWObjState *get_state(rgw_obj& obj);
- void set_atomic(rgw_obj& obj);
- void set_prefetch_data(rgw_obj& obj);
- void invalidate(rgw_obj& obj);
+ explicit RGWObjectCtx(RGWRados *store) : user_ctx(NULL), obj(store), raw(store) { }
+ RGWObjectCtx(RGWRados *store, void *_user_ctx) : user_ctx(_user_ctx), obj(store), raw(store) { }
};
class Finisher;
int get_obj_ioctx(const rgw_obj& obj, librados::IoCtx *ioctx);
int get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_pool *pool);
int get_raw_obj_ref(const rgw_raw_obj& obj, rgw_rados_ref *ref, rgw_pool *pool);
+ void obj_to_raw(const rgw_obj& obj, rgw_raw_obj *raw_obj);
int get_system_obj_ref(const rgw_raw_obj& obj, rgw_rados_ref *ref, rgw_pool *pool);
uint64_t max_bucket_id;
int get_olh_target_state(RGWObjectCtx& rctx, rgw_obj& obj, RGWObjState *olh_state,
RGWObjState **target_state);
- int get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker);
+ int get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawObjState **state, RGWObjVersionTracker *objv_tracker);
int get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent = false);
int append_atomic_test(RGWObjectCtx *rctx, rgw_obj& obj,
librados::ObjectOperation& op, RGWObjState **state);
RGWObjState *state;
protected:
- int get_state(RGWObjState **pstate, RGWObjVersionTracker *objv_tracker);
+ int get_state(RGWRawObjState **pstate, RGWObjVersionTracker *objv_tracker);
public:
SystemObject(RGWRados *_store, RGWObjectCtx& _ctx, rgw_raw_obj& _obj) : store(_store), ctx(_ctx), obj(_obj), state(NULL) {}
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs);
- int get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker);
+ int get_system_obj_state(RGWObjectCtx *rctx, rgw_raw_obj& obj, RGWRawObjState **state, RGWObjVersionTracker *objv_tracker);
int get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, bool follow_olh, bool assume_noent = false);
int get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state) {
return get_obj_state(rctx, obj, state, true);
void set_atomic(void *ctx, rgw_obj& obj) {
RGWObjectCtx *rctx = static_cast<RGWObjectCtx *>(ctx);
- rctx->set_atomic(obj);
+ rctx->obj.set_atomic(obj);
}
void set_prefetch_data(void *ctx, rgw_obj& obj) {
RGWObjectCtx *rctx = static_cast<RGWObjectCtx *>(ctx);
- rctx->set_prefetch_data(obj);
+ rctx->obj.set_prefetch_data(obj);
}
int decode_policy(bufferlist& bl, ACLOwner *owner);