]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't reset readdir offset if client supports hash order dentry
authorYan, Zheng <zyan@redhat.com>
Mon, 25 Apr 2016 07:52:32 +0000 (15:52 +0800)
committerGreg Farnum <gfarnum@redhat.com>
Sun, 12 Jun 2016 21:10:22 +0000 (14:10 -0700)
Now the ordering of dentries is stable across directory fragmentation.
There is no need to reset readdir offset if directory get fragmented
in the middle of readdir.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
(cherry picked from commit 98a01af2cd8e01f14ab7be32c31a43571ef8bb87)

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

index ad8aca627643653c3859947119db8fba3142bf68..9755446c400fdd33bf7b2f4fe998b51a376fb237 100644 (file)
@@ -1125,10 +1125,11 @@ void Client::insert_readdir_results(MetaRequest *request, MetaSession *session,
     if (fg != dst.frag) {
       ldout(cct, 10) << "insert_trace got new frag " << fg << " -> " << dst.frag << dendl;
       fg = dst.frag;
-      readdir_offset = 2;
-      readdir_start.clear();
-      if (!hash_order)
+      if (!hash_order) {
+       readdir_offset = 2;
+       readdir_start.clear();
        dirp->offset = dir_result_t::make_fpos(fg, readdir_offset, false);
+      }
     }
 
     ldout(cct, 10) << __func__ << " " << numdn << " readdir items, end=" << end
@@ -1184,13 +1185,12 @@ void Client::insert_readdir_results(MetaRequest *request, MetaSession *session,
       ldout(cct, 15) << __func__ << "  " << hex << dn->offset << dec << ": '" << dname << "' -> " << in->ino << dendl;
     }
 
-    if (end) {
-      dirp->last_name.clear();
-      dirp->next_offset = 2;
-    } else {
+    if (numdn > 0)
       dirp->last_name = dname;
+    if (end)
+      dirp->next_offset = 2;
+    else
       dirp->next_offset = readdir_offset;
-    }
 
     if (dir->is_empty())
       close_dir(dir);
@@ -6918,10 +6918,12 @@ void Client::_readdir_next_frag(dir_result_t *dirp)
   ldout(cct, 10) << "_readdir_next_frag advance from " << dirp->buffer_frag << " to " << fg << dendl;
 
   if (dirp->hash_order()) {
+    // keep last_name
     int64_t new_offset = dir_result_t::make_fpos(fg.value(), 2, true);
     if (dirp->offset < new_offset) // don't decrease offset
       dirp->offset = new_offset;
   } else {
+    dirp->last_name.clear();
     dirp->offset = dir_result_t::make_fpos(fg, 2, false);
     _readdir_rechoose_frag(dirp);
   }
@@ -7208,7 +7210,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
        return r;
     }
 
-    if (!dirp->last_name.empty()) {
+    if (dirp->next_offset > 2) {
       ldout(cct, 10) << " fetching next chunk of this frag" << dendl;
       _readdir_drop_dirp_buffer(dirp);
       continue;  // more!
index 514f4d958e9ec816b5d5643ac22605dc47259d80..313744718b0b18015868fa9c283ea476c5a256c8 100644 (file)
@@ -3276,7 +3276,8 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
   frag_t fg = (__u32)req->head.args.readdir.frag;
   unsigned req_flags = (__u32)req->head.args.readdir.flags;
   string offset_str = req->get_path2();
-  dout(10) << " frag " << fg << " offset '" << offset_str << "'" << dendl;
+  dout(10) << " frag " << fg << " offset '" << offset_str << "'"
+          << " flags " << req_flags << dendl;
 
   __u32 offset_hash = 0;
   if (!offset_str.empty())
@@ -3284,10 +3285,20 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
 
   // does the frag exist?
   if (diri->dirfragtree[fg.value()] != fg) {
-    frag_t newfg = diri->dirfragtree[fg.value()];
+    frag_t newfg;
+    if (req_flags & CEPH_READDIR_REPLY_BITFLAGS) {
+      if (fg.contains((unsigned)offset_hash)) {
+       newfg = diri->dirfragtree[offset_hash];
+      } else {
+       // client actually wants next frag
+       newfg = diri->dirfragtree[fg.value()];
+      }
+    } else {
+      offset_str.clear();
+      newfg = diri->dirfragtree[fg.value()];
+    }
     dout(10) << " adjust frag " << fg << " -> " << newfg << " " << diri->dirfragtree << dendl;
     fg = newfg;
-    offset_str.clear();
   }
   
   CDir *dir = try_open_auth_dirfrag(diri, fg, mdr);