From: Yehuda Sadeh Date: Wed, 29 Apr 2015 21:15:33 +0000 (-0700) Subject: rgw: async object stat functionality X-Git-Tag: v9.0.3~76^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=13adf3cf4f5fd8a0feb7cc1d7a4ee4ded9f573db;p=ceph.git rgw: async object stat functionality An async functionality that stats object. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index b496e17412bc..b39559ad1099 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -4869,6 +4869,83 @@ int RGWRados::Object::Read::get_attr(const char *name, bufferlist& dest) return 0; } + +int RGWRados::Object::Stat::stat_async() +{ + RGWObjectCtx& ctx = source->get_ctx(); + 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 */ + if (s->has_attrs) { + state.ret = 0; + result.size = s->size; + result.mtime = s->mtime; + result.attrs = s->attrset; + result.has_manifest = s->has_manifest; + result.manifest = s->manifest; + return 0; + } + + string oid; + string loc; + rgw_bucket bucket; + get_obj_bucket_and_oid_loc(obj, bucket, oid, loc); + + int r = store->get_obj_ioctx(obj, &state.io_ctx); + if (r < 0) { + return r; + } + + librados::ObjectReadOperation op; + op.stat(&result.size, &result.mtime, NULL); + op.getxattrs(&result.attrs, NULL); + state.completion = librados::Rados::aio_create_completion(NULL, NULL, NULL); + r = state.io_ctx.aio_operate(oid, state.completion, &op, NULL); + if (r < 0) { + ldout(store->ctx(), 5) << __func__ << ": ERROR: aio_operate() returned ret=" << r << dendl; + return r; + } + + return 0; +} + + +int RGWRados::Object::Stat::wait() +{ + if (!state.completion) { + return state.ret; + } + + state.completion->wait_for_complete(); + state.ret = state.completion->get_return_value(); + state.completion->release(); + + if (state.ret != 0) { + return state.ret; + } + + return finish(); +} + +int RGWRados::Object::Stat::finish() +{ + map::iterator iter = result.attrs.find(RGW_ATTR_MANIFEST); + if (iter != result.attrs.end()) { + bufferlist& bl = iter->second; + bufferlist::iterator biter = bl.begin(); + try { + ::decode(result.manifest, biter); + } catch (buffer::error& err) { + RGWRados *store = source->get_store(); + ldout(store->ctx(), 0) << "ERROR: " << __func__ << ": failed to decode manifest" << dendl; + return -EIO; + } + } + + return 0; +} + /** * Get the attributes for an object. * bucket: name of the bucket holding the object. diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index b487c034b923..0e89bb5b1327 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1603,6 +1603,38 @@ public: int delete_obj(); }; + + struct Stat { + RGWRados::Object *source; + + struct Result { + rgw_obj obj; + RGWObjManifest manifest; + bool has_manifest; + uint64_t size; + time_t mtime; + map attrs; + + Result() : has_manifest(false), size(0), mtime(0) {} + } result; + + struct State { + librados::IoCtx io_ctx; + librados::AioCompletion *completion; + int ret; + + State() : completion(NULL), ret(0) {} + } state; + + + Stat(RGWRados::Object *_source) : source(_source) {} + + int stat_async(); + int wait(); + int stat(); + private: + int finish(); + }; }; class Bucket {