}
}
-void OpenFileTable::get_ref(CInode *in)
+void OpenFileTable::get_ref(CInode *in, frag_t fg)
{
do {
auto p = anchor_map.find(in->ino());
+ if (!in->is_dir()) {
+ ceph_assert(fg == -1U);
+ ceph_assert(p == anchor_map.end());
+ }
+
if (p != anchor_map.end()) {
ceph_assert(in->state_test(CInode::STATE_TRACKEDBYOFT));
ceph_assert(p->second.nref > 0);
p->second.nref++;
+
+ if (fg != -1U) {
+ auto ret = p->second.frags.insert(fg);
+ ceph_assert(ret.second);
+ dirty_items.emplace(in->ino(), (int)DIRTY_UNDEF);
+ }
break;
}
ceph_assert(ret.second == true);
in->state_set(CInode::STATE_TRACKEDBYOFT);
+ if (fg != -1U)
+ ret.first->second.frags.insert(fg);
+
auto ret1 = dirty_items.emplace(in->ino(), (int)DIRTY_NEW);
if (!ret1.second) {
int omap_idx = ret1.first->second;
}
in = pin;
+ fg = -1U;
} while (in);
}
-void OpenFileTable::put_ref(CInode *in)
+void OpenFileTable::put_ref(CInode *in, frag_t fg)
{
do {
ceph_assert(in->state_test(CInode::STATE_TRACKEDBYOFT));
ceph_assert(p != anchor_map.end());
ceph_assert(p->second.nref > 0);
+ if (!in->is_dir()) {
+ ceph_assert(fg == -1U);
+ ceph_assert(p->second.nref == 1);
+ }
+
if (p->second.nref > 1) {
p->second.nref--;
+ if (fg != -1U) {
+ auto ret = p->second.frags.erase(fg);
+ ceph_assert(ret);
+ dirty_items.emplace(in->ino(), (int)DIRTY_UNDEF);
+ }
break;
}
ceph_assert(p->second.d_name == "");
}
+ if (fg != -1U) {
+ ceph_assert(p->second.frags.size() == 1);
+ ceph_assert(*p->second.frags.begin() == fg);
+ }
+
int omap_idx = p->second.omap_idx;
anchor_map.erase(p);
in->state_clear(CInode::STATE_TRACKEDBYOFT);
}
in = pin;
+ fg = -1U;
} while (in);
}
void OpenFileTable::add_inode(CInode *in)
{
dout(10) << __func__ << " " << *in << dendl;
- if (!in->is_dir()) {
- auto p = anchor_map.find(in->ino());
- ceph_assert(p == anchor_map.end());
- }
get_ref(in);
}
void OpenFileTable::remove_inode(CInode *in)
{
dout(10) << __func__ << " " << *in << dendl;
- if (!in->is_dir()) {
- auto p = anchor_map.find(in->ino());
- ceph_assert(p != anchor_map.end());
- ceph_assert(p->second.nref == 1);
- }
put_ref(in);
}
dout(10) << __func__ << " " << *dir << dendl;
ceph_assert(!dir->state_test(CDir::STATE_TRACKEDBYOFT));
dir->state_set(CDir::STATE_TRACKEDBYOFT);
- auto ret = dirfrags.insert(dir->dirfrag());
- ceph_assert(ret.second);
- get_ref(dir->get_inode());
- dirty_items.emplace(dir->ino(), (int)DIRTY_UNDEF);
+ get_ref(dir->get_inode(), dir->get_frag());
}
void OpenFileTable::remove_dirfrag(CDir *dir)
dout(10) << __func__ << " " << *dir << dendl;
ceph_assert(dir->state_test(CDir::STATE_TRACKEDBYOFT));
dir->state_clear(CDir::STATE_TRACKEDBYOFT);
- auto p = dirfrags.find(dir->dirfrag());
- ceph_assert(p != dirfrags.end());
- dirfrags.erase(p);
- dirty_items.emplace(dir->ino(), (int)DIRTY_UNDEF);
- put_ref(dir->get_inode());
+ put_ref(dir->get_inode(), dir->get_frag());
}
void OpenFileTable::notify_link(CInode *in)
}
for (auto& it : dirty_items) {
- frag_vec_t frags;
auto p = anchor_map.find(it.first);
- if (p != anchor_map.end()) {
- for (auto q = dirfrags.lower_bound(dirfrag_t(it.first, 0));
- q != dirfrags.end() && q->ino == it.first;
- ++q)
- frags.push_back(q->frag);
- }
if (first_commit) {
auto q = loaded_anchor_map.find(it.first);
if (q != loaded_anchor_map.end()) {
ceph_assert(p != anchor_map.end());
p->second.omap_idx = q->second.omap_idx;
- bool same = p->second == q->second;
- if (same) {
- auto r = loaded_dirfrags.lower_bound(dirfrag_t(it.first, 0));
- for (const auto& fg : frags) {
- if (r == loaded_dirfrags.end() || !(*r == dirfrag_t(it.first, fg))) {
- same = false;
- break;
- }
- ++r;
- }
- if (same && r != loaded_dirfrags.end() && r->ino == it.first)
- same = false;
- }
+ bool same = (p->second == q->second);
loaded_anchor_map.erase(q);
if (same)
continue;
if (p != anchor_map.end()) {
bufferlist bl;
encode(p->second, bl);
- encode(frags, bl);
+ encode((__u32)0, bl); // frags set was encoded here
ctl.write_size += bl.length() + len + 2 * sizeof(__u32);
ctl.to_update[key].swap(bl);
}
}
loaded_anchor_map.clear();
- loaded_dirfrags.clear();
}
size_t total_items = 0;
std::make_tuple());
RecoveredAnchor& anchor = it->second;
decode(anchor, p);
+ frag_vec_t frags; // unused
+ decode(frags, p);
ceph_assert(ino == anchor.ino);
anchor.omap_idx = idx;
anchor.auth = MDS_RANK_NONE;
- frag_vec_t frags;
- decode(frags, p);
- for (const auto& fg : frags)
- loaded_dirfrags.insert(loaded_dirfrags.end(), dirfrag_t(anchor.ino, fg));
if (loaded_anchor_map.size() > count)
++omap_num_items[idx];
ceph_assert(count > 0);
--count;
}
- auto r = loaded_dirfrags.lower_bound(dirfrag_t(ino, 0));
- while (r != loaded_dirfrags.end() && r->ino == ino)
- loaded_dirfrags.erase(r++);
}
op_vec.resize(op_vec.size() + 1);
new C_OnFinisher(c, mds->finisher));
}
-bool OpenFileTable::get_ancestors(inodeno_t ino, vector<inode_backpointer_t>& ancestors,
- mds_rank_t& auth_hint)
+void OpenFileTable::_get_ancestors(const Anchor& parent,
+ vector<inode_backpointer_t>& ancestors,
+ mds_rank_t& auth_hint)
{
- auto p = loaded_anchor_map.find(ino);
- if (p == loaded_anchor_map.end())
- return false;
-
- inodeno_t dirino = p->second.dirino;
- if (dirino == inodeno_t(0))
- return false;
+ inodeno_t dirino = parent.dirino;
+ std::string_view d_name = parent.d_name;
bool first = true;
ancestors.clear();
while (true) {
- ancestors.push_back(inode_backpointer_t(dirino, p->second.d_name, 0));
+ ancestors.push_back(inode_backpointer_t(dirino, string{d_name}, 0));
- p = loaded_anchor_map.find(dirino);
+ auto p = loaded_anchor_map.find(dirino);
if (p == loaded_anchor_map.end())
break;
auth_hint = p->second.auth;
dirino = p->second.dirino;
+ d_name = p->second.d_name;
if (dirino == inodeno_t(0))
break;
first = false;
}
- return true;
}
class C_OFT_OpenInoFinish: public MDSContext {
num_opening_inodes--;
if (num_opening_inodes == 0) {
if (prefetch_state == DIR_INODES) {
- prefetch_state = DIRFRAGS;
- _prefetch_dirfrags();
+ if (g_conf().get_val<bool>("mds_oft_prefetch_dirfrags")) {
+ prefetch_state = DIRFRAGS;
+ _prefetch_dirfrags();
+ } else {
+ prefetch_state = FILE_INODES;
+ _prefetch_inodes();
+ }
} else if (prefetch_state == FILE_INODES) {
prefetch_state = DONE;
logseg_destroyed_inos.clear();
ceph_assert(prefetch_state == DIRFRAGS);
MDCache *mdcache = mds->mdcache;
- std::vector<CDir*> fetch_queue;
+ std::set<CDir*> fetch_queue;
- CInode *last_in = nullptr;
- for (auto df : loaded_dirfrags) {
- CInode *diri;
- if (last_in && last_in->ino() == df.ino) {
- diri = last_in;
- } else {
- diri = mdcache->get_inode(df.ino);
- if (!diri)
- continue;
- last_in = diri;
- }
+ for (auto& it : loaded_anchor_map) {
+ if (it.second.frags.empty())
+ continue;
+ CInode *diri = mdcache->get_inode(it.first);
+ if (!diri)
+ continue;
if (diri->state_test(CInode::STATE_REJOINUNDEF))
continue;
- CDir *dir = diri->get_dirfrag(df.frag);
- if (dir) {
- if (dir->is_auth() && !dir->is_complete())
- fetch_queue.push_back(dir);
- } else {
- frag_vec_t leaves;
- diri->dirfragtree.get_leaves_under(df.frag, leaves);
- for (const auto& leaf : leaves) {
- if (diri->is_auth()) {
- dir = diri->get_or_open_dirfrag(mdcache, leaf);
- } else {
- dir = diri->get_dirfrag(leaf);
+ for (auto& fg: it.second.frags) {
+ CDir *dir = diri->get_dirfrag(fg);
+ if (dir) {
+ if (dir->is_auth() && !dir->is_complete())
+ fetch_queue.insert(dir);
+ } else {
+ frag_vec_t leaves;
+ diri->dirfragtree.get_leaves_under(fg, leaves);
+ if (leaves.empty())
+ leaves.push_back(diri->dirfragtree[fg.value()]);
+ for (auto& leaf : leaves) {
+ if (diri->is_auth()) {
+ dir = diri->get_or_open_dirfrag(mdcache, leaf);
+ } else {
+ dir = diri->get_dirfrag(leaf);
+ }
+ if (dir && dir->is_auth() && !dir->is_complete())
+ fetch_queue.insert(dir);
}
- if (dir && dir->is_auth() && !dir->is_complete())
- fetch_queue.push_back(dir);
}
}
}
continue;
num_opening_inodes++;
- mdcache->open_ino(it.first, pool, new C_OFT_OpenInoFinish(this, it.first), false);
+
+ auto fin = new C_OFT_OpenInoFinish(this, it.first);
+ if (it.second.dirino != inodeno_t(0)) {
+ vector<inode_backpointer_t> ancestors;
+ mds_rank_t auth_hint = MDS_RANK_NONE;
+ _get_ancestors(it.second, ancestors, auth_hint);
+ mdcache->open_ino(it.first, pool, fin, false, false, &ancestors, auth_hint);
+ } else {
+ mdcache->open_ino(it.first, pool, fin, false);
+ }
if (!(num_opening_inodes % 1000))
mds->heartbeat_reset();