EMetaBlob類分析

EMetaBlob用於記錄CDir和CDentry的Lognode

EMetaBlob類說明:數組

class EMetaBlob: public LogEvent {session

 

};函數

 

EMetaBlob類的方法:日誌

EMetaBlob::add_dir_context(dir, mode)                    將dir及其父目錄添加到EMetaBlob類中code

|__檢查當前lump_map集合中是否已經包含dir對象

     |__直接返回rem

|__從dir目錄開始依次向根目錄遍歷get

     |__獲得dir的CInode(diri)和CDentry(parent)it

     |__若mode==TO_AUTH_SUBTREE_ROOT

          |__若dir是subtree_root而且已是auth的

               |__退出遍歷

          |__若dir是subtree_root但不是auth的

               |__將maybe數組(CDentry list)插入到parents數組的首部

          |__若diri已經journal過了

               |__退出遍歷

          |__若diri->last_journaled >= last_subtree_map     說明從last subtree map開始,該inode已經寫入日誌了

               |__maybenot=true

     |__若已是根目錄了(parent爲空)

          |__退出遍歷

     |__maybenot==true

          |__將parent插入到maybe數組中

     |__maybenot==false

          |__將parent插入到parents數組中

     |__dir=parent->get_dir()               從當前dir開始向根目錄遞進

|__將maybe數組插入到parents數組的首部

|__遍歷parents數組

     |__add_dentry()               將parents數組中成員添加到EMetaBlob類中

 

EMetaBlob::update_segment(ls)          更新LogSegment的inotablev和sessionmapv

|__若inotablev不爲空

     |__ls->inotablev=inotablev

|__若sessionmapv不爲空

     |__ls->sessionmapv=sessionmapv

 

EMetaBlob::fullbit::update_inode(mds, in)

|__用EMedaBlob類對象中的數據初始化CInode類對象

 

EMetaBlob::get_inodes(inodes)

|__遍歷lump_map集合

     |__獲得lump_map結合中每一個成員的dirfrag的inode號

     |__將inode號插入到inodes數組中

     |__從lump_map中獲得dirlump信息

     |__遍歷dirlump中的fullbit

          |__將dirlump中fullbit對應的inode號插入到inodes數組中

     |__遍歷dirlump中的remotebit

          |__將remotebit的inode號插入到inodes數組中

 

EMetaBlob::get_dentries(dentries)

|__遍歷lump_map集合

     |__從lump_map中獲得dirlump信息

     |__從dirlump結構中分別獲得full_dentry/remote_dentry/null_dentry信息

     |__遍歷full_dentry數組

          |__將full_dentry數組中成員的dn(dentry name)插入到dentries數組中

     |__遍歷remote_dentry數組

          |__將remote_dentry數組中成員的dn(dentry name)插入到dentries數組中

    |__遍歷null_dentry數組

          |__將null_dentry數組中成員的dn(dentry name)插入到dentries數組中

 

EMetaBlob::get_paths(paths)                         從dirlump結構中獲得全部的絕對目錄信息

|__若lump_map爲空且roots不爲空

     |__將」/「插入到paths數組

|__遍歷lump_map集合

     |__獲得full_dentry/remote_dentry/null_dentry數組

     |__遍歷full_dentry數組

          |__將full_dentry數組成員中的dentry name插入到children數組中,即:children[dir_ino].push_back(dentry)

          |__更新ino_locations數組,即:ino_locations[(*iter)->inode.ino] = Location(dir_ino, dentry)

     |__遍歷remote_dentry數組

          |__將remote_dentry數組成員中的dentry name插入到children數組中,即:children[dir_ino].push_back(dentry)

     |__遍歷null_dentry數組

          |__將null_dentry數組成員中的dentry name插入到children數組中,即:children[dir_ino].push_back(dentry)

|__遍歷lump_map集合

     |__獲得full_dentry/remote_dentry/null_dentry數組

     |__遍歷full_dentry數組

          |__若在children數組中沒有找到對應的節點,則說明此節點是葉子節點

               |__將節點的inode和dentry信息插入到leaf_locations數組中,即:leaf_locations.push_back(Location(dir_ino, dentry))

     |__遍歷remote_dentry數組

          |__將節點的inode和dentry信息插入到leaf_locations數組中,即:leaf_locations.push_back(Location(dir_ino, dentry))

     |__遍歷null_dentry數組

          |__將節點的inode和dentry信息插入到leaf_locations數組中,即:leaf_locations.push_back(Location(dir_ino, dentry))

|__遍歷leaf_locations數組

     |__獲得inode號和對應的path

     |__在ino_locations數組中遍歷查找inode號,若查找成功

          |__將ino_locations數組中對應的path值添加到path的前面,即:構成當前path的上一級path目錄信息

          |__inode號更新爲ino_locations對應的inode號

     |__將獲得的path值插入到paths數組中

 

EMetaBlob::replay(mds, logseg, slaveup)

|__遍歷roots數組

     |__從MDCache中獲得CInode信息,即:mds->mdcache->get_inode()

     |__若MDCache中沒有CInode信息

          |__建立一個新的CInode類對象

     |__EMetaBlob::fullbit::update_inode()          使用fullbit信息更新CInode信息

     |__若roots成員是dirty的

          |__設置CInode爲dirty

|__若renamed_dirino不爲空

     |__從MDCache中獲得CInode信息,即:mds->mdcache->get_inode(renamed_dirino)

     |__遍歷lump_order數組

          |__從lump_map數組中獲得dirlump信息

          |__dirlump的nnull不爲空

               |__更新nnull個數,即:nnull += lump.nnull

|__遍歷lump_order數組

     |__從lump_map數組中獲得dirlump信息

     |__從MDCache中獲得dirfrag對應的CDir信息,即:mds->mdcache->get_force_dirfrag()

     |__若CDir爲空

          |__從MDCache中獲得該CDir對應的CInode信息,即:mds->mdcache->get_inode()

          |__若CInode爲空

               |__若CDir對應的CInode號是MDSDIR的範圍

                    |__從MDCache中建立一個CInode,即:mds->mdcache->create_system_inode()

                    |__清除新建的CInode的AUTH標識,即:diri->state_clear(STATE_AUTH)

               |__若CDir對應的CInode號不是MDSDIR的範圍

                    |__assert(0)

          |__根據CInode獲得CDir信息,即:diri->get_or_open_dirfrag()

          |__若CInode對應的號是ROOT或MDSDIR

               |__調整subtree的auth,即:mds->mdcache->adjust_subtree_auth()

     |__設置CDir的version/fnode信息

     |__若dirlump是is_importing()

          |__設置CDir STATE_AUTH標誌,清除STATE_COMPLETE標誌

     |__若dirlump是is_dirty()

          |__CDir::_mark_dirty()

          |__若dir->fnode.rstat != dir->fnode.accounted_rstat          說明有dirty nestinfo

               |__mds->locker->mark_updated_scatterlock()

               |__logseg->dirty_dirfrag_nest.push_back(dir->inode->item_dirty_dirfrag_nest)

          |__若dir->fnode.fragstat != dir->fnode.accounted_fragstat     說明有dirty fragstat

               |__mds->locker->mark_updated_scatterlock()

               |__logseg->dirty_dirfrag_dir.push_back(dir->inode->item_dirty_dirfrag_nest)

     |__若lump是is_dirty_dft()

          |__設置dir的狀態爲DIRTYDFT,即:dir->state_set(STATE_DIRTYDFT)

          |__mds->locker->mark_updated_scatterlock()

          |__logseg->dirty_dirfrag_dirfragtree.push_back(dir->inode->item_dirty_dirfrag_nest)

     |__若lump是is_new()

          |__設置dir是new的,即:dir->mark_new()

     |__若lump是is_complete()

          |__設置dir是complete的,即:dir->mark_complete()

     |__從lump中解析出dfull/dremote/dnull信息,即:lump._decode_bits()

     |__遍歷full_dentry數組

          |__獲得dnlast對應的CDentry對象,即:dir->lookup_exact_snap(dn, dnlast)

          |__若CDentry對象爲空

               |__向dir添加一個空的dentry,即:dir->add_null_dentry()

               |__根據full_dentry的dentry version信息,設置dentry的版本信息

          |__若CDentry對象不爲空

               |__根據full_dentry的dentry version信息,設置dentry的版本信息

               |__設置dentry的first爲full_entry的dnfirst

          |__若lump是is_importing()

               |__設置dentry的狀態爲AUTH,即:dn->state_set(STATE_AUTH)

          |__從MDCache中獲得dnlast的CInode信息,即:mds->mdcache->get_inode(ino, dnlast)

          |__若CInode信息爲空

               |__建立一個新的CInode類對象

               |__使用full_dentry信息初始化新的CInode類對象,即:p->update_inode(mds, in)

               |__將新的CInode添加到MDCache中,即:mds->mdcache->add_inode(in)

               |__若dentry的linkage不爲空

                    |__若dentry的linkage是primary

                         |__將dir放入到unlinked數組中               應該被刪除掉的

                    |__解除dir和dentry之間的對應關係,即:dir->unlink_inode(dn)

               |__若CInode位於unlinked數組中

                    |__將CInode插入到linked數組中

               |__設置dir的primary link inode,即:dir->link_primary_inode(dn, in)

          |__若CInode信息不爲空

               |__設置CInode的first值,即:in->first = p->dnfirst

               |__使用full_dentry信息初始化新的CInode類對象,即:p->update_inode(mds, in)

               |__若dentry的linkage不是CInode而且CInode有parent dentry

                    |__將CInode的parent dir放入unlinked數組

                    |__解除CInode與其parent dir的對應關係,即:in->get_parent_dir()->unlink_inode(in->get_parent_dn())

               |__若dentry的linkage不是CInode

                    |__若dentry的linkage不爲空

                         |__若dentry的linkage是primary

                              |__將dir放入到unlinked數組中               應該被刪除掉的

                         |__解除dir和dentry之間的對應關係,即:dir->unlink_inode(dn)

                    |__若CInode位於unlinked數組中

                         |__將CInode插入到linked數組中

                    |__設置dir的primary link inode,即:dir->link_primary_inode(dn, in)

               |__若full_dentry是is_dirty()

                    |__設置CInode爲dirty, 即:in->_mark_dirty(logseg)

               |__若full_dentry是is_dirty_parent()

                    |__設置CInode爲dirty parent,即:in->_mark_dirty_parent()

               |__若dentry是is_auth()

                    |__設置CInode的狀態爲AUTH,即:in->state_set(STATE_AUTH)

          |__遍歷remote dentry數組

               |__獲得dnlast對應的CDentry對象,即:dir->lookup_exact_snap(dn, dnlast)

               |__若CDentry對象爲空

                    |__向dir添加一個新的remote dentry,即:dir->add_remote_dentry()

                    |__根據remote_dentry的dentry version信息,設置dentry的版本信息

               |__若CDentry對象不爲空

                    |__若dentry的linkage不爲空

                         |__若dentry的linkage是primary

                              |__將dir插入到unlinked數組中

                         |__解除dir與dentry之間的關聯,即:dir->unlink_inode(dn)

               |__向dir添加remote inode,即:dir->link_remote_inode()

               |__根據remote_dentry的dentry version信息,設置dentry的版本信息

               |__設置dentry的first爲remote_dentry的first

               |__若lump是is_importing()

                    |__設置dentry的狀態爲AUTH,即:dn->state_set(STATE_AUTH)

          |__遍歷null_dentry數組

               |__獲得dnlast對應的CDentry對象,即:dir->lookup_exact_snap(dn, dnlast)

               |__若CDentry對象爲空

                    |__向dir添加一個新的remote dentry,即:dir->add_remote_dentry()

                    |__根據remote_dentry的dentry version信息,設置dentry的版本信息

               |__若CDentry對象不爲空

                    |__設置dentry的first爲null_dentry的first

                    |__若dentry的linkage不爲空

                         |__將dir插入到unlinked數組中

                         |__解除dir與dentry之間的關聯,即:dir->unlink_inode(dn)

                    |__根據null_dentry的版本信息,設置dentry的版本信息

               |__若lump是is_importing()

                    |__設置dentry的狀態爲AUTH,即:dn->state_set(STATE_AUTH)

|__若renamed_dirino不爲空

     |__若renamed_diri不爲空

          |__設置olddir爲unlinked[renamed_diri]

     |__若renamed_diri爲空

          |__從MDCache中獲得renamed_diri,即:mds->mdcache->get_inode(renamed_dirino)

     |__若olddir不爲空

          |__從renamed_diri的dirfragtree上獲得全部的葉子節點,即:renamed_diri->dirfragtree.get_leaves()

          |__遍歷葉子節點

               |__根據葉子節點找到對應的CDir信息

               |__若CDir沒有被認證

                    |__將CDir對應的CInode插入到slaveup的olddirs中,即:slaveup->olddirs.insert(dir->inode)

               |__若CDir被認證

                    |__設置dir的狀態爲AUTH,即:dir->state_set(STATE_AUTH)

          |__更新MDCache中的subtree信息,即:mds->mdcache->adjust_subtree_after_rename()

          |__從MDCache中獲得olddir的subtree_root的CDir信息

          |__若subtree_root未認證

               |__若slaveup不爲空

                    |__將olddir對應的CInode插入到slaveup的olddirs中,即:slaveup->olddirs.insert(dir->inode)

               |__若slaveup爲空

                    |__更新MDCache的subtree信息,即:mds->mdcache->try_trim_non_auth_subtree()

     |__若renamed_diri被認證

          |__遍歷renamed_dir_frags數組

               |__從renamed_diri這個CInode獲得其dirfrag的CDir信息,即:reanmed_diri->get_dirfrag()

               |__若CDir信息存在

                    |__遍歷下一個

               |__建立一個新的CDir對象,即:renamed_diri->get_or_open_dirfrag()

               |__清除新建的CDir的AUTH,即:dir->state_clear(STATE_AUTH)

               |__調整MDCache中的subtree信息,即:mds->mdcache->adjust_subtree_auth()

     |__從unlinked數組中刪除renamed_diri

     |__遍歷unlined數組

          |__調整MDCache中的subtree信息,即:mds->mdcache->adjust_subtree_after_rename()

|__若unlinked數組不爲空

     |__遍歷linked數組

          |__從unlinked數組中刪除linked數組中的成員

     |__遍歷unlinked數組

          |__若slaveup不爲空

               |__將unlinked信息插入到slaveup的unlinked數組中,即:slaveup->unlinked.insert()

          |__若slaveup爲空

               |__更新MDCache,即:mds->mdcache->remove_inode_recursive()

|__遍歷table_tids數組(遍歷table client)

     |__獲得MDSTableClient類對象,即:mds->get_table_client()

     |__執行client的got_journaled_agree()函數,即:client->got_journaled_agree()

|__若opened_ino不爲空

     |__從MDCache中獲得opened_ino對應的CInode,即:mds->mdcache->get_inode()

     |__將CInode的item_open_file插入到logseg的open_files數組中,即:logseg->open_files.push_back()

|__若inotablev不爲空

     |__若mds的inotable版本號小於inotablev

          |__若allocated_ino不爲空

               |__從新分配inode號,即:mds->inotable->replay_alloc_id()

          |__若preallocated_inos不爲空

               |__從新分配inode號,即:mds->inotable->replay_alloc_id()

|__若sessionmapv不爲空

     |__若mds的sessionmap版本號+2>=sessionmapv

          |__根據client_name獲得session信息,即:mds->sessionmap.get_session()

          |__若session不爲空

               |__從新執行dirty的session,即:mds->sessionmap.replay_dirty_session()

          |__若session爲空

               |__執行advance version,即:mds->sessionmap.replay_advance_version()

|__遍歷truncate_start數組

     |__從MDCache中獲得對應的CInode信息,即:mds->mdcache->get_inode()

     |__在MDCache中執行add recovered truncate,即:mds->mdcache->add_recovered_truncate()

|__遍歷truncate_finish數組

     |__從MDLog中獲得對應的LogSegment,即:mds->mdlog->get_segment()

     |__從MDCache中獲得對應的CInode信息,即:mds->mdcache->get_inode()

     |__在MDCache中執行remove recovered truncate,即:mds->mdcache->remove_recovered_truncate()

|__遍歷destroyed_inodes數組

     |__從MDCache中獲得對應的CInode信息,即:mds->mdcache->get_inode()

     |__在MDCache中刪除對應的CInode,即:mds->mdcache->remove_inode()

|__遍歷client_reqs數組

     |__從sessionmap中獲得對應的Session類對象,即:mds->sessionmap.get_session()

     |__在Session對象中添加completed request,即:session->add_completed_request()

     |__若client_reqs數組中包含trim的session

          |__在Session對象中執行trim completed request,即:session->trim_completed_request()

|__遍歷client_flushes數組

     |__從sessionmap中獲得對應的Session類對象,即:mds->sessionmap.get_session()

     |__在Session對象中添加completed request,即:session->add_completed_request()

     |__若client_reqs數組中包含trim的session

          |__在Session對象中執行trim completed request,即:session->trim_completed_request()

|__更新LogSegment信息,即:update_segment(logseg)

相關文章
相關標籤/搜索