]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add an option to decide whether prefetching entire dir or not. 39315/head
authorshenhang <shenhang@kuaishou.com>
Fri, 10 Sep 2021 10:59:49 +0000 (18:59 +0800)
committershenhang <shenhang@kuaishou.com>
Wed, 9 Feb 2022 09:31:46 +0000 (17:31 +0800)
Accessing one single dentry could be fastened by set this option to
false, when dir is not in the memory.
Signed-off-by: "Shen, Hang" <shenhang@kuaishou.com>
qa/cephfs/overrides/prefetch_entire_dirfrags/no.yaml [new file with mode: 0644]
qa/cephfs/overrides/prefetch_entire_dirfrags/yes.yaml [new file with mode: 0644]
qa/suites/fs/thrash/workloads/overrides/prefetch_entire_dirfrags [new symlink]
src/common/options/mds.yaml.in
src/mds/CDir.cc
src/mds/MDCache.cc

diff --git a/qa/cephfs/overrides/prefetch_entire_dirfrags/no.yaml b/qa/cephfs/overrides/prefetch_entire_dirfrags/no.yaml
new file mode 100644 (file)
index 0000000..41903ef
--- /dev/null
@@ -0,0 +1,4 @@
+overrides:
+  ceph:
+    cephfs:
+      mds_dir_prefetch: false 
diff --git a/qa/cephfs/overrides/prefetch_entire_dirfrags/yes.yaml b/qa/cephfs/overrides/prefetch_entire_dirfrags/yes.yaml
new file mode 100644 (file)
index 0000000..143865a
--- /dev/null
@@ -0,0 +1,4 @@
+overrides:
+  ceph:
+    cephfs:
+      mds_dir_prefetch: true
diff --git a/qa/suites/fs/thrash/workloads/overrides/prefetch_entire_dirfrags b/qa/suites/fs/thrash/workloads/overrides/prefetch_entire_dirfrags
new file mode 120000 (symlink)
index 0000000..9b8024f
--- /dev/null
@@ -0,0 +1 @@
+.qa/cephfs/overrides/prefetch_entire_dirfrags
\ No newline at end of file
index 697710484c8fc157205e5e1fec2fbe87c553ba1c..3a6464ebcdd71f9793fbdb188e6861902f50fd82 100644 (file)
@@ -395,6 +395,15 @@ options:
   - mds
   flags:
   - runtime
+- name: mds_dir_prefetch
+  type: bool
+  level: advanced
+  desc: flag to prefetch entire dir
+  default: true
+  services:
+  - mds
+  flags:
+  - runtime
 - name: mds_tick_interval
   type: float
   level: advanced
index 5bd44be7f4c14b89401f636577141ab5eac757c9..31b5eff331cbdf8edb3a304aec6416aed3af6c2a 100644 (file)
@@ -1567,7 +1567,7 @@ void CDir::fetch(std::string_view dname, snapid_t last,
 
   // FIXME: to fetch a snap dentry, we need to get omap key in range
   //       [(name, last), (name, CEPH_NOSNAP))
-  if (!dname.empty() && last == CEPH_NOSNAP) {
+  if (!dname.empty() && last == CEPH_NOSNAP && !g_conf().get_val<bool>("mds_dir_prefetch")) {
     dentry_key_t key(last, dname, inode->hash_dentry_name(dname));
     fetch_keys({key}, c);
     return;
@@ -1594,7 +1594,7 @@ void CDir::fetch(std::string_view dname, snapid_t last,
 
 void CDir::fetch_keys(const std::vector<dentry_key_t>& keys, MDSContext *c)
 {
-  dout(10) << "fetch " << keys.size() << " keys on " << *this << dendl;
+  dout(10) << __func__ << " " << keys.size() << " keys on " << *this << dendl;
   ceph_assert(is_auth());
   ceph_assert(!is_complete());
 
@@ -2132,7 +2132,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   for (auto p = omap.rbegin(); p != omap.rend(); ++p, --pos) {
     string_snap_t key;
     dentry_key_t::decode_helper(p->first, key.name, key.snapid);
-    bool touch;
+    bool touch = false;
 
     if (key.snapid == CEPH_NOSNAP) {
       if (complete) {
@@ -2141,8 +2141,6 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
        touch = proc_nulls_and_waiters(p->first, key);
       }
       last_name = std::string_view(p->first.c_str(), key.name.length());
-    } else {
-      touch = false;
     }
 
     CDentry *dn = nullptr;
index eb0bc7e645a0c83c98e912a197450f1e216e3a8c..8e97ee551990978e550964eb89dd3a35f45ce9a2 100644 (file)
@@ -5974,19 +5974,28 @@ bool MDCache::open_undef_inodes_dirfrags()
   map<CDir*, pair<bool, std::vector<dentry_key_t> > > fetch_queue;
   for (auto& dir : rejoin_undef_dirfrags) {
     ceph_assert(dir->get_version() == 0);
-    (void)fetch_queue[dir];
+    fetch_queue.emplace(std::piecewise_construct, std::make_tuple(dir), std::make_tuple());
   }
 
-  for (auto& in : rejoin_undef_inodes) {
-    assert(!in->is_base());
-    CDentry *dn = in->get_parent_dn();
-    auto& p = fetch_queue[dn->get_dir()];
-    if (dn->last != CEPH_NOSNAP) {
-      p.first = true;
-      p.second.clear();
-    } else if (!p.first) {
-      p.second.push_back(dn->key());
+  if (g_conf().get_val<bool>("mds_dir_prefetch")) {
+    for (auto& in : rejoin_undef_inodes) {
+      ceph_assert(!in->is_base());
+      ceph_assert(in->get_parent_dir());
+      fetch_queue.emplace(std::piecewise_construct, std::make_tuple(in->get_parent_dir()), std::make_tuple());
     }
+  } else {
+    for (auto& in : rejoin_undef_inodes) {
+      assert(!in->is_base());
+      CDentry *dn = in->get_parent_dn();
+      auto& p = fetch_queue[dn->get_dir()];
+
+      if (dn->last != CEPH_NOSNAP) {
+        p.first = true;
+        p.second.clear();
+      } else if (!p.first) {
+        p.second.push_back(dn->key());
+      }
+         }
   }
 
   if (fetch_queue.empty())