From: Yan, Zheng Date: Mon, 9 May 2016 03:51:36 +0000 (+0800) Subject: client: fix cached readdir after seekdir X-Git-Tag: v10.2.2~8^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8361b988441d073b82809dbafd82fba1c23b13be;p=ceph.git client: fix cached readdir after seekdir Client::seekdir doesn't reset dirp->at_cache_name for a forward seek within same frag. So the dentry with name == at_cache_name may not be the one prior to the readdir postion. Signed-off-by: Yan, Zheng (cherry picked from commit 0e32115bae2f1ac2c59b57852976b0de5587abac) Signed-off-by: Greg Farnum dentries.end()) return -EAGAIN; Dentry *dn = it->second; + assert(dir_result_t::fpos_cmp(dn->offset, dirp->offset) < 0); pd = xlist::iterator(&dn->item_dentry_list); ++pd; + while (!pd.end() && + dir_result_t::fpos_cmp((*pd)->offset, dirp->offset) < 0) + ++pd; } string dn_name; diff --git a/src/client/Client.h b/src/client/Client.h index 10e338aa2a6..b03e770cda2 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -172,6 +172,14 @@ struct dir_result_t { static unsigned fpos_off(uint64_t p) { return p & MASK; } + static int fpos_cmp(uint64_t l, uint64_t r) { + int c = ceph_frag_compare(fpos_high(l), fpos_high(r)); + if (c) + return c; + if (fpos_low(l) == fpos_low(r)) + return 0; + return fpos_low(l) < fpos_low(r) ? -1 : 1; + } InodeRef inode;