]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: fix misuse of make_key_name before make_fhk 15108/head
authorGui Hecheng <guihecheng@cmss.chinamobile.com>
Fri, 2 Jun 2017 02:00:48 +0000 (10:00 +0800)
committerGui Hecheng <guihecheng@cmss.chinamobile.com>
Wed, 14 Jun 2017 08:09:18 +0000 (16:09 +0800)
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 <guihecheng@cmss.chinamobile.com>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index e5032d0a5104a8221cf49848fb3b45622ab5568a..ca8a5c4b4b879af7e85b6252691382cea0881232 100644 (file)
@@ -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<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() {
index bfda28055a6d6c024ec4d20547f1ff7defc93b49..bd9dcd168eb4ab312a56f65bc007b718860e6efe 100644 (file)
@@ -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));