From: Gui Hecheng Date: Fri, 2 Jun 2017 02:00:48 +0000 (+0800) Subject: rgw_file: fix misuse of make_key_name before make_fhk X-Git-Tag: ses5-milestone7~3^2~1^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=123321f4790423e276bd50bb4723ee975e669c62;p=ceph.git rgw_file: fix misuse of make_key_name before make_fhk The make_fhk calls make_key_name internally. Also, because this makes the stored fhk and the new constructed fhk mismatch, we make the assertion check conditional based on versioned fhk and bump up the version. Also, we shall safely update the old_key using update_fhk(). Signed-off-by: Gui Hecheng --- diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index e5032d0a510..ca8a5c4b4b8 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -92,7 +92,10 @@ namespace rgw { auto ux_key = req.get_attr(RGW_ATTR_UNIX_KEY1); auto ux_attrs = req.get_attr(RGW_ATTR_UNIX1); if (ux_key && ux_attrs) { - rgw_fh->decode_attrs(ux_key, ux_attrs); + bool old_key = rgw_fh->decode_attrs(ux_key, ux_attrs); + if (old_key) { + update_fhk(rgw_fh); + } } if (! (flags & RGWFileHandle::FLAG_LOCKED)) { rgw_fh->mtx.unlock(); @@ -144,7 +147,10 @@ namespace rgw { auto ux_key = req.get_attr(RGW_ATTR_UNIX_KEY1); auto ux_attrs = req.get_attr(RGW_ATTR_UNIX1); if (ux_key && ux_attrs) { - rgw_fh->decode_attrs(ux_key, ux_attrs); + bool old_key = rgw_fh->decode_attrs(ux_key, ux_attrs); + if (old_key) { + update_fhk(rgw_fh); + } } } goto done; @@ -175,7 +181,10 @@ namespace rgw { auto ux_key = req.get_attr(RGW_ATTR_UNIX_KEY1); auto ux_attrs = req.get_attr(RGW_ATTR_UNIX1); if (ux_key && ux_attrs) { - rgw_fh->decode_attrs(ux_key, ux_attrs); + bool old_key = rgw_fh->decode_attrs(ux_key, ux_attrs); + if (old_key) { + update_fhk(rgw_fh); + } } } goto done; @@ -734,6 +743,41 @@ namespace rgw { return 0; } /* RGWLibFS::setattr */ + /* called under rgw_fh->mtx held */ + void RGWLibFS::update_fhk(RGWFileHandle *rgw_fh) + { + int rc, rc2; + string obj_name{rgw_fh->relative_object_name()}; + buffer::list ux_key, ux_attrs; + + if (rgw_fh->is_dir() && + (likely(! rgw_fh->is_bucket()))) { + obj_name += "/"; + } + + lsubdout(get_context(), rgw, 17) + << __func__ + << " update old versioned fhk : " << obj_name + << dendl; + + RGWSetAttrsRequest req(cct, get_user(), rgw_fh->bucket_name(), obj_name); + + rgw_fh->encode_attrs(ux_key, ux_attrs); + + /* update ux_key only */ + req.emplace_attr(RGW_ATTR_UNIX_KEY1, std::move(ux_key)); + + rc = rgwlib.get_fe()->execute_req(&req); + rc2 = req.get_ret(); + + if ((rc != 0) || (rc2 != 0)) { + lsubdout(get_context(), rgw, 17) + << __func__ + << " update fhk failed : " << obj_name + << dendl; + } + } /* RGWLibFS::update_fhk */ + void RGWLibFS::close() { state.flags |= FLAG_CLOSED; @@ -933,16 +977,23 @@ namespace rgw { rgw::encode(*this, ux_attrs1); } /* RGWFileHandle::encode_attrs */ - void RGWFileHandle::decode_attrs(const ceph::buffer::list* ux_key1, + bool RGWFileHandle::decode_attrs(const ceph::buffer::list* ux_key1, const ceph::buffer::list* ux_attrs1) { + bool old_key = false; fh_key fhk; auto bl_iter_key1 = const_cast(ux_key1)->begin(); rgw::decode(fhk, bl_iter_key1); - assert(this->fh.fh_hk == fhk.fh_hk); + if (fhk.version >= 2) { + assert(this->fh.fh_hk == fhk.fh_hk); + } else { + old_key = true; + } auto bl_iter_unix1 = const_cast(ux_attrs1)->begin(); rgw::decode(*this, bl_iter_unix1); + + return old_key; } /* RGWFileHandle::decode_attrs */ bool RGWFileHandle::reclaim() { diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index bfda28055a6..bd9dcd168eb 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -91,42 +91,50 @@ namespace rgw { struct fh_key { rgw_fh_hk fh_hk; + uint32_t version; static constexpr uint64_t seed = 8675309; - fh_key() {} + fh_key() : version(0) {} fh_key(const rgw_fh_hk& _hk) - : fh_hk(_hk) { + : fh_hk(_hk), version(0) { // nothing } - fh_key(const uint64_t bk, const uint64_t ok) { + fh_key(const uint64_t bk, const uint64_t ok) + : version(0) { fh_hk.bucket = bk; fh_hk.object = ok; } - fh_key(const uint64_t bk, const char *_o) { + fh_key(const uint64_t bk, const char *_o) + : version(0) { fh_hk.bucket = bk; fh_hk.object = XXH64(_o, ::strlen(_o), seed); } - fh_key(const std::string& _b, const std::string& _o) { + fh_key(const std::string& _b, const std::string& _o) + : version(0) { fh_hk.bucket = XXH64(_b.c_str(), _o.length(), seed); fh_hk.object = XXH64(_o.c_str(), _o.length(), seed); } void encode(buffer::list& bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(fh_hk.bucket, bl); ::encode(fh_hk.object, bl); + ::encode((uint32_t)2, bl); ENCODE_FINISH(bl); } void decode(bufferlist::iterator& bl) { - DECODE_START(1, bl); + DECODE_START(2, bl); ::decode(fh_hk.bucket, bl); ::decode(fh_hk.object, bl); + if (struct_v >= 2) { + ::decode(version, bl); + } DECODE_FINISH(bl); } }; /* fh_key */ @@ -613,7 +621,7 @@ namespace rgw { void encode_attrs(ceph::buffer::list& ux_key1, ceph::buffer::list& ux_attrs1); - void decode_attrs(const ceph::buffer::list* ux_key1, + bool decode_attrs(const ceph::buffer::list* ux_key1, const ceph::buffer::list* ux_attrs1); void invalidate(); @@ -982,7 +990,7 @@ namespace rgw { << " (" << obj_name << ")" << dendl; - fh_key fhk = parent->make_fhk(key_name); + fh_key fhk = parent->make_fhk(obj_name); retry: RGWFileHandle* fh = @@ -1066,6 +1074,9 @@ namespace rgw { int setattr(RGWFileHandle* rgw_fh, struct stat* st, uint32_t mask, uint32_t flags); + void update_fhk(RGWFileHandle *rgw_fh); + + LookupFHResult stat_bucket(RGWFileHandle* parent, const char *path, RGWLibFS::BucketStats& bs, uint32_t flags); @@ -2343,8 +2354,7 @@ public: /* XXX and fixup key attr (could optimize w/string ref and * dest_object) */ buffer::list ux_key; - std::string key_name{dst_parent->make_key_name(dst_name.c_str())}; - fh_key fhk = dst_parent->make_fhk(key_name); + fh_key fhk = dst_parent->make_fhk(dst_name); rgw::encode(fhk, ux_key); emplace_attr(RGW_ATTR_UNIX_KEY1, std::move(ux_key));