]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: incremental listing fixes
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 11 Dec 2015 02:33:01 +0000 (21:33 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:06:34 +0000 (12:06 -0500)
* remove path in RGWStatLeafRequest--use bool is_dir instead
* remove unused uri in RGWListBucketRequest
* more dbg prints; problem w/final segment in obj_rec

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/test/librgw_file_nfsns.cc

index ba211403d2762935d40d5c4069e9d3de6f7466d4..d4e8a846a3141b3de1bf8ae9496aa2fec8207bfd 100644 (file)
@@ -85,9 +85,9 @@ LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
        if (req.matched) {
          fhr = lookup_fh(parent, path,
                          RGWFileHandle::FLAG_CREATE|
-                         ((req.path.back() == '/') ?
-                          RGWFileHandle::FLAG_DIRECTORY :
-                          RGWFileHandle::FLAG_NONE));
+                         ((req.is_dir) ?
+                           RGWFileHandle::FLAG_DIRECTORY :
+                           RGWFileHandle::FLAG_NONE));
        }
       }
     }
index d3723fa0f5a6a38b77ad0d25b45873a76898b6c1..8a55dcd9d622f427c3ac6e753634d491d4335a2b 100644 (file)
@@ -713,7 +713,6 @@ class RGWListBucketRequest : public RGWLibRequest,
 {
 public:
   RGWFileHandle* rgw_fh;
-  std::string uri;
   uint64_t* offset;
   void* cb_arg;
   rgw_readdir_cb rcb;
@@ -769,6 +768,7 @@ public:
 
   int operator()(const std::string& name, const std::string& marker,
                 bool add_marker) {
+    /* hash offset of name in parent (short name) for NFS readdir cookie */
     uint64_t off = XXH64(name.c_str(), name.length(), fh_key::seed);
     *offset = off;
     /* update traversal cache */
@@ -784,6 +784,7 @@ public:
   }
 
   virtual void send_response() {
+    struct req_state* s = get_state();
     size_t size = objs.size();for (const auto& iter : objs) {
       size_t last_del = iter.key.name.find_last_of('/');
       boost::string_ref sref;
@@ -791,9 +792,14 @@ public:
        sref = boost::string_ref{iter.key.name.substr(last_del+1)};
       else
        sref = boost::string_ref{iter.key.name};
+
+      /* if we find a trailing slash in a -listing- the parent is an
+       * empty directory */
+      if (sref=="")
+       continue;
        
       std::cout << "RGWListBucketRequest "
-               << __func__ << " " << "list uri=" << uri << " "
+               << __func__ << " " << "list uri=" << s->relative_uri << " "
                << " prefix=" << prefix << " "
                << " obj path=" << iter.key.name
                << " (" << sref << ")" << ""
@@ -816,7 +822,7 @@ public:
        sref = boost::string_ref{iter.first};
 
       std::cout << "RGWListBucketRequest "
-               << __func__ << " " << "list uri=" << uri << " "
+               << __func__ << " " << "list uri=" << s->relative_uri << " "
                << " prefix=" << prefix << " "
                << " cpref=" << sref << " (not chomped)"
                << std::endl;
@@ -1340,11 +1346,12 @@ public:
   RGWFileHandle* rgw_fh;
   std::string path;
   bool matched;
+  bool is_dir;
 
   RGWStatLeafRequest(CephContext* _cct, RGWUserInfo *_user,
                     RGWFileHandle* _rgw_fh, const std::string& _path)
     : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), path(_path),
-      matched(false) {
+      matched(false), is_dir(false) {
     default_max = 1000; // logical max {"foo", "foo/"}
     magic = 80;
     op = this;
@@ -1381,6 +1388,9 @@ public:
     s->user = user;
 
     prefix = rgw_fh->full_object_name();
+    if (prefix.length() > 0)
+      prefix += "/";
+    prefix += path;
     delimiter = '/';
 
     return 0;
@@ -1395,24 +1405,26 @@ public:
     struct req_state* s = get_state();
     // try objects
     for (const auto& iter : objs) {
-      path = iter.key.name;
+      auto& name = iter.key.name;
       std::cout << "RGWStatLeafRequest "
                << __func__ << " " << "list uri=" << s->relative_uri << " "
                << " prefix=" << prefix << " "
-               << " obj path=" << path << ""
+               << " obj path=" << name << ""
                << std::endl;
+      /* XXX is there a missing match-dir case (trailing '/')? */
       matched = true;
       return;
     }
     // try prefixes
     for (auto& iter : common_prefixes) {
-      path = iter.first;
+      auto& name = iter.first;
       std::cout << "RGWStatLeafRequest "
                << __func__ << " " << "list uri=" << s->relative_uri << " "
                << " prefix=" << prefix << " "
-               << " pref path=" << path << " (not chomped)"
+               << " pref path=" << name << " (not chomped)"
                << std::endl;
       matched = true;
+      is_dir = true;
       break;
     }
   }
index 59bbcfd96bc9c52af3a313808c7b22b6acff7fdc..bc1744fd57822eaa9d4534cddae5664bf7627f82 100644 (file)
@@ -68,7 +68,9 @@ namespace {
     RGWFileHandle* rgw_fh = rec.rgw_fh;
     if (rgw_fh) {
       const char* type = rgw_fh->is_dir() ? "DIR " : "FILE ";
-      os << rec.name << ": "
+      os << rec.rgw_fh->full_object_name()
+        << " (" << rec.rgw_fh->object_name() << ", "
+        << " " << rec.name << "): "
         << type;
     }
     return os;
@@ -100,6 +102,12 @@ extern "C" {
   static bool r1_cb(const char* name, void *arg, uint64_t offset) {
     struct rgw_file_handle* parent_fh
       = static_cast<struct rgw_file_handle*>(arg);
+    RGWFileHandle* rgw_fh = get_rgwfh(parent_fh);
+    std::cout << __func__
+             << " bucket=" << rgw_fh->bucket_name()
+             << " dir=" << rgw_fh->full_object_name()
+             << " called back name=" << name
+             << std::endl;
     obj_stack.push(
       obj_rec{name, nullptr, parent_fh, nullptr});
     return true; /* XXX */
@@ -134,7 +142,7 @@ TEST(LibRGW, ENUMERATE1) {
          std::cout << "readdir in"
                    << " bucket: " << elt.rgw_fh->bucket_name()
                    << " object_name: " << elt.rgw_fh->object_name()
-                   << " full name: " << elt.rgw_fh->full_object_name()
+                   << " full_name: " << elt.rgw_fh->full_object_name()
                    << std::endl;
          rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof);
          elt.state.readdir = true;