StrayManager類說明:
class StrayManager {
elist<CDentry*> delayed_eval_stray;
list<QueuedStray> ready_for_purge;
MDSRank *mds;
uint64_t ops_in_flight;
uint64_t files_purging;
uint64_t max_purge_ops;
uint64_t num_strays;
uint64_t num_strays_purging;
uint64_t num_strays_delayed;
Filer filer;
};node
StrayManager類方法:
StrayManager::purge(dn, op_allowance) 實際上就是從集羣中刪除指定dentry對應的inode信息
|__從dn獲得CDentry對應的CInode類對象in
|__增長num_strays_purging的值
|__若in是目錄
|__根據mds所在的metadata_pool信息,獲得in對象所在的pool位置
|__若in目錄在dirfragtree上不是葉子節點
|__獲得in目錄在dirfragtree上的全部葉子節點
|__遍歷全部葉子節點
|__獲得葉子節點的oid信息,即:CInode::get_object_name(in->inode.ino, *p, "");
|__從pool裏刪除該葉子節點,即:mds->objecter->remove(oid, oloc,...)
|__直接返回
|__從in中獲得全部的SnapRealm信息
|__SnapRealm有效
|__獲得SnapRealm的上下文信息,即:snapc = &realm->get_snap_context()
|__SnapRealm無效
|__設置snapc爲nullsnapc
|__獲得in的projected inode信息
|__獲得projected_inode的oid,即:oid = CInode::get_object_name(pi->ino, frag_t(), "")
|__刪除backtrace對象,即:mds->objecter->remove(oid, oloc,...)
|__遍歷old backtrace對象集合,即:pi->old_pools
|__刪除backtrace對象,即:mds->objecter->remove(oid, oloc,...)數組
StrayManager::_purge_stray_purged(dn, ops_allowance, only_head)
|__從dn獲得CDentry對應的CInode類對象in
|__若only_head==true
|__建立EUpdate類對象
|__設置mds的mdlog的start_entry爲EUpdate類對象,即:mds->mdlog->start_entry(le)
|__獲得in的project_inode信息
|__初始化project_inode信息
|__設置LogEvent類對象(le)中metablob的dir_context,即:le->metablob.add_dir_context()
|__向LogEvent類對象(le)中medtablob中添加primary dentry,即:le->metablob.add_primary_dentry()
|__向MDLog提交entry,即:mds->mdlog->submit_entry()
|__若only_head==false
|__建立EUpdate類對象
|__設置mds的mdlog的start_entry爲EUpdate類對象,即:mds->mdlog->start_entry(le)
|__設置LogEvent類對象(le)中metablob的dir_context,即:le->metablob.add_dir_context()
|__在LogEvent的metablob中添加一個dir,即:le->metablob.add_dir()
|__在LogEvent的metablob中添加一個空的dentry,即:le->metablob.add_null_dentry()
|__在LogEvent的metablob中添加一個destroyed inode,即:le->metablob.add_destroyed_inode()
|__向MDLog提交entry,即:mds->mdlog->submit_entry()
|__遞減num_strays_purging
|__從ops_in_flight中減去ops_allowance
|__調用_advance()ui
StrayManager::_advance()
|__遍歷ready_for_purge集合(QueuedStray集合)
|__調用_consume()
|__若_consume()返回true
|__中止遍歷
|__刪除ready_for_purge集合中從開始到_consume()返回true的節點對象
StrayManager::_consume(dn, trunc, ops_required)
|__從配置文件中獲取到目前能夠purge的文件數量,即:g_conf->mds_max_purge_files-files_purging;
|__若files_avail<=0
|__直接返回
|__若ops_in_flight<=max_purge_pos
|__ops_avail = max_purge_ops - ops_in_flight
|__若ops_in_flight>max_purge_pos
|__ops_avail = 0
|__若ops_in_flight>0而且ops_avail<ops_required
|__直接退出並返回false
|__增長ops_in_flight數值,即:ops_in_flight += ops_required
|__若trunc==true
|__truncate(dn, ops_required)
|__若trunc==false
|__purge(dn, ops_required)
|__返回true進程
StrayManager::_purge_stray_logged(dn, pdv, ls)
|__從dn獲得CDentry對應的CInode類對象in
|__從dn所在的dir目錄下刪除該dn,即:dn->dir->unlink_inode(dn)
|__從dn所在的dir目錄下刪除projected fnode,即:dn->dir->pop_and_dirty_projected_fnode(ls)
|__從MDCache中刪除in,即:in->mdcache->remove_inode(in)
|__若dn是new
|__從dn所在的dir目錄下刪除該dn,即:dn->dir->remove_dentry(dn)
|__若dn不是new
|__在MDCache中將dn設置到dentry的bottom,即:in->mdcache->touch_dentry_bottom(dn)ip
StrayManager::_calculate_ops_required(in, trunc)
|__若in是目錄
|__ops_reqired數量=1+in在dirfragtree下的葉子節點個數
|__若in不是目錄
|__ops_reqired數量=1+g_conf->filer_max_purge_opsrem
StrayManager::enqueue(dn, trunc)
|__從dn獲得CDentry對應的CInode類對象in
|__設置dn的狀態爲STATE_PURGING
|__設置in的狀態爲STATE_PURGING
|__根據in和trunc計算一下所需的ops數,即:_calculate_ops_required(in, trunc)
|__若ready_for_purge數組不爲空
|__調用_consume(dn, trunc, ops_required)
|__若_consume()返回false
|__將dn從新插入到ready_for_purge數組,即:ready_for_purge.push_back()get
StrayManager::advance_delayed()
|__遍歷delayed_eval_stray數組
|__從dn的item_stray數組中刪除本身,即:dn->item_stray.remove_myself()
|__遞減num_strays_delayedit
StrayManager::_eval_stray(dn, delay) 檢查dn及其對應的CInode是否知足stray的條件,若知足則返回true,不然返回false
|__從dn獲得CDentry對應的CInode類對象in
|__若dn不是auth的
|__在MDCache中將dn設置到dentry的bottom,以後會當即被trim掉。即:in->mdcache->touch_dentry_bottom(dn)
|__返回false
|__若dn在item_stray數組中
|__從item_stray數組中刪除本身,即:dn->item_stray.remove_myself()
|__遞減num_strays_delayed
|__若in的inode link爲0
|__若in中包含有snaprealm
|__若in的snaprealm沒有past_parents_open而且沒有open parents
|__返回false
|__從in的snaprealm中刪除past parents,即:in->snaprealm->prune_past_parents()
|__從in中刪除stale snap data,即:in->purge_stale_snap_data()
|__若in是目錄
|__若in中包含有snaprealm且in的snamrealm中包含past parents
|__返回false
|__若in中包含dirfrags
|__獲得該in下全部的dirfrags
|__遍歷全部的dirfrags
|__刪除全部的dirfrags,即:(*p)->try_remove_dentries_for_stray()
|__若in的remote parents不爲空,說明in仍然有遠程連接
|__遍歷in的remote parents數組
|__刪除遠程連接,即:remote_dn->unlink_remote(remote_dn->get_linkage())
|__若dn是replicted,即:dn的replica_map不爲空
|__返回false
|__若dn仍然有any leases或仍然有any caps
|__返回false
|__若dn的當前狀態是STATE_NEEDSRECOVER或STATE_RECOVERING
|__返回false
|__若in的引用計數>in的dirty數量+1
|__返回false
|__若delay==true
|__若dn不在item_stray數組中
|__將dn->item_stray數組插入到delayed_eval_stray數組中,即:delayed_eval_stray.push_back(dn->item_stray)
|__若delay==false而且in擁有snaprealm而且in的snaprealm包含past parents而且in的old_inodes不爲空
|__若in是文件而且in的projected inode的大小大於0
|__enqueue(dn, true)
|__其餘條件
|__若in是目錄
|__關閉in的全部dirfrags,即:in->close_dirfrags()
|__enqueue(dn, false)
|__返回true
|__若in的inode link不爲0
|__調用eval_remote_stray(dn, NULL)
|__返回falseast
StrayManager::eval_stray(dn, delay)
|____eval_stray(dn, delay)
-
StrayManager::eval_remote_stray(stray_dn, remote_dn) 當待評估的dn的nlink大於0,則須要評估遠程的dn是不是stray
|__從dn獲得CDentry對應的CInode類對象in
|__若remote_dn爲空
|__若stray_in的remote_parents不爲空
|__遍歷stray_in的remote_parents數組
|__若數組中成員的last==CEPH_NOSNAP
|__將數組中成員賦值給remote_dn
|__若remote_dn爲空,即:沒有在stray_in的remote parents數組中找到last==CEPH_NOSNAP的
|__直接返回
|__若remote_dn不是projected
|__若remote_dn是auth的而且remote_dn對應的CDir能auth pin
|__reintegrate_stray(stray_dn, remote_dn)
|__不然,若remote_dn不是auth而且stray_dn是auth的
|__migrate_stray(stray_dn, remote_dn->authority().first)
StrayManager::reintegrate_stray(straydn, rdn)
|__獲得straydn的完整路徑,即:straydn->make_path(src)
|__獲得remotedn的完整路徑,即:rdn->make_path(dst)
|__建立MClientRequest類消息且消息類型是CEPH_MDS_OP_RENAME
|__設置源和目的filepath
|__設置tid
|__將消息發送給rdn受權的第一個MDS進程,即:mds->send_message_mds(req, rdn->authority().first)
StrayManager::migrate_stray(dn, to)
|__從dn獲得CDentry對應的CInode類對象in
|__獲得dn對應的dir的CInode類對象diri
|__獲得dn的完整路徑,即:dn->make_path(src)
|__獲得in的stray dentry名字,即:in->name_stray_dentry(dname)
|__建立MClientRequest類消息且消息類型是CEPH_MDS_OP_RENAME
|__設置源和目的filepath
|__設置tid
|__將消息發送給to這個MDS進程,即:mds->send_message_mds(req, to)
StrayManager::abort_queue()
|__遍歷ready_for_purge集合
|__從集合成員QueuedStray中獲得CDentry
|__從Cdentry獲得CInode
|__清除dn的STATE_PURGING狀態,即:dn->state_clear(STATE_PURGING)
|__清除in的STATE_PURGING狀態,即:in->state_clear(STATE_PURGING)
|__清空ready_for_purge集合
StrayManager::truncate(dn, op_allowance)
|__從dn獲得CDentry對應的CInode類對象in
|__從in中獲得snaprealm信息
|__從snaprealm中獲得SnapContext信息
|__獲得in->inode.size和in->inode.get_max_size()以及in->inode.max_size_ever的最大值
|__若該最大值大於0
|__從Striper獲得該inode的條帶個數,即:Striper::get_num_objects(in->inode.layout, to)
|__若條帶個數大於1
|__經過filer purge指定數量的條帶,即:filer.purge_range()
|__經過filer清空指定inode,即:filer.zero()
StrayManager::_truncate_stray_logged(dn, ls)
|__從dn獲得CDentry對應的CInode類對象in
|__清除dn的STATE_PURGING狀態,即:dn->state_clear(STATE_PURGING)
|__從in中dirty projected inode,即:in->pop_and_dirty_projected_inode(ls)
|__eval_stray(dn)
StrayManager::update_op_limit() |__從mds的objecter裏獲得當前的osdmap |__從mdspmap中獲得全部的data pool |__遍歷data pool |__累加全部data pool的pg數量 |__從mdsmap中獲得當前可用的最大mds數量 |__計算可用於purge的操做個數,即:n_pgs/n_mdss*g_conf->mds_max_purge_ops_per_pg |__若配置文件中包含mds_max_purge_ops |__將max_purge_ops和配置文件中的mds_max_purge_ops的最小值賦值給max_purge_ops