max: 4_K
flags:
- runtime
+- name: mds_use_global_snaprealm_seq_for_subvol
+ type: bool
+ level: advanced
+ default: true
+ services:
+ - mds
+ fmt_desc: MDS will use the global snaprealm's seq to cow old inodes
+ for the directory. If the option is disabled, MDS will use the
+ respective snaprealm seq number for the subvolume snapshot directory
+ i.e., the directory marked with the 'ceph.dir.subvolume'. This is
+ safe because the hardlinks/renames are contained within the subvolume
+ snaprealm with the marking of 'ceph.dir.subvolume'. For the directories
+ above subvolume, it will use the global snaprealm's seq only if there
+ is at least one snapshot of the directory above the subvolume.
+ If the option is enabled, which is the default, it uses the global
+ snaprealm's seq to cow old inodes across the filesystem. Hence,
+ disabling this option is only suitalbe for the cephfs volumes used
+ purely for subvolume usecase where there are no snapshots in the
+ filesystem apart from the subvolume snapshots. So it's a great
+ optimization for subvolumes.
+ flags:
+ - runtime
- name: mds_asio_thread_count
type: uint
level: advanced
void CInode::pre_cow_old_inode()
{
- snapid_t follows = mdcache->get_global_snaprealm()->get_newest_seq();
- dout(20) << __func__ << " follows " << follows << " on " << *this << dendl;
+ snapid_t follows;
+ bool using_global_snaprealm_seq = true;
+ SnapRealm *realm = find_snaprealm();
+ //bool use_global_snaprealm_seq = mdcache->use_global_snaprealm_seq;
+
+ if (mdcache->get_use_global_snaprealm_seq()) {
+ follows = mdcache->get_global_snaprealm()->get_newest_seq();
+ } else if (realm->get_subvolume_ino() || realm->get_newest_seq() <= 1 ) {
+ /* Config is disabled :
+ 1. If it's a subvolume realm, obviously use realm's seq number.
+ 2. If there are no snaps on that directory, use realm's seq number.
+ a. In a pure subvolume use case, updates outside the subvolume directory
+ from group directory (/volumes/<group>/<subvol> to root would use realm's
+ seq number to avoid unnecessary cow of old inodes.
+ b. In a non subvolume use case, use realm's seq number only if there are
+ no snaps. If there are snaps, always use global snaprealm's seq as there
+ could be hardlinks/renames.
+ */
+ follows = realm->get_newest_seq();
+ using_global_snaprealm_seq = false;
+ } else {
+ /* Config is disabled:
+ * 1. In a pure subvolume use case, if there is atleast one snap in the realm (between
+ * root and subvolume snap path), use global snaprealm's seq number.
+ * 2. In a non subvolume use case, if there is atleast one snap in the realm,
+ * use global snaprealm's seq number.
+ */
+ follows = mdcache->get_global_snaprealm()->get_newest_seq();
+ }
+
+ dout(20) << __func__ << " using_global_snaprealm_seq:" << (using_global_snaprealm_seq ? "yes ":"no ")
+ << " follows " << follows << " on " << *this << " snaprealm=" << *realm << dendl;
if (first <= follows)
cow_old_inode(follows, true);
}
kill_dirfrag_at = static_cast<enum dirfrag_killpoint>(g_conf().get_val<int64_t>("mds_kill_dirfrag_at"));
kill_shutdown_at = g_conf().get_val<uint64_t>("mds_kill_shutdown_at");
+ use_global_snaprealm_seq = g_conf().get_val<bool>("mds_use_global_snaprealm_seq_for_subvol");
lru.lru_set_midpoint(g_conf().get_val<double>("mds_cache_mid"));
if (changed.count("mds_kill_shutdown_at")) {
kill_shutdown_at = g_conf().get_val<uint64_t>("mds_kill_shutdown_at");
}
+ if (changed.count("mds_use_global_snaprealm_seq_for_subvol")) {
+ use_global_snaprealm_seq = g_conf().get_val<bool>("mds_use_global_snaprealm_seq_for_subvol");
+ dout(20) << __func__ << " mds_use_global_snaprealm_seq_for_subvol now " << use_global_snaprealm_seq << dendl;
+ }
migrator->handle_conf_change(changed, mdsmap);
mds->balancer->handle_conf_change(changed, mdsmap);
return symlink_recovery;
}
+ bool get_use_global_snaprealm_seq(void) const {
+ return use_global_snaprealm_seq;
+ }
+
/**
* Call this when you know that a CDentry is ready to be passed
* on to StrayManager (i.e. this is a stray you've just created)
// -- snaprealms --
SnapRealm *global_snaprealm = nullptr;
+ bool use_global_snaprealm_seq = true;
std::map<dirfrag_t, ufragment> uncommitted_fragments;
"mds_session_cap_acquisition_throttle",
"mds_session_max_caps_throttle_ratio",
"mds_session_metadata_threshold",
- "mds_symlink_recovery"
+ "mds_symlink_recovery",
+ "mds_use_global_snaprealm_seq_for_subvol"
});
static_assert(std::is_sorted(as_sv.begin(), as_sv.end()),
"keys are not sorted!");