CompatSet是一個結構體類型,其用於對特性兼容性進行管理。該類型的定義位於src/include/CompatSet.h文件中。
爲什麼需要該兼容性管理模塊:
OSD對外提供一些功能特性,這個些特性需要OSD後端的存儲驅動(或者文件系統)如filestore支持,如果後端驅動不支持,即兩者之間在某些特性上不能兼容,就會影響讀寫操作,所以謹慎處理這些特性的兼容性是非常重要的。
涉及的主要類型:
struct Feature //(CompatSet的內部結構體)標識一個具體的特性
class FeatureSet //(CompatSet的內部類) 標識一組特性集合
struct CompatSet // 兼容性管理的主要類型
CompatSet |- Feature
|- FeatureSet
struct Feature:
該類型包含兩個重要屬性:
id:特性的唯一標識
name:特性的名字
class FeatureSet:
該類型包含兩個重要屬性:
mask:標識該組特性的位圖
names:是一個map,key爲特性的id,value爲特性的name
struct CompatSet:
該類型中包含了三個重要的屬性,分別是:compat、ro_compat、incompat,都是FeatureSet實例。
compat:該組中的特性支持與否,對讀寫沒有任何影響。
ro_compat:該組中的特性,如果不支持,則會影響寫入操作,讀操作沒有影響。
incompat:該組中的特性,如果不支持,則會影響讀寫操作。
其中主要的成員函數:
/* does this filesystem implementation have the
features required to read the other? */
bool CompatSet::readable(CompatSet const& other) const {
return !((other.incompat.mask ^ incompat.mask) & other.incompat.mask);
}
/* does this filesystem implementation have the
features required to write the other? */
bool CompatSet::writeable(CompatSet const& other) const {
return readable(other) &&
!((other.ro_compat.mask ^ ro_compat.mask) & other.ro_compat.mask);
}
/* Compare this CompatSet to another.
* CAREFULLY NOTE: This operation is NOT commutative.
* a > b DOES NOT imply that b < a.
* If returns:
* 0: The CompatSets have the same feature set.
* 1: This CompatSet's features are a strict superset of the other's.
* -1: This CompatSet is missing at least one feature
* described in the other. It may still have more features, though.
*/
int CompatSet::compare(const CompatSet& other) {
if ((other.compat.mask == compat.mask) &&
(other.ro_compat.mask == ro_compat.mask) &&
(other.incompat.mask == incompat.mask)) return 0;
//okay, they're not the same
//if we're writeable we have a superset of theirs on incompat and ro_compat
if (writeable(other) && !((other.compat.mask ^ compat.mask)
& other.compat.mask)) return 1;
//if we make it here, we weren't writeable or had a difference compat set
return -1;
}
/* Get the features supported by other CompatSet but not this one,
¦* as a CompatSet.
¦*/
CompatSet CompatSet::unsupported(CompatSet& other) {
¦ CompatSet diff;
¦ uint64_t other_compat =
¦ ¦ ((other.compat.mask ^ compat.mask) & other.compat.mask);
¦ uint64_t other_ro_compat =
¦ ¦ ((other.ro_compat.mask ^ ro_compat.mask) & other.ro_compat.mask);
¦ uint64_t other_incompat =
¦ ¦ ((other.incompat.mask ^ incompat.mask) & other.incompat.mask);
¦ for (int id = 1; id < 64; ++id) {
¦ ¦ uint64_t mask = (uint64_t)1 << id;
¦ ¦ if (mask & other_compat) {
diff.compat.insert( Feature(id, other.compat.names[id]));
¦ ¦ }
¦ ¦ if (mask & other_ro_compat) {
diff.ro_compat.insert(Feature(id, other.ro_compat.names[id]));
¦ ¦ }
¦ ¦ if (mask & other_incompat) {
diff.incompat.insert( Feature(id, other.incompat.names[id]));
¦ ¦ }
¦ }
¦ return diff;
}