扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章将为大家详细讲解有关EMetaBlob类有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
创新互联公司长期为1000多家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为迎江企业提供专业的成都网站建设、成都网站设计,迎江网站改版等技术服务。拥有10年丰富建站经验和众多成功案例,为您定制开发。
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)
关于“EMetaBlob类有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流