目录
CEPH caps简介
CAPS 和锁的关系
caps由mds进行管理,其将元数据划分为多个部分,每个部分都有专门的锁(SimpleLock、ScatterLock、FileLock)来保护,mds通过这些锁的状态来确定caps可以怎么样分配。
mds内部维护了每个锁的状态机,其内容非常复杂,也是mds保证caps分配准确性和数据一致性的关键。
CEPH MDS锁实现介绍
锁的作用
MDS中的锁是为了保护log的正常写入。每次对目录树进行操作前,需要先将目标path中涉及的节点加锁,在内存中修改完目录树(修改方式类似于RCU,即生成一个新节点,push_back到 队列 中)后,将新的目录树信息(只是此条path,不是整个目录树)记录到MDS的journal对象中,journal对象落盘后再将 队列 中的节点pop_front出来,至此,内存中的目录树已经能反映出之前的修改,加的锁也在此时开始释放,最后当前目录树的信息更新到meta pool的dir对象中。
锁的获取
加锁类型
加锁的类型分三类:rdlock(读)、wrlock(写)、xlock(互斥)。每次对目录树进行操作前都要将path上的节点进行适当地加锁。可从src/mds/Server.cc
中观察这一操作:
handle_client_xxx
|-- rdlock_path_xlock_dentry或rdlock_path_pin_ref
|-- mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks)
对于一个路径进行操作时,最后一个dentry之前的dentry都要加rdlock,避免别人进行修改。xlock用于创建或者修改节点时,比如mkdir时需要对新的dentry加xlock,创建新文件时需要对CInode::linklock(负责inode的nlink属性)加xlock。rdlock和xlock符合通常认知:共享读,互斥写。
wrlock比较特殊,主要用在CInode::filelock
和CInode::nestlock
上,前者负责保护当前目录的统计信息inode_t::dirstat
,后者负责保护当前目录的递归统计信息inode_t::rstat
;
由于一个目录可以分成多个分片,甚至同一个分片也可以有多个副本分散于各个mds,为了允许对这些分片的统计信息同时进行修改,引入了wrlock,这些分散的被修改的信息将在后续的一个时间点上进行综合,最终传播到目录树的inode信息中(见CInode::preditry_journal_parents
)。对于CInode::versionlock
和CDentry::versionlock
也会加wrlock锁,但由于是locallock sm,意义和simplelock的xlock一样,只是为了互斥写。
锁的种类和状态机
一个inode中的信息有很多种,每种由不同的锁来保护,