]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fix cached readdir after seekdir
authorYan, Zheng <zyan@redhat.com>
Mon, 9 May 2016 03:51:36 +0000 (11:51 +0800)
committerGreg Farnum <gfarnum@redhat.com>
Sun, 12 Jun 2016 21:10:10 +0000 (14:10 -0700)
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 <zyan@redhat.com>
(cherry picked from commit 0e32115bae2f1ac2c59b57852976b0de5587abac)

Signed-off-by: Greg Farnum <gfarnum@redhat.com
src/client/Client.cc
src/client/Client.h

index bf6b3d69573a674c21bcb4fdf081e125521f4fd7..6b1213085d29a8b37e2bd307afe3754252df4b8f 100644 (file)
@@ -6991,8 +6991,12 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p)
     if (it == dir->dentries.end())
       return -EAGAIN;
     Dentry *dn = it->second;
+    assert(dir_result_t::fpos_cmp(dn->offset, dirp->offset) < 0);
     pd = xlist<Dentry*>::iterator(&dn->item_dentry_list);
     ++pd;
+    while (!pd.end() &&
+          dir_result_t::fpos_cmp((*pd)->offset, dirp->offset) < 0)
+      ++pd;
   }
 
   string dn_name;
index 10e338aa2a6540b145790fc2de7875094a80f758..b03e770cda2862fc471ae0af8d71e6b4c903b65b 100644 (file)
@@ -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;