]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: rgw file fix bug of rgw_lookup can not exact match file name
authorMin Chen <chenmin@xsky.com>
Fri, 19 Aug 2016 05:02:50 +0000 (01:02 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Wed, 5 Oct 2016 18:25:43 +0000 (14:25 -0400)
bug reproduce steps:
in nfs-client (connect to nfs-ganesha server):
1. mv file file.rename
2. stat file // get file attrs, not return with -ENOENT

the reason is that:
RGWStatLeafRequest does not exact match the file name,
just take file name as a prefix filter

Signed-off-by: Min Chen <chenmin@xsky.com>
(cherry picked from commit 9d813bafc8e197507457c58ab4f365ccdb7f3589)

Fixes: http://tracker.ceph.com/issues/17326
src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index e5a72525e423c15f7ae28a603afe63905b3cc064..918b9425524016e68b71a2f6dbcdde0ccaeaa499 100644 (file)
@@ -168,6 +168,15 @@ namespace rgw {
        if ((rc == 0) &&
            (req.get_ret() == 0)) {
          if (req.matched) {
+           // we need rgw object's key name equal to file name, if not return NULL
+           if ((flags & RGWFileHandle::FLAG_EXACT_MATCH) &&
+               !req.exact_matched) {
+             lsubdout(get_context(), rgw, 15)
+               << __func__
+               << ": stat leaf not exact match file name = "
+               << path << dendl;
+             goto done;
+           }
            fhr = lookup_fh(parent, path,
                            RGWFileHandle::FLAG_CREATE|
                            ((req.is_dir) ?
@@ -1262,7 +1271,7 @@ int rgw_lookup(struct rgw_fs *rgw_fs,
        return -ENOENT;
     }
   } else {
-    fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_NONE);
+    fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_EXACT_MATCH);
     if (! get<0>(fhr)) {
       if (! (flags & RGW_LOOKUP_FLAG_CREATE))
        return -ENOENT;
index 0998fa39965e4ba00521fe8dc50d679aab3588b5..47435a43469f52aea8095e18f24c552455bf6f5a 100644 (file)
@@ -236,6 +236,7 @@ namespace rgw {
     static constexpr uint32_t FLAG_UNLINK_THIS = 0x0100;
     static constexpr uint32_t FLAG_LOCKED = 0x0200;
     static constexpr uint32_t FLAG_STATELESS_OPEN = 0x0400;
+    static constexpr uint32_t FLAG_EXACT_MATCH = 0x0800;
 
 #define CREATE_FLAGS(x) \
     ((x) & ~(RGWFileHandle::FLAG_CREATE|RGWFileHandle::FLAG_LOCK))
@@ -1861,11 +1862,12 @@ public:
   std::string path;
   bool matched;
   bool is_dir;
+  bool exact_matched;
 
   RGWStatLeafRequest(CephContext* _cct, RGWUserInfo *_user,
                     RGWFileHandle* _rgw_fh, const std::string& _path)
     : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), path(_path),
-      matched(false), is_dir(false) {
+      matched(false), is_dir(false), exact_matched(false) {
     default_max = 1000; // logical max {"foo", "foo/"}
     op = this;
   }
@@ -1924,9 +1926,12 @@ public:
                             << "list uri=" << s->relative_uri << " "
                             << " prefix=" << prefix << " "
                             << " obj path=" << name << ""
+                            << " target = " << path << ""
                             << dendl;
       /* XXX is there a missing match-dir case (trailing '/')? */
       matched = true;
+      if (name == path)
+       exact_matched = true;
       return;
     }
     // try prefixes
@@ -1937,6 +1942,7 @@ public:
                             << "list uri=" << s->relative_uri << " "
                             << " prefix=" << prefix << " "
                             << " pref path=" << name << " (not chomped)"
+                            << " target = " << path << ""
                             << dendl;
       matched = true;
       is_dir = true;