Handle extremely rare edge case

This commit is contained in:
topjohnwu 2020-04-22 05:04:45 -07:00
parent 486b2c82a7
commit 945a52a99f

View File

@ -417,32 +417,42 @@ bool dir_node::prepare() {
auto child = it->second; auto child = it->second;
if (child->need_clone()) { if (child->need_clone()) {
if (node_type > type_id<skel_node>()) { if (node_type > type_id<skel_node>()) {
// Upgrade will fail, remove unsupported child node // Upgrade will fail
delete child; goto delete_node;
it = children.erase(it);
continue;
} }
// Tell parent to upgrade self to skel // Tell parent to upgrade self to skel
upgrade_skel = true; upgrade_skel = true;
// If child is inter_node, upgrade to module // If child is inter_node, upgrade to module
if (auto nit = upgrade<module_node, inter_node>(it); nit != children.end()) { if (auto nit = upgrade<module_node, inter_node>(it); nit != children.end()) {
it = nit; it = nit;
goto increment; goto next_node;
} }
} }
if (auto dn = dyn_cast<dir_node>(child); dn && dn->is_dir() && !dn->prepare()) { if (auto dn = dyn_cast<dir_node>(child); dn && dn->is_dir() && !dn->prepare()) {
string mirror = dn->mirror_path();
if (access(mirror.data(), F_OK) != 0) {
// It is actually possible that mirror does not exist
goto delete_node;
}
// Upgrade child to skeleton (shall always success) // Upgrade child to skeleton (shall always success)
it = upgrade<skel_node>(it); it = upgrade<skel_node>(it);
auto skel = iter_to_node<skel_node>(it); auto skel = iter_to_node<skel_node>(it);
string mirror = skel->mirror_path();
auto dir = xopen_dir(mirror.data()); auto dir = xopen_dir(mirror.data());
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
// Insert mirror nodes // Insert mirror nodes
skel->emplace<mirror_node>(entry->d_name, entry); skel->emplace<mirror_node>(entry->d_name, entry);
} }
} }
increment: next_node:
++it; ++it;
continue;
delete_node:
// Remove the unsupported child node
delete it->second;
it = children.erase(it);
continue;
} }
return !upgrade_skel; return !upgrade_skel;
} }