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();
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;
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;
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;
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<buffer::list*>(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<buffer::list*>(ux_attrs1)->begin();
rgw::decode(*this, bl_iter_unix1);
+
+ return old_key;
} /* RGWFileHandle::decode_attrs */
bool RGWFileHandle::reclaim() {
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 */
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();
<< " (" << obj_name << ")"
<< dendl;
- fh_key fhk = parent->make_fhk(key_name);
+ fh_key fhk = parent->make_fhk(obj_name);
retry:
RGWFileHandle* fh =
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);
/* 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));