From: shenhang Date: Fri, 10 Sep 2021 10:59:49 +0000 (+0800) Subject: mds: add an option to decide whether prefetching entire dir or not. X-Git-Tag: v18.0.0~1394^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F39315%2Fhead;p=ceph.git mds: add an option to decide whether prefetching entire dir or not. 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" --- diff --git a/qa/cephfs/overrides/prefetch_entire_dirfrags/no.yaml b/qa/cephfs/overrides/prefetch_entire_dirfrags/no.yaml new file mode 100644 index 000000000000..41903ef45fca --- /dev/null +++ b/qa/cephfs/overrides/prefetch_entire_dirfrags/no.yaml @@ -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 index 000000000000..143865a33f1a --- /dev/null +++ b/qa/cephfs/overrides/prefetch_entire_dirfrags/yes.yaml @@ -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 index 000000000000..9b8024fbadd1 --- /dev/null +++ b/qa/suites/fs/thrash/workloads/overrides/prefetch_entire_dirfrags @@ -0,0 +1 @@ +.qa/cephfs/overrides/prefetch_entire_dirfrags \ No newline at end of file diff --git a/src/common/options/mds.yaml.in b/src/common/options/mds.yaml.in index 697710484c8f..3a6464ebcdd7 100644 --- a/src/common/options/mds.yaml.in +++ b/src/common/options/mds.yaml.in @@ -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 diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 5bd44be7f4c1..31b5eff331cb 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -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("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& 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& 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& 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; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index eb0bc7e645a0..8e97ee551990 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -5974,19 +5974,28 @@ bool MDCache::open_undef_inodes_dirfrags() map > > 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("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())