]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: fix readdir after dirent-change 13871/head
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 14 Apr 2017 19:56:37 +0000 (15:56 -0400)
committerNathan Cutler <ncutler@suse.com>
Tue, 4 Jul 2017 08:03:03 +0000 (10:03 +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 99c88c4bf40ae5b72c20a7cde098da051073d167..dd1ebcc753dff702619f5b14634ad8853719f9ce 100644 (file)
@@ -745,10 +745,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;
       {
@@ -946,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);
@@ -958,6 +959,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 2b58c08ada2727c12112dd54e775bc54be5d9131..4a0e33a0dbaf74ca17c6b167401301537a726fa8 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; }
@@ -1225,7 +1227,6 @@ public:
                              << dendl;
        return;
       }
-      ++d_count;
       ++ix;
     }
   } /* send_response_data */
@@ -1241,6 +1242,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);
   }
 
@@ -1257,8 +1259,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;
@@ -1328,6 +1330,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 :
@@ -1372,7 +1375,6 @@ public:
                              << dendl;
        return;
       }
-      ++d_count;
       ++ix;
     }
     for (auto& iter : common_prefixes) {