Merge pull request #41080 from t-msn/readdir-fix2

os/FileStore: fix to handle readdir error correctly

Reviewed-by: Kefu Chai <kchai@redhat.com>
Reviewed-by: Mykola Golub <mgolub@suse.com>
Reviewed-by: Josh Durgin <jdurgin@redhat.com>
Reviewed-by: Neha Ojha <nojha@redhat.com>
This commit is contained in:
Kefu Chai 2021-05-08 16:36:51 +08:00 committed by GitHub
commit 0edba988f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 5 deletions

View File

@ -326,7 +326,17 @@ int BtrfsFileStoreBackend::list_checkpoints(list<string>& ls)
list<string> snaps;
char path[PATH_MAX];
struct dirent *de;
while ((de = ::readdir(dir))) {
while (true) {
errno = 0;
de = ::readdir(dir);
if (de == nullptr) {
if (errno != 0) {
err = -errno;
dout(0) << "list_checkpoints: readdir '" << get_basedir_path() << "' failed: "
<< cpp_strerror(err) << dendl;
}
break;
}
snprintf(path, sizeof(path), "%s/%s", get_basedir_path().c_str(), de->d_name);
struct stat st;

View File

@ -4987,7 +4987,17 @@ int FileStore::list_collections(vector<coll_t>& ls, bool include_temp)
}
struct dirent *de = nullptr;
while ((de = ::readdir(dir))) {
while (true) {
errno = 0;
de = ::readdir(dir);
if (de == nullptr) {
if (errno != 0) {
r = -errno;
derr << "readdir failed " << fn << ": " << cpp_strerror(-r) << dendl;
if (r == -EIO && m_filestore_fail_eio) handle_eio();
}
break;
}
if (de->d_type == DT_UNKNOWN) {
// d_type not supported (non-ext[234], btrfs), must stat
struct stat sb;

View File

@ -429,7 +429,18 @@ int LFNIndex::list_objects(const vector<string> &to_list, int max_objs,
int r = 0;
int listed = 0;
bool end = true;
while ((de = ::readdir(dir))) {
while (true) {
errno = 0;
de = ::readdir(dir);
if (de == nullptr) {
if (errno != 0) {
r = -errno;
dout(0) << "readdir failed " << to_list_path << ": "
<< cpp_strerror(-r) << dendl;
goto cleanup;
}
break;
}
end = false;
if (max_objs > 0 && listed >= max_objs) {
break;
@ -477,7 +488,18 @@ int LFNIndex::list_subdirs(const vector<string> &to_list,
return -errno;
struct dirent *de = nullptr;
while ((de = ::readdir(dir))) {
int r = 0;
while (true) {
errno = 0;
de = ::readdir(dir);
if (de == nullptr) {
if (errno != 0) {
r = -errno;
dout(0) << "readdir failed " << to_list_path << ": "
<< cpp_strerror(-r) << dendl;
}
break;
}
string short_name(de->d_name);
string demangled_name;
if (lfn_is_subdir(short_name, &demangled_name)) {
@ -486,7 +508,7 @@ int LFNIndex::list_subdirs(const vector<string> &to_list,
}
::closedir(dir);
return 0;
return r;
}
int LFNIndex::create_path(const vector<string> &to_create)