From: Matt Benjamin Date: Fri, 14 Jun 2019 18:26:27 +0000 (-0400) Subject: rgw_file: fix readdir eof() calc--caller stop implies !eof X-Git-Tag: v13.2.7~80^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=84784a2466a7916f4b71d0f8eb905a8ec3018673;p=ceph.git rgw_file: fix readdir eof() calc--caller stop implies !eof 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 (cherry picked from commit 7fa9cf35deca5efbf82cf438574d7afe15748bc0) --- diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index eade60cff8f..c206acfef06 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -1272,12 +1272,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; @@ -1350,6 +1352,7 @@ public: << " dirent=" << ent.bucket.name << " call count=" << ix << dendl; + rcb_eof = true; return; } ++ix; @@ -1383,7 +1386,7 @@ public: << " is_truncated: " << is_truncated << dendl; } - return !is_truncated; + return !is_truncated && !rcb_eof; } }; /* RGWListBucketsRequest */ @@ -1403,12 +1406,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; @@ -1519,12 +1524,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; @@ -1565,7 +1571,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; } } @@ -1585,7 +1599,7 @@ public: << " is_truncated: " << is_truncated << dendl; } - return !is_truncated; + return !is_truncated && !rcb_eof; } }; /* RGWReaddirRequest */