StrayManager类分析

StrayManager类说明:
class StrayManager {
  elist<CDentry*> delayed_eval_stray;
  list<QueuedStray> ready_for_purge;
  MDSRank *mds;
  uint64_t ops_in_flight;
  uint64_t files_purging;
  uint64_t max_purge_ops;
  uint64_t num_strays;
  uint64_t num_strays_purging;
  uint64_t num_strays_delayed;
  Filer    filer;
};

StrayManager类方法:
StrayManager::purge(dn, op_allowance)        实际上就是从集群中删除指定dentry对应的inode信息
|__从dn得到CDentry对应的CInode类对象in
|__增加num_strays_purging的值
|__若in是目录
  |__根据mds所在的metadata_pool信息,得到in对象所在的pool位置
  |__若in目录在dirfragtree上不是叶子节点
    |__得到in目录在dirfragtree上的所有叶子节点
    |__遍历所有叶子节点
      |__得到叶子节点的oid信息,即:CInode::get_object_name(in->inode.ino, *p, "");
      |__从pool里删除该叶子节点,即:mds->objecter->remove(oid, oloc,...)
  |__直接返回
|__从in中得到所有的SnapRealm信息
|__SnapRealm有效
  |__得到SnapRealm的上下文信息,即:snapc = &realm->get_snap_context()
|__SnapRealm无效
  |__设置snapc为nullsnapc
|__得到in的projected inode信息
|__得到projected_inode的oid,即:oid = CInode::get_object_name(pi->ino, frag_t(), "")
|__删除backtrace对象,即:mds->objecter->remove(oid, oloc,...)
|__遍历old backtrace对象集合,即:pi->old_pools
  |__删除backtrace对象,即:mds->objecter->remove(oid, oloc,...)

StrayManager::_purge_stray_purged(dn, ops_allowance, only_head)
|__从dn得到CDentry对应的CInode类对象in
|__若only_head==true
  |__创建EUpdate类对象
  |__设置mds的mdlog的start_entry为EUpdate类对象,即:mds->mdlog->start_entry(le)
  |__得到in的project_inode信息
  |__初始化project_inode信息
  |__设置LogEvent类对象(le)中metablob的dir_context,即:le->metablob.add_dir_context()
  |__向LogEvent类对象(le)中medtablob中添加primary dentry,即:le->metablob.add_primary_dentry()
  |__向MDLog提交entry,即:mds->mdlog->submit_entry()
|__若only_head==false
  |__创建EUpdate类对象
  |__设置mds的mdlog的start_entry为EUpdate类对象,即:mds->mdlog->start_entry(le)
  |__设置LogEvent类对象(le)中metablob的dir_context,即:le->metablob.add_dir_context()
  |__在LogEvent的metablob中添加一个dir,即:le->metablob.add_dir()
  |__在LogEvent的metablob中添加一个空的dentry,即:le->metablob.add_null_dentry()
  |__在LogEvent的metablob中添加一个destroyed inode,即:le->metablob.add_destroyed_inode()
  |__向MDLog提交entry,即:mds->mdlog->submit_entry()
|__递减num_strays_purging
|__从ops_in_flight中减去ops_allowance
|__调用_advance()

StrayManager::_advance()
|__遍历ready_for_purge集合(QueuedStray集合)
  |__调用_consume()
  |__若_consume()返回true
    |__停止遍历
|__删除ready_for_purge集合中从开始到_consume()返回true的节点

StrayManager::_consume(dn, trunc, ops_required)
|__从配置文件中获取到目前可以purge的文件数量,即:g_conf->mds_max_purge_files-files_purging;
|__若files_avail<=0
  |__直接返回
|__若ops_in_flight<=max_purge_pos
  |__ops_avail = max_purge_ops - ops_in_flight
|__若ops_in_flight>max_purge_pos
  |__ops_avail = 0
|__若ops_in_flight>0并且ops_avail<ops_required
  |__直接退出并返回false
|__增加ops_in_flight数值,即:ops_in_flight += ops_required
|__若trunc==true
  |__truncate(dn, ops_required)
|__若trunc==false
  |__purge(dn, ops_required)
|__返回true

StrayManager::_purge_stray_logged(dn, pdv, ls)
|__从dn得到CDentry对应的CInode类对象in
|__从dn所在的dir目录下删除该dn,即:dn->dir->unlink_inode(dn)
|__从dn所在的dir目录下删除projected fnode,即:dn->dir->pop_and_dirty_projected_fnode(ls)
|__从MDCache中删除in,即:in->mdcache->remove_inode(in)
|__若dn是new
  |__从dn所在的dir目录下删除该dn,即:dn->dir->remove_dentry(dn)
|__若dn不是new
  |__在MDCache中将dn设置到dentry的bottom,即:in->mdcache->touch_dentry_bottom(dn)

  
StrayManager::_calculate_ops_required(in, trunc)
|__若in是目录
  |__ops_reqired数量=1+in在dirfragtree下的叶子节点个数
|__若in不是目录
  |__ops_reqired数量=1+g_conf->filer_max_purge_ops

StrayManager::enqueue(dn, trunc)
|__从dn得到CDentry对应的CInode类对象in
|__设置dn的状态为STATE_PURGING
|__设置in的状态为STATE_PURGING
|__根据in和trunc计算一下所需的ops数,即:_calculate_ops_required(in, trunc)
|__若ready_for_purge数组不为空
  |__调用_consume(dn, trunc, ops_required)
|__若_consume()返回false
  |__将dn重新插入到ready_for_purge数组,即:ready_for_purge.push_back()

StrayManager::advance_delayed()
|__遍历delayed_eval_stray数组
  |__从dn的item_stray数组中删除自己,即:dn->item_stray.remove_myself()
  |__递减num_strays_delayed

StrayManager::_eval_stray(dn, delay)    检查dn及其对应的CInode是否满足stray的条件,若满足则返回true,否则返回false
|__从dn得到CDentry对应的CInode类对象in
|__若dn不是auth的
  |__在MDCache中将dn设置到dentry的bottom,之后会立即被trim掉。即:in->mdcache->touch_dentry_bottom(dn)
  |__返回false
|__若dn在item_stray数组中
  |__从item_stray数组中删除自己,即:dn->item_stray.remove_myself()
  |__递减num_strays_delayed
|__若in的inode link为0
  |__若in中包含有snaprealm
    |__若in的snaprealm没有past_parents_open并且没有open parents
      |__返回false
    |__从in的snaprealm中删除past parents,即:in->snaprealm->prune_past_parents()
    |__从in中删除stale snap data,即:in->purge_stale_snap_data()
  |__若in是目录
    |__若in中包含有snaprealm且in的snamrealm中包含past parents
      |__返回false
    |__若in中包含dirfrags
      |__得到该in下所有的dirfrags
      |__遍历所有的dirfrags
    |__删除所有的dirfrags,即:(*p)->try_remove_dentries_for_stray()
    |__若in的remote parents不为空,说明in仍然有远程链接
      |__遍历in的remote parents数组
    |__删除远程链接,即:remote_dn->unlink_remote(remote_dn->get_linkage())
  |__若dn是replicted,即:dn的replica_map不为空
    |__返回false
  |__若dn仍然有any leases或仍然有any caps
    |__返回false
  |__若dn的当前状态是STATE_NEEDSRECOVER或STATE_RECOVERING
    |__返回false
  |__若in的引用计数>in的dirty数量+1
    |__返回false
  |__若delay==true
    |__若dn不在item_stray数组中
      |__将dn->item_stray数组插入到delayed_eval_stray数组中,即:delayed_eval_stray.push_back(dn->item_stray)
  |__若delay==false并且in拥有snaprealm并且in的snaprealm包含past parents并且in的old_inodes不为空
    |__若in是文件并且in的projected inode的大小大于0
      |__enqueue(dn, true)
  |__其他条件 
    |__若in是目录
      |__关闭in的所有dirfrags,即:in->close_dirfrags()
    |__enqueue(dn, false)
  |__返回true
|__若in的inode link不为0
  |__调用eval_remote_stray(dn, NULL)
  |__返回false

StrayManager::eval_stray(dn, delay)
|____eval_stray(dn, delay)
-
StrayManager::eval_remote_stray(stray_dn, remote_dn)    当待评估的dn的nlink大于0,则需要评估远程的dn是否是stray
|__从dn得到CDentry对应的CInode类对象in
|__若remote_dn为空
  |__若stray_in的remote_parents不为空
    |__遍历stray_in的remote_parents数组
      |__若数组中成员的last==CEPH_NOSNAP
    |__将数组中成员赋值给remote_dn
      |__若remote_dn为空,即:没有在stray_in的remote parents数组中找到last==CEPH_NOSNAP的
    |__直接返回 
|__若remote_dn不是projected
  |__若remote_dn是auth的并且remote_dn对应的CDir能auth pin 
    |__reintegrate_stray(stray_dn, remote_dn)
  |__否则,若remote_dn不是auth并且stray_dn是auth的
    |__migrate_stray(stray_dn, remote_dn->authority().first)

StrayManager::reintegrate_stray(straydn, rdn)
|__得到straydn的完整路径,即:straydn->make_path(src)
|__得到remotedn的完整路径,即:rdn->make_path(dst)
|__创建MClientRequest类消息且消息类型是CEPH_MDS_OP_RENAME
|__设置源和目的filepath
|__设置tid
|__将消息发送给rdn授权的第一个MDS进程,即:mds->send_message_mds(req, rdn->authority().first)

StrayManager::migrate_stray(dn, to)
|__从dn得到CDentry对应的CInode类对象in
|__得到dn对应的dir的CInode类对象diri
|__得到dn的完整路径,即:dn->make_path(src)
|__得到in的stray dentry名字,即:in->name_stray_dentry(dname)
|__创建MClientRequest类消息且消息类型是CEPH_MDS_OP_RENAME
|__设置源和目的filepath
|__设置tid
|__将消息发送给to这个MDS进程,即:mds->send_message_mds(req, to)

StrayManager::abort_queue()
|__遍历ready_for_purge集合
  |__从集合成员QueuedStray中得到CDentry
  |__从Cdentry得到CInode
  |__清除dn的STATE_PURGING状态,即:dn->state_clear(STATE_PURGING)
  |__清除in的STATE_PURGING状态,即:in->state_clear(STATE_PURGING)
|__清空ready_for_purge集合

StrayManager::truncate(dn, op_allowance)
|__从dn得到CDentry对应的CInode类对象in
|__从in中得到snaprealm信息
|__从snaprealm中得到SnapContext信息
|__得到in->inode.size和in->inode.get_max_size()以及in->inode.max_size_ever的最大值
|__若该最大值大于0
  |__从Striper得到该inode的条带个数,即:Striper::get_num_objects(in->inode.layout, to)
  |__若条带个数大于1
    |__通过filer purge指定数量的条带,即:filer.purge_range()
  |__通过filer清空指定inode,即:filer.zero()
  
StrayManager::_truncate_stray_logged(dn, ls)
|__从dn得到CDentry对应的CInode类对象in
|__清除dn的STATE_PURGING状态,即:dn->state_clear(STATE_PURGING)
|__从in中dirty projected inode,即:in->pop_and_dirty_projected_inode(ls)
|__eval_stray(dn)

StrayManager::update_op_limit()
|__从mds的objecter里得到当前的osdmap
|__从mdspmap中得到所有的data pool
|__遍历data pool
  |__累加所有data pool的pg数量
|__从mdsmap中得到当前可用的最大mds数量
|__计算可用于purge的操作个数,即:n_pgs/n_mdss*g_conf->mds_max_purge_ops_per_pg
|__若配置文件中包含mds_max_purge_ops
  |__将max_purge_ops和配置文件中的mds_max_purge_ops的最小值赋值给max_purge_ops
 

转载于:https://my.oschina.net/linuxhunter/blog/716069

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值