]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: fix readdir eof() calc--caller stop implies !eof 28565/head
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 14 Jun 2019 18:26:27 +0000 (14:26 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 14 Jun 2019 19:25:00 +0000 (15:25 -0400)
If rgw_readdir2()'s caller stops enumeration by returning an error
from the readdir callback function, the value of eof is false
for the rgw_readdir2() call.  I.e., eof() is true when the
underlying listing is !truncated and no results were refused by
the caller.

Fixes: http://tracker.ceph.com/issues/40375
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_file.h

index 5ab2a1b378375d41628869580ec3744fef04bd7b..9af81ed322fa00cc6b26f60cf6b1e741ebfbfe80 100644 (file)
@@ -1306,12 +1306,14 @@ public:
   uint64_t* ioff;
   size_t ix;
   uint32_t d_count;
+  bool rcb_eof; // caller forced early stop in readdir cycle
 
   RGWListBucketsRequest(CephContext* _cct, RGWUserInfo *_user,
                        RGWFileHandle* _rgw_fh, rgw_readdir_cb _rcb,
                        void* _cb_arg, RGWFileHandle::readdir_offset& _offset)
     : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), offset(_offset),
-      cb_arg(_cb_arg), rcb(_rcb), ioff(nullptr), ix(0), d_count(0) {
+      cb_arg(_cb_arg), rcb(_rcb), ioff(nullptr), ix(0), d_count(0),
+      rcb_eof(false) {
 
     using boost::get;
 
@@ -1384,6 +1386,7 @@ public:
                              << " dirent=" << ent.bucket.name
                              << " call count=" << ix
                              << dendl;
+       rcb_eof = true;
        return;
       }
       ++ix;
@@ -1417,7 +1420,7 @@ public:
                             << " is_truncated: " << is_truncated
                             << dendl;
     }
-    return !is_truncated;
+    return !is_truncated && !rcb_eof;
   }
 
 }; /* RGWListBucketsRequest */
@@ -1437,12 +1440,14 @@ public:
   uint64_t* ioff;
   size_t ix;
   uint32_t d_count;
+  bool rcb_eof; // caller forced early stop in readdir cycle
 
   RGWReaddirRequest(CephContext* _cct, RGWUserInfo *_user,
                    RGWFileHandle* _rgw_fh, rgw_readdir_cb _rcb,
                    void* _cb_arg, RGWFileHandle::readdir_offset& _offset)
     : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), offset(_offset),
-      cb_arg(_cb_arg), rcb(_rcb), ioff(nullptr), ix(0), d_count(0) {
+      cb_arg(_cb_arg), rcb(_rcb), ioff(nullptr), ix(0), d_count(0),
+      rcb_eof(false) {
 
     using boost::get;
 
@@ -1553,12 +1558,13 @@ public:
                             << " (" << sref << ")" << ""
                             << dendl;
 
-      if(! this->operator()(sref, next_marker, RGW_FS_TYPE_FILE)) {
+      if (! this->operator()(sref, next_marker, RGW_FS_TYPE_FILE)) {
        /* caller cannot accept more */
        lsubdout(cct, rgw, 5) << "readdir rcb failed"
                              << " dirent=" << sref.data()
                              << " call count=" << ix
                              << dendl;
+       rcb_eof = true;
        return;
       }
       ++ix;
@@ -1599,7 +1605,15 @@ public:
        return;
       }
 
-      this->operator()(sref, next_marker, RGW_FS_TYPE_DIRECTORY);
+      if (! this->operator()(sref, next_marker, RGW_FS_TYPE_DIRECTORY)) {
+       /* caller cannot accept more */
+       lsubdout(cct, rgw, 5) << "readdir rcb failed"
+                             << " dirent=" << sref.data()
+                             << " call count=" << ix
+                             << dendl;
+       rcb_eof = true;
+       return;
+      }
       ++ix;
     }
   }
@@ -1619,7 +1633,7 @@ public:
                             << " is_truncated: " << is_truncated
                             << dendl;
     }
-    return !is_truncated;
+    return !is_truncated && !rcb_eof;
   }
 
 }; /* RGWReaddirRequest */