MDCache類分析

class MDCache {node

     //my mastersapi

     MDSRank *mds;          MDCache所處的MDSRank數組

     //my cacheapp

     LRU lru;                         最近最少使用列表(保存dentries)函數

     unordered_map<vinodeno_t, CInode*> inode_map;     inode映射關係(保存inodes)fetch

     CInode *root;          根CInodeui

     CInode *myin;this

     CInode *strays[10];日誌

     int stray_index;對象

     set<CInode*> base_inodes;

     Filer filer;          與OSD操做的接口類

     DecayRate     decayrate;     

     file_layout_t     default_file_layout;          存儲文件默認的layout

     file_layout_t     default_log_layout;          存儲日誌默認的layout

     //client leases

     float client_lease_durations[3];

     xlist<ClientLease*> client_leases[3];

     //discover

     map<ceph_tid_t, discover_info_t> discovers;

     ceph_tid_t      discover_last_tid;

     //subtrees

     map<CDir*, set<CDir*>> subtrees;     子樹 

     map<CInode*, list<piar<CDir*, CDir*>>> projected_subtree_renames;

     //delayed cache expire

     map<CDir*, map<mds_rank_t, MCacheExpire*>> delayed_expire;

     //request

     unordered_map<metareqid_t, MDRequestRef> active_requests;

     //recovery

     set<mds_rank_t> recovery_set;

     //file size recovery

     RecoveryQueue recovery_queue;

     //subsystems

     Migrator *migragor;

};

 

全部非I/O上下文的使用class MDCacheContext類

全部I/O上下文的使用cass MDCacheIOContext類

 

=================some inode functions======================

 

MDS

MDSDIR

INO LOG

INO LOG BACKUP

INO_LOG POINTER

INO STRAY

INO SYSTEM BASE

0         0x100       0x200        0x300                    0x400                     0x600            0x600+(MDS*STRAY)     

 

MDCache::add_inode(CInode* in)

|__更新inode_map數組,即:inode_map[in->vino()] = in

|__若in的inode編號小於INO_SYSTEM_BASE

     |__若in的inode編號==1

          |__設置root=in

     |__若in的inode編號位於MDSDIR範圍內

          |__設置myin=in

     |__若in的當前狀態是stray的

          |__若in的inode編號位於INO_STRAY範圍內

               |__更新strays數組,即:strays[MDS_INO_STRAY_INDEX(in->ino()]=in

     |__若in的inode編號是1或者位於MDSDIR範圍內

          |__更新base_inodes數組,即:base_inodes.insert(in)

 

MDCache::remove_inode(CInode *o)

|__若o的parent dentry不爲空

     |__從o的parent dentry對應的dir裏刪除o,即:dn=o->get_parent_dn(); dn->dir->unlink_inode(dn) 

|__若o是dirty的

     |__o->mark_clean()

|__若o是parent dirty

     |__o->clear_dirty_parent()

|__從inode_map數組中刪除o,即:inode_map.erase(o->ino())

|__若o的inode編號小於INO_SYSTEM_BASE

     |__若o的inode編號==1

          |__設置root=0

     |__若o的inode編號位於MDSDIR範圍內

          |__設置myin=0

     |__若o的當前狀態是stray的

          |__若o的inode編號位於INO_STRAY範圍內

               |__更新strays數組,即:strays[MDS_INO_STRAY_INDEX(o->ino()]=0

     |__若o的inode編號是1或者位於MDSDIR範圍內

          |__更新base_inode數組,即:base_inode.erase(o)

|__刪除o

 

MDSCache::gen_default_file_layout(MDSMap mdsmap)

|__調用file_layout_t的get_default()函數獲得一個默認的file_layout_t類對象(默認的file_layout_t對象的stripe_unit=4MB, stripe_count=1, object_size=4MB, pool_id=-1)

|__設置默認的file_layout_t對象的pool_id=mdsmap中的第一個data pool

 

MDSCache::get_default_log_layout(MDSMap mdsmap)

|__調用file_layout_t的get_default()函數獲得一個默認的file_layout_t類對象(默認的file_layout_t對象的stripe_unit=4MB, stripe_count=1, object_size=4MB, pool_id=-1)

|__設置默認的file_layout_t對象的pool_id=mdsmap中的metadata pool

 

MDCache::init_layouts()

|__調用gen_default_file_layout()函數獲得default_file_layout

|__調用get_default_log_layout()函數獲得default_log_layout

 

MDCache::create_unlinked_system_inode(CInode *in, inodeno_t ino, int mode)

|__初始化in的inode成員(inode_t)

|__初始化in的inode成員中的dir_layout

|__若in是目錄

     |__設置in的inode成員中的dir_layout的dl_dir_hash爲mds_default_dir_hash值

|__若in不是目錄

     |__設置in的inode成員中的layout爲default_file_layout

|__若in的inode編號是1或者位於MDSDIR範圍內

     |__若in是root

          |__設置in的inode_auth爲mds_authority_t(mds->get_nodeid(), UNKNOWN)

     |__若in不是root     

          |__設置in的inode_auth爲mds_authority_t(mds_rank_t(in->ino() - MDS_INO_MDSDIR_OFFSET), CDIR_AUTH_UNKNOWN)

     |__調用in的open_snaprealm()來初始化snap

     |__設置snaprealm的序列號爲1,即:in->snaprealm->srnode.seq=1

 

MDCache::create_system_inode(inodeno_t ino, int mode)

|__建立CInode類對象

|__調用create_unlinked_system_inode()初始化CInode類對象

|__調用add_inode()將建立並初始化後的CInode添加到inode_map中

 

MDCache::create_root_inode()

|__調用create_system_inode()建立並初始化root CInode並將root添加到inode_map中

|__設置root CInode的uid/gid=0/0

|__設置root CInode的layout爲default_file_layout

|__設置root CInode的layout的pool_id爲mdsmap中第一個data pool

 

MDCache::create_empty_hierarchy(MDSGather *gather)

|__調用create_root_inode()建立root CInode

|__調用root的get_or_open_dirfrag()函數獲得root的CDir類對象

|__調用adjust_subtree_auth()函數更新rootdir的auth

|__調整rootdir的一系列統計字段(rootdir->fnode.accounted_fragstat/rootdir->fnode.accounted_rstat/root->inode.dirstat/root->inode.rstat/root->inode.acounted_rstat)

|__調用rootdir->mark_dirty()     標識rootdir被修改過

|__調用rootdir->commit()          將rootdir寫入到集羣metadata pool

|__調用root->store()                  將root寫入到集羣metadata pool

 

MDCache::create_mydir_hierarchy(MDSGather *gather)

|__獲得mydir的名稱,即:mds%d

|__調用create_system_inode()建立並初始化mydir CInode並將mydir添加到inode_map中

|__調用mydir的get_or_open_dirfrag()函數獲得mydir的CDir類對象

|__調用adjust_subtree_auth()函數更新mydir的auth

|__建立10個stray dir

     |__調用create_system_inode()建立並初始化stray CInode並將stray添加到inode_map中

     |__調用stray的get_or_open_dirfrag()函數獲得stray的CDir類對象straydir

     |__獲得stray的名稱,即:stray%d

     |__調用mydir->add_primary_dentry()將stray對應的CDentry添加到mydir的items數組中

     |__提交保存straydir數據到集羣metadata pool,即:straydir->commit()

     |__保存stray數據到集羣metadata pool,即:stray->store_backtrace()

|__調整mydir的一系列統計字段(mydir->fnode.accounted_fragstat/mydir->fnode.accounted_rstat/myin->inode.dirstat/myin->inode.rstat/myin->inode.acounted_rstat)

|__調用mydir->commit()          將mydir寫入到集羣metadata pool

|__調用myin->store()               將myin寫入到集羣metadata pool

 

MDCache::_create_system_file(CDir *dir, char *name, CInode *in, MDSInternalContextBase *fin)

|__調用dir->add_null_entry(name)     將根據name建立的CDentry類對象dn插入到dir的items數組中

|__調用dn->push_projected_linkage(in)     將in做爲dn的projected linkage

|__若in是目錄

     |__經過調用in->get_or_open_dirfrag()獲得in對應的CDir類對象mdir

|__經過dir的CInode的到SnapRealm類對象

|__根據SnapRealm類對象中的seq值初始化dn->first以及in->first值

|__建立MutationImpl類對象

|__建立EUpdate類對象

|__調用mds->mdlog->start_entry(EUpdate)     開啓mdlog

|__若in不是mdsdir

     |__predirty_journal_parents()

     |__調用le->metablob.add_primary_dentry()     更新metablob

|__若in是mdsdir

     |__predirty_journal_parents()

     |__journal_dirty_inode()

     |__調用le->metablob.add_remote_dentry()

     |__調用le->metablob.add_root()

|__若mdir不爲空

     |__調用le->metablob.add_new_dir(mdir)          建立一個新的dir

|__調用mds->mdlog->submit_entry()                    提交log

|__調用mds->mdlog->flush()                                 刷新log

 

MDCache::_create_system_file_finish(MutationRef mut, CDentry *dn, version_t dpv, MDSInternalContextBase *fin)

|__調用dn->pop_projected_linkage()     將in從projected linkage中刪除

|__調用dn->mark_dirty()                         標記dentry是dirty的

|__獲得dn對應的CInode類對象,即:dn->get_linkage()->get_inode()

|__調用in->mark_dirty()                          標記dentry對應的CInode是dirty的

|__若in是目錄

     |__調用in->get_dirfrag()                    獲得in對應的CDir類對象dir

     |__調用dir->mark_dirty()                    標記in對應的CDir是dirty的

|__調用mut->apply()

|__調用fin->complete(0)

 

MDCache::open_root_inode(MDSInternalContextBase *c)

|__若mds的nodeid==mdsmap的root

     |__調用create_system_inode(MDS_INO_ROOT)     建立root inode

     |__調用in->fetch(c)          從集羣裏讀取root inode信息到MDCache

|__若mds的nodeid!=mdsmap的root

     |__調用discover_base_ino(MDS_INO_ROOT, c, mds->mdsmap->get_root())     經過discover流程找到root inode

 

MDCache::open_mydir_inode(MDSInternalContextBase *c)

|__調用create_system_inode(MDS_INO_MDSDIR(mds->get_nodeid())     建立mydir inode

|__調用in->fetch(c)          從集羣裏讀取mydir inode信息到MDCache

 

MDCache::open_root()

|__若root爲空

     |__調用open_root_inode()          建立或者發現root

     |__直接返回

|__若mds的root位於此mds上

     |__調用root->get_or_open_dirfrag()獲得rootdir對應餓CDir類對象

     |__若rootdir不是subtree_root

          |__調用adjust_subtree_auth()     更新rootdir的subtree auth

     |__若rootdir未完成

          |__調用rootdir->fetch()     從集羣中讀取rootdir信息到MDCache

|__若mds的root不在此mds上

     |__調用root->get_dirfrag()     在此MDS上找出rootdir

     |__若rootdir爲空

          |__調用discover_dir_frag()函數在MDS集羣中找到rootdir並寫入到MDCache中

          |__直接返回

|__若myin爲空

     |__調用create_system_inode(MDS_INO_MDSDIR(mds->get_nodeid()))建立mydir對應的CInode類對象

     |__調用in->fetch()     從集羣中獲取mydir類對象並寫入到集羣

     |__直接返回

|__獲得myin對應的CDir類對象,即:myin->get_or_open_dirfrag()

|__調用adjust_subtree_auth(mydir)          更新mydir的目錄權限

|__調用populate_mydir()                    填充mydir目錄

 

MDCache::populate_mydir()

|__獲得myin對應的CDir類對象,即:mydir=myin->get_or_open_dirfrag()

|__若mydir未完成

     |__調用mydir->fetch()     從集羣中獲取mydir信息

     |__直接返回

|__若mydir的版本號是0而且mydir的狀態是STATE_BADFRAG

     |__清空mydir的STATE_BADFRAG狀態

     |__調用mydir->mark_dirty()

|__遍歷10個Stray

     |__從mydir目錄下查找到stray對應的CDentry,即:straydn=mydir->lookup()

     |__若straydn爲空或者straydn對應的CInode爲空

          |__調用_create_system_file()     建立stray inode並添加到inode_map中

          |__直接返回

     |__在dirfragtree中獲得stray下的葉子節點

     |__遍歷葉子節點

          |__獲得葉子節點對應的CDir類對象,即:dir=stray[i]->get_dirfrag()

          |__若dir爲空

               |__調用strays[i]->get_or_open_dirfrag()獲得dir類對象

          |__若dir的版本號爲0

               |__調用dir->fetch()     從集羣中讀取CDir類對象的內容到MDCache

|__設置open=true

|__調用scan_stray_dir()來掃描stray dir

 

MDCache::scan_stray_dir(dirfrag_t next)

|__遍歷strays數組

     |__獲取到strays數組中CInode成員對應的CDir類對象

|__遍歷strays數組中CInode成員對應的CDir類對象

     |__若CDir類對象爲完成

         |__調用dir->fetch()函數從集羣中獲取CDir類對象的內容到MDCache

         |__直接返回

     |__遍歷每一個CDir下的CDentry,即:遍歷CDir下的items數組

          |__從items數組成員中獲得CDentry類對象

          |__設置CDentry類對象的當前狀態是STATE_STRAY

          |__若CDentry的projected linkage是primary

               |__獲得CDentry對應的CInode類對象

               |__若CInode對應的nlink==0

                    |__設置CInode的狀態爲STATE_ORPHAN

               |__調用maybe_eval_stray(in)

 

MDCache::maybe_eval_stray(CInode *in, bool delay)

|__若in的nlink數>0或者in是base或者MDCache是readonly或者mds處於standby replay狀態

     |__直接返回

|__獲得in的parent dentry類對象dn

|__若dn的當前狀態是STATE_PURGING

     |__直接返回

|__若dn是primary而且dn所在的dir是stray狀態

     |__由stray manager來處理dn(嘗試刪除dn對應的CInode和CDir),即:stray_manager.eval_stray(dn, delay)

 

MDCache::open_foreign_mdsdir(inodeno_t ino, MDSInternalContextBase *fin)

|__調用discover_base_ino()函數從其餘的MDS節點處尋找inode number是ino的inode節點信息

 

MDCache::get_or_create_stray_dentry(CInode *in)

|__調用in->name_stray_dentry()獲得in的strayname,即:in的inode編號

|__獲得當前stray_index指定的strays數組項,即:strayi=get_stray()

|__由strayi獲得strayname對應的dirfrag_t,即:strayi->pick_dirfrag(strayname)

|__由dirfrag_t獲得對應的CDir類對象(straydir)和CDentry類對象(straydn)

|__若CDentry類對象爲空

     |__在straydir的items數組中添加由strayname構成的CDentry

     |__新建立的CDentry標識new,即:straydn->mark_new()

|__通知stray manager有新的stray,即:stray_manager.notify_stray_created()

|__設置straydn的當前狀態爲STATE_STRAY

|__返回straydn

 

MDCache::get_object(MDSCacheObjectInfo info)

|__若info.ino不爲空

     |__調用get_inode(info.ino, info.snapid)     獲得MDCache中對應的CInode

     |__返回MDCache中的CInode

|__調用get_dirfrag(info.dirfrag)獲得dirfrag對應的CDir類對象dir

|__若dir爲空

     |__返回0

|__若info.dname不爲空

     |__調用dir->lookup(info.dname, info.snapid)獲得snapid指定的dir

     |__返回dir

|__若info.dname爲空

     |__返回dir

 

=======================subtree management==========================

MDCache::list_subtrees(list<CDir*> ls)

|__遍歷subtrees數組

     |__將subtrees數組中的父目錄添加到ls數組中,即:ls.push_back(p->first)

 

MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth, bool do_eval)     調整dir目錄及其子目錄的auth

|__若mds當前狀態是replay狀態或者resolve狀態

     |__設置do_eval=false

|__若dir是base

     |__設置root=dir

|__若dir不是base

     |__調用get_subtree_root(dir)來找到dir的root dir

|__若root==dir

     |__設置dir的auth信息,即:dir->set_dir_auth(auth)

|__若root!=dir

     |__設置dir的auth信息,即:dir->set_dir_auth(auth)

     |__遍歷subtrees數組中以root爲索引的全部CDir集合

          |__若數組成員的parent dir==dir

               |__將數組成員從subtrees的root索引處刪除

               |__將數組成員添加到subtrees的dir索引處

     |__將dir添加到subtrees[root]中

     |__設置root=dir

     |__若do_eval==true

          |__調用eval_subtree_root()來評估dir subtree的鎖的使用狀況

 

MDCache::try_subtree_merge(CDir *dir)     將dir及其子目錄的全部內容合併到對應的parent目錄中,以後將dir及其子目錄從subtrees數組中刪除

|__從subtrees數組中獲得dir下全部的CDir集合,即:oldbounds=subtrees[dir]

|__調用try_subtree_merge_at(dir)函數嘗試merge subtree

|__遍歷oldbounds數組

     |__對於數組成員調用try_subtree_merge_at(*p)函數嘗試merge subtree中的目錄

 

MDCache::try_subtree_merge_at(CDir *dir, bool do_eval)

|__若mds當前狀態是replay狀態或者resolve狀態

     |__設置do_eval=false

|__若dir不是base     

     |__調用get_subtree_root()函數獲得dir對應的parent

|__若dir!=parent而且dir和parent的auth是一致的而且auth是ambiguous

     |__設置dir的auth爲CDIR_AUTH_DEFAULT

     |__遍歷以dir爲索引的subtrees數組

          |__將數組中的內容添加到subtrees[parent]下

     |__在subtrees數組中刪除dir項

     |__在subtrees[parent]下刪除dir項

     |__若do_eval==true

          |__調用eval_subtree_root()函數

     |__若dir是auth的而且mds處於active狀態

          |__獲得dir對應的CInode信息,即:in=dir->inode

          |__設置in的auth_pin,即:in->auth_pin(this)

          |__建立MutationImpl類對象

          |__設置MutationImpl類對象的LogSegment成員爲mds->mdlog->get_current_segment()

          |__建立EUpdate類對象

          |__設置mdlog的start_entry是EUpdate類對象,即:mds->mdlog->start_entry(le)

          |__向EUpdate類對象的metablob中添加dir,即:le->metablob.add_dir_context(in->get_parent_dn()->get_dir())

          |__調用journal_dirty_inode()函數將處於dirty的inode也寫入到EUpdate類對象的metablob中

          |__提交mdslog,即:mds->mdlog->submit_entry()

          |__刷新mdslog,即:mds->mdlog->flush()

 

MDCache::subtree_merge_writebehind_finish(CInode *in, MutationRef mut)

|__將in的dirty projected inode寫入到mut的LogSegment中,即:in->pop_and_dirty_projected_inode(mut->ls)

|__執行mut,即:mut->apply()

|__清空mut,即:mut->cleanup()

|__設置in的auth_unpin,即:in->auth_unpin(this)

 

MDCache::eval_subtree_root(CInode *diri)

|__若diri是auth的

     |__調用mds->locker->try_eval(diri, CEPH_LOCK_IFILE|CEPH_LOCK_INEST)

 

MDCache::adjust_bounded_subtree_auth(CDir *dir, set<CDir*> bounds, mds_authority_t auth)     設置dir及其子樹的權限信息爲auth,同時將bounds數組中的成員合併到dir子樹下且設置其權限爲auth

|__若dir是root

     |__設置root=dir

     |__若subtrees數組中不包含root

          |__清空以root爲索引的subtrees項,即:subtrees[root].clear()

|__若dir不是root

     |__調用get_subtree_root(dir)獲得dir的root,即:root=get_subtree_root(dir)

|__獲得dir當前的auth信息,即:oldauth=dir->authority()

|__若root==dir

     |__設置dir的auth,即:dir->set_dir_auth(auth)

|__若root!=dir

     |__清空以dir爲索引的subtrees項,即:subtrees[dir].clear()

     |__設置dir的auth,即:dir->set_dir_auth(auth)

     |__遍歷以root爲索引的subtrees項

          |__若數組中對應的項的subtree root是dir

               |__把該項添加到subtrees[dir]下

               |__把該項從subtrees[root]下刪除

     |__將dir添加到subtrees[root]下

     |__設置root=dir

|__遍歷bounds數組

     |__若bounds數組成員不在subtrees[dir]下

          |__若bounds數組成員的subtree root是dir    

               |__調用adjust_subtree_auth(bound, oldauth)設置bound的auth信息

          |__若bounds數組成員的subtree root不是dir

               |__調用get_subtree_root()獲得bounds數組成員的subtree root

               |__subtree root爲索引的subtrees數組中沒有包含bounds數組成員

                    |__調用adjust_subtree_auth(bound, t->authority())設置bound的auth

          |__循環遍歷

               |__在subtrees[dir]目錄下的到bound的subtree root

               |__調用adjust_subtree_auth(t, auth)來調整subtree root的auth

               |__調用try_subtree_merge_at(t)來嘗試merge subtree root t到dir

               |__調用get_subtree_root()函數獲得bound的subtree root

               |__若subtree root==dir

                    |__退出遍歷

|__遍歷subtrees[dir]數組

     |__若數組成員不在bounds數組中

          |__調用adjust_subtree_auth(p, auth)來設置成員的auth

          |__調用try_subtree_merge_at(p)來嘗試合併p到dir

|__調用verify_subtree_bounds(dir, bounds)

 

MDSCache::verify_subtree_bounds(CDir *dir, set<CDir*> bounds)

|__遍歷subtrees[dir]數組

     |__若數組中的成員在bounds數組中

          |__將數組中的成員從bounds數組中刪除

|__遍歷bounds數組

     |__打印出extra bound

 

MDCache::get_force_dirfrag_bound_set(vector<dirfrag_t> dfs, set<CDir*> bounds)     獲得dfs數組中全部位於frag葉子節點的CDir類對象並將其放入到bounds數組中

|__遍歷dfs數組

     |__獲得數組成員中的ino號和frag信息

     |__獲得ino號對應的CInode類對象

     |__遍歷全部的frag信息

          |__在CInode類對象對應的dirfragtree下獲得frag下的全部葉子節點

          |__遍歷葉子節點

               |__將葉子節點對應的CDir類對象放入bounds數組中

 

MDSCache::adjust_bounded_subtree_auth(CDir *dir, vector<dirfrag_t> bound_dfs, mds_authority_t auth)

|__調用get_force_dirfrag_bound_set(bound_dfs, bounds)獲得bound_dfs數組中全部位於frag葉子節點的CDir類對象並將其放入到bounds數組中

|__調用adjust_bounded_subtree_auth(dir, bounds, auth)設置dir及其子樹的權限信息爲auth,同時將bounds數組中的成員合併到dir子樹下且設置其權限爲auth

 

MDCache::map_dirfrag_set(list<dirfrag_t> dfs, set<CDir*> result)     獲得dfs中位於dirfragtree上指定frag的葉子節點的CDir類對象

|__遍歷dfs數組

     |__獲得數組成員中的ino成員和frag成員並將這兩項寫入到map<inodeno_t, fragset_t> ino_fragset集合中

|__遍歷ino_fragset集合

     |__獲得inodeno_t對應的CInode類對象

     |__遍歷fragset_t集合

          |__獲得CInode的dirfragtree裏fragset_t集合成員的葉子節點

          |__遍歷葉子節點

               |__獲得葉子節點對應的CDir類對象,即:dir=in->get_dirfrag(*q)

               |__將dir放入到result數組中

 

MDCache::get_subtree_root(CDir *dir)

|__若dir是subtree root

     |__返回dir

|__獲得dir的父目錄dir,即:dir=dir->get_inode()->get_parent_dir()

|__若dir爲空

     |__返回0

 

MDCache::get_projected_subtree_root(CDir *dir)

|__若dir是subtree root

     |__返回dir

|__獲得dir的projected父目錄dir,即:dir=dir->get_inode()->get_projected_parent_dir()

|__若dir爲空

     |__返回0

 

MDCache::remove_subtree(CDir *dir)

|__從subtrees數組中刪除dir,即:subtrees,erase(dir)

|__若dir存在parent dir

     |__獲得dir的subtree root,即:p=get_subtree_root(dir->get_parent_dir())

     |__在以p爲索引的subtrees數組中刪除dir,即:subtrees[p].erase(dir)

 

MDCache::get_subtree_bounds(CDir *dir, set<CDir*> bounds)

|__將subtrees[dir]集合賦值給bounds

 

MDCache::get_wouldbe_subtree_bounds(CDir *dir, set<CDir*> bounds)

|__若subtrees[dir]不爲空

     |__將subtrees[dir]集合賦值給bounds

|__若subtrees[dir]爲空

     |__獲得dir的subtree root,即:root=get_subtree_root(dir)

     |__遍歷subtrees[root]集合

          |__若集合中的成員==dir或成員的parent dir==dir

               |__將成員或成員的parent dir插入到bounds數組中

 

MDCache::project_subtree_rename(CInode *diri, CDir *olddir, CDir *newdir)

|__以diri爲索引以olddir和newdir爲值,更新projected_subtree_renames數組,即:projected_subtree_renames[diri].push_back(pair<CDir*,CDir*>(olddir, newdir))

 

MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop, bool imported)

|__獲得diri的parent dir,即:newdir=diri->get_parent_dir()

|__若pop==true

     |__在projected_subtree_renames數組中查找diri對應的項

     |__若找到且diri對應的項爲空

          |__從projected_subtree_renames數組中刪除diri,即:projected_subtree_renames.erase(p)

|__獲得subtree dirfrags,即:diri->get_subtree_dirfrags(dfls)

|__獲得nested dirfrags,即:diri->get_nested_dirfrags(dfls)

|__遍歷dfls數組

     |__獲得olddir的subtree root,即: oldparent=get_subtree_root(olddir)

     |__獲得newdir的subtree root,即:newparent=get_subtree_root(newdir)

     |__若oldparent==newparent

          |__遍歷下一個

     |__若dir是subtree root

          |__從oldparent的subtrees數組中刪除dir,即:subtrees[oldparent].erase(dir)

          |__將dir插入到newparent的subtrees數組中,即:subtrees[newparent].insert(dir)

          |__調用try_subtree_merge_at(dir, !imported)     嘗試合併dir

     |__若dir不是subtree root

          |__遍歷subtrees[oldparent]數組

               |__若數組成員的subtree root != oldparent

                    |__將該數組成員添加到tomove數組中

          |__遍歷tomove數組

               |__將數組中的成員從subtrees數組中的oldparent中移除,同時添加到newparent中

 

MDCache::get_fullauth_subtrees(set<CDir*> s)

|__遍歷subtrees數組

     |__若subtrees root是auth的但不是ambigous auth

          |__將subtrees root插入到s數組中

 

MDCache::get_auth_subtrees(set<CDir*> s)

|__遍歷subtrees數組

     |__若subtrees root是auth的

          |__將subtrees root插入到s數組中

 

MDCache::num_subtrees()

|__返回subtrees數組的大小

 

MDCache::num_subtrees_fullauth()

|__返回subtrees數組中的subtree root是is_full_dir_auth()的個數

 

MDCache::num_subtrees_fullnonauth()

|__返回subtrees數組中的subtree root是is_full_dir_nonauth()的個數

相關文章
相關標籤/搜索