MDCache类分析

原创
2016/07/27 15:34
阅读数 2.3K

class MDCache {

     //my masters

     MDSRank *mds;          MDCache所处的MDSRank

     //my cache

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

     unordered_map<vinodeno_t, CInode*> inode_map;     inode映射关系(保存inodes)

     CInode *root;          根CInode

     CInode *myin;

     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()的个数

 

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部