From: Greg Farnum Date: Thu, 20 Oct 2011 23:26:15 +0000 (-0700) Subject: rgw: fix check_disk_state; add a strip_namespace function. X-Git-Tag: v0.38~57^2~15^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f57c33df48f11a26b06d15c1e275e5fa956d286f;p=ceph.git rgw: fix check_disk_state; add a strip_namespace function. Use copies of the IoCtx rather than references so that we can set locators without breaking stuff, and make use of the on-disk locators which we just added. Signed-off-by: Greg Farnum --- diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 67c9115131b4..6d0fffeab630 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -724,6 +724,35 @@ public: return true; } + /** + * Given a mangled object name and an empty namespace string, this + * function extracts the namespace into the string and sets the object + * name to be the unmangled version. + * + * It returns true after successfully doing so, or + * false if it fails. + */ + static bool strip_namespace_from_object(string& obj, string& ns) { + ns.clear(); + if (obj[0] != '_') { + return true; + } + + size_t pos = obj.find('_', 1); + if (pos == string::npos) { + return false; + } + + size_t period_pos = obj.find('.'); + if (period_pos < pos) { + return false; + } + + ns = obj.substr(1, pos-1); + obj = obj.substr(pos+1, string::npos); + return true; + } + void encode(bufferlist& bl) const { __u8 struct_v = 2; ::encode(struct_v, bl); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index eec3825c2cc2..93e3cd6bd707 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2165,7 +2165,9 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, ma if (!dirent.exists || !dirent.pending_map.empty()) { /* there are uncommitted ops. We need to check the current state, * and if the tags are old we need to do cleanup as well. */ - r = check_disk_state(io_ctx, bucket, dirent, e, updates); + librados::IoCtx sub_ctx; + sub_ctx.dup(io_ctx); + r = check_disk_state(sub_ctx, bucket, dirent, e, updates); if (r < 0) { if (r == -ENOENT) continue; @@ -2190,16 +2192,22 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, ma return m.size(); } -int RGWRados::check_disk_state(librados::IoCtx& io_ctx, +int RGWRados::check_disk_state(librados::IoCtx io_ctx, rgw_bucket& bucket, rgw_bucket_dir_entry& list_state, RGWObjEnt& object, bufferlist& suggested_updates) { rgw_obj obj; - std::string oid, key; - obj.init(bucket, list_state.name); + std::string oid, key, ns; + oid = list_state.name; + if (!rgw_obj::strip_namespace_from_object(oid, ns)) { + // well crap + assert(0 == "got bad object name off disk"); + } + obj.init(bucket, oid, list_state.locator, ns); get_obj_bucket_and_oid_key(obj, bucket, oid, key); + io_ctx.locator_set_key(key); int r = io_ctx.stat(oid, &object.size, &object.mtime); list_state.pending_map.clear(); // we don't need this and it inflates size diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 75987059ff40..e697d0ab1475 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -338,7 +338,7 @@ public: * and -errno on other failures. (-ENOENT is not a failure, and it * will encode that info as a suggested update.) */ - int check_disk_state(librados::IoCtx& io_ctx, + int check_disk_state(librados::IoCtx io_ctx, rgw_bucket& bucket, rgw_bucket_dir_entry& list_state, RGWObjEnt& object,