]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: fix readdir eof() calc--caller stop implies !eof 29409/head
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 14 Jun 2019 18:26:27 +0000 (14:26 -0400)
committerPrashant D <pdhange@redhat.com>
Tue, 30 Jul 2019 23:07:35 +0000 (19:07 -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>
(cherry picked from commit 7fa9cf35deca5efbf82cf438574d7afe15748bc0)

src/rgw/rgw_file.h

index 72787e3ba8f176cfb1c4d010fb13c0d9a54bee45..12af52ea804035d04bb63c6231acb50b650a689f 100644 (file)
@@ -1303,12 +1303,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;
 
@@ -1381,6 +1383,7 @@ public:
                              << " dirent=" << ent.bucket.name
                              << " call count=" << ix
                              << dendl;
+       rcb_eof = true;
        return;
       }
       ++ix;
@@ -1414,7 +1417,7 @@ public:
                             << " is_truncated: " << is_truncated
                             << dendl;
     }
-    return !is_truncated;
+    return !is_truncated && !rcb_eof;
   }
 
 }; /* RGWListBucketsRequest */
@@ -1434,12 +1437,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;
 
@@ -1550,12 +1555,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;
@@ -1596,7 +1602,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;
     }
   }
@@ -1616,7 +1630,7 @@ public:
                             << " is_truncated: " << is_truncated
                             << dendl;
     }
-    return !is_truncated;
+    return !is_truncated && !rcb_eof;
   }
 
 }; /* RGWReaddirRequest */