]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: fix readdir after dirent-change 14561/head
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 14 Apr 2017 19:56:37 +0000 (15:56 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Sat, 15 Apr 2017 14:05:24 +0000 (10:05 -0400)
Also, fixes link count computation off-by-one, update of state.nlink
after computation, link computation reset at start, and a time print
in debug log.

Fixes: http://tracker.ceph.com/issues/19634
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
link count

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

index 10b0aed5f4be95077feab7a35ce86c895f4b013e..15f20ee1eabe9b60738fdbdb90ba6a7098b697ee 100644 (file)
@@ -777,10 +777,9 @@ namespace rgw {
 
     do {
       (void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
-
       lsubdout(get_context(), rgw, 15)
        << "GC: top of expire loop"
-       << " expire_ts=" << expire_ts
+       << " now=" << now
        << " expire_s=" << expire_s
        << dendl;
       {
@@ -978,6 +977,8 @@ namespace rgw {
        (void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now); /* !LOCKED */
        lock_guard guard(mtx);
        state.atime = now;
+       if (*offset == 0)
+         set_nlink(2);
        inc_nlink(req.d_count);
        *eof = req.eof();
        event ev(event::type::READDIR, get_key(), state.atime);
@@ -990,6 +991,8 @@ namespace rgw {
        (void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now); /* !LOCKED */
        lock_guard guard(mtx);
        state.atime = now;
+       if (*offset == 0)
+         set_nlink(2);
        inc_nlink(req.d_count);
        *eof = req.eof();
        event ev(event::type::READDIR, get_key(), state.atime);
index 00a2b5ac300b714450a1a8bc30ba19be9af7b3b6..df53d4246aa41bb13c578be18ff16805299d288f 100644 (file)
@@ -392,7 +392,7 @@ namespace rgw {
 
       switch (fh.fh_type) {
       case RGW_FS_TYPE_DIRECTORY:
-       st->st_nlink = 2;
+       st->st_nlink = state.nlink;
        break;
       case RGW_FS_TYPE_FILE:
        st->st_nlink = 1;
@@ -483,13 +483,15 @@ namespace rgw {
 
     const rgw_obj_key* find_marker(uint64_t off) const {
       using std::get;
-      const directory* d = get<directory>(&variant_type);
-      if (d) {
-       return &d->last_marker;
+      if (off > 0) {
+       const directory* d = get<directory>(&variant_type);
+       if (d ) {
+         return &d->last_marker;
+       }
       }
       return nullptr;
     }
-    
+
     bool is_open() const { return flags & FLAG_OPEN; }
     bool is_root() const { return flags & FLAG_ROOT; }
     bool is_bucket() const { return flags & FLAG_BUCKET; }
@@ -1227,7 +1229,6 @@ public:
                              << dendl;
        return;
       }
-      ++d_count;
       ++ix;
     }
   } /* send_response_data */
@@ -1243,6 +1244,7 @@ public:
     /* update traversal cache */
     rgw_fh->add_marker(off, rgw_obj_key{marker.data(), ""},
                       RGW_FS_TYPE_DIRECTORY);
+    ++d_count;
     return rcb(name.data(), cb_arg, off, RGW_LOOKUP_FLAG_DIR);
   }
 
@@ -1259,8 +1261,8 @@ public:
   read directory content (bucket objects)
 */
 
-  class RGWReaddirRequest : public RGWLibRequest,
-                           public RGWListBucket /* RGWOp */
+class RGWReaddirRequest : public RGWLibRequest,
+                         public RGWListBucket /* RGWOp */
 {
 public:
   RGWFileHandle* rgw_fh;
@@ -1330,6 +1332,7 @@ public:
     *offset = off;
     /* update traversal cache */
     rgw_fh->add_marker(off, marker, type);
+    ++d_count;
     return rcb(name.data(), cb_arg, off,
               (type == RGW_FS_TYPE_DIRECTORY) ?
               RGW_LOOKUP_FLAG_DIR :
@@ -1374,7 +1377,6 @@ public:
                              << dendl;
        return;
       }
-      ++d_count;
       ++ix;
     }
     for (auto& iter : common_prefixes) {