文档章节

EMetaBlob类分析

linuxhunter
 linuxhunter
发布于 2016/07/20 17:48
字数 2666
阅读 227
收藏 0

EMetaBlob用于记录CDir和CDentry的Log

EMetaBlob类说明:

class EMetaBlob: public LogEvent {

 

};

 

EMetaBlob类的方法:

EMetaBlob::add_dir_context(dir, mode)                    将dir及其父目录添加到EMetaBlob类中

|__检查当前lump_map集合中是否已经包含dir

     |__直接返回

|__从dir目录开始依次向根目录遍历

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

     |__若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)

© 著作权归作者所有

上一篇: StrayManager类分析
下一篇: LogSegment类分析
linuxhunter
粉丝 72
博文 144
码字总数 93264
作品 0
沈阳
高级程序员
私信 提问
ESlaveUpdate类分析

ESlaveUpdate类说明: class ESlaveUpdate: public LogEvent { EMetaBlob commit; bufferlist rollback; string type; metareqid_t reqid; mdsrankt master; u8 op; u8 origop; }; ESlaveUpd......

linuxhunter
2016/07/22
32
0
EImportStart类分析

EImportStart类说明: class EImportStart:public LogEvent { dirfrag_t base; vector<dirfrag_t> bounds; EMetaBlob metablob; bufferlist client_map; version_t cmapv; }; EImportStart类......

linuxhunter
2016/07/22
35
0
ESubtreeMap类分析

ESubtreeMap类说明: class ESubtreeMap: public LogEvent { EMetaBlob metablob; map<dirfragt, vector<dirfragt>> subtrees; set<dirfragt> ambiguoussubtrees; uint64t expirepos; uint64......

linuxhunter
2016/07/22
65
0
EExport类分析

EExport类说明: class EExport:public LogEvent { EMetaBlob metablob; dirfrag_t bsae; set<dirfrag_t> bounds; }; EExport类方法: EExport::replay(mds) |从MDCache中得到base的CDir,即......

linuxhunter
2016/07/22
30
0
MDLog分析

ReplayThread类:负责log的replay事件处理。 RecoveryThread类:负责log的recovery事件处理。 SubmitThread类:负责log的submit事件处理。 map<uint64_t, LogSegment*> segments; 记录log的序......

linuxhunter
2016/07/12
654
0

没有更多内容

加载失败,请刷新页面

加载更多

Handler简解

Handler 这里简化一下代码 以便理解 Handler不一定要在主线程建 但如Handler handler = new Handler(); 会使用当前的Looper的, 由于要更新UI 所以最好在主线程 new Handler() { mLooper = Lo...

shzwork
15分钟前
2
0
h5获取摄像头拍照功能

完整代码展示: <!DOCTYPE html> <head> <title>HTML5 GetUserMedia Demo</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum......

诗书易经
18分钟前
1
0
正向代理和反向代理

文章来源 运维公会:正向代理和反向代理 1、正向代理 (1)服务对象不同 正向代理服务器的服务对象是客户端,可以将客户端和代理服务器看作一个整体。 (2)配置方法不同 需要在客户端配置代...

运维团
34分钟前
2
0
5个避免意外论文重复率高的方法

即使你不是故意抄袭,但你可能在无意中抄袭了别人的论文, 这个叫做意外抄袭,它可能正发生在你身上,如果你不熟悉学术 道德规范,这里将告诉你5个基本的方法来避免意外抄袭。 Tip1 熟悉其他...

论文辅导员
35分钟前
2
0
Maven通过profiles标签读取不同的配置

<profiles> <profile> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> ......

时刻在奔跑
41分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部