]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: fix readdir after dirent-change
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 14 Apr 2017 19:56:37 +0000 (15:56 -0400)
committerNathan Cutler <ncutler@suse.com>
Thu, 20 Apr 2017 09:35:35 +0000 (11:35 +0200)
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>
(cherry picked from commit e0f80266ecd424bf9466579b3edc03911a7c5719)

src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index 3f5042f1d690b5174209b7717113758713dfd7dc..4927f21f70c804e3313337487671b13991b56518 100644 (file)
@@ -730,10 +730,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;
       {
@@ -931,6 +930,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);
@@ -944,6 +945,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 85e34e7fa4908d59d043d3fba47de38cf3b20d35..7bc62785ed510f95db45db5e5841009d3028b9da 100644 (file)
@@ -386,7 +386,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;
@@ -477,13 +477,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; }
@@ -1216,7 +1218,6 @@ public:
                              << dendl;
        return;
       }
-      ++d_count;
       ++ix;
     }
   } /* send_response_data */
@@ -1232,6 +1233,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);
   }
 
@@ -1248,8 +1250,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;
@@ -1319,6 +1321,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 :
@@ -1363,7 +1366,6 @@ public:
                              << dendl;
        return;
       }
-      ++d_count;
       ++ix;
     }
     for (auto& iter : common_prefixes) {