From d69aa5909e5467cb32127055c38f54e0dd2211e0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 24 Aug 2011 14:38:25 -0700 Subject: [PATCH] client: fix readdir + cap recovation/reissue race The current race: - we start readdir - mds revokes dir cap - some file gets removed - mds reissues dir cap - we finish readdir and set I_COMPLETE We should only set it if there have been no FILE_SHARED reissues during the readdir. Note that we still set I_COMPLETE even if we don't have the cap; that's useless but harmless, since it is undefined without FILE_SHARED being set. Signed-off-by: Sage Weil --- src/client/Client.cc | 9 ++++++--- src/client/Client.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 208569d86374a..c24b501b918a7 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -100,7 +100,7 @@ void client_flush_set_callback(void *p, ObjectCacher::ObjectSet *oset) dir_result_t::dir_result_t(Inode *in) : inode(in), offset(0), next_offset(2), - release_count(0), + release_count(0), start_shared_gen(0), buffer(0) { inode->get(); } @@ -4138,8 +4138,9 @@ int Client::_opendir(Inode *in, dir_result_t **dirpp, int uid, int gid) if (!in->is_dir()) return -ENOTDIR; (*dirpp)->set_frag(in->dirfragtree[0]); - if(in->dir) + if (in->dir) (*dirpp)->release_count = in->dir->release_count; + (*dirpp)->start_shared_gen = in->shared_gen; ldout(cct, 10) << "_opendir " << in->ino << ", our cache says the first dirfrag is " << (*dirpp)->frag() << dendl; ldout(cct, 3) << "_opendir(" << in->ino << ") = " << 0 << " (" << *dirpp << ")" << dendl; return 0; @@ -4516,7 +4517,9 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) continue; } - if (diri->dir && diri->dir->release_count == dirp->release_count) { + if (diri->dir && + diri->dir->release_count == dirp->release_count && + diri->shared_gen == dirp->start_shared_gen) { ldout(cct, 10) << " marking I_COMPLETE on " << *diri << dendl; diri->flags |= I_COMPLETE; if (diri->dir) diff --git a/src/client/Client.h b/src/client/Client.h index bd7479617ffdf..bfa077116ea8b 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -145,6 +145,7 @@ struct dir_result_t { string last_name; // last entry in previous chunk uint64_t release_count; + int start_shared_gen; // dir shared_gen at start of readdir frag_t buffer_frag; vector > *buffer; -- 2.39.5