From 3d3082bc82e552e5787f660b547dc839c2cf6554 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 26 Feb 2023 01:14:10 -0800 Subject: [PATCH] Minor optimizations --- native/src/core/module.cpp | 37 ++++++++++---------- native/src/core/node.hpp | 69 ++++++++++++++++++++------------------ 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/native/src/core/module.cpp b/native/src/core/module.cpp index b5b6a0dca..5cdd4efd7 100644 --- a/native/src/core/module.cpp +++ b/native/src/core/module.cpp @@ -30,7 +30,7 @@ string node_entry::mirror_dir; *************************/ tmpfs_node::tmpfs_node(node_entry *node) : dir_node(node, this) { - if (!skip_mirror) { + if (!skip_mirror()) { string mirror = mirror_path(); if (auto dir = open_dir(mirror.data())) { set_exist(true); @@ -54,14 +54,11 @@ tmpfs_node::tmpfs_node(node_entry *node) : dir_node(node, this) { } bool dir_node::prepare() { - bool to_tmpfs = skip_mirror; - if (!exist()) { - // If not exist, we need to create it by mounting tmpfs - to_tmpfs = true; - set_exist(true); - } + // If direct replace or not exist, mount ourselves as tmpfs + bool upgrade_to_tmpfs = skip_mirror() || !exist(); + for (auto it = children.begin(); it != children.end();) { - // We need to upgrade to tmpfs node if any child: + // We also need to upgrade to tmpfs node if any child: // - Target does not exist // - Source or target is a symlink (since we cannot bind mount symlink) bool cannot_mnt; @@ -80,12 +77,12 @@ bool dir_node::prepare() { it = children.erase(it); continue; } - // Tell parent to upgrade self to tmpfs - to_tmpfs = true; + upgrade_to_tmpfs = true; } if (auto dn = dyn_cast(it->second)) { - if (skip_mirror) { - dn->skip_mirror = true; + if (skip_mirror()) { + // Propagate skip mirror state to all children + dn->set_skip_mirror(true); } if (dn->prepare()) { // Upgrade child to tmpfs @@ -94,7 +91,7 @@ bool dir_node::prepare() { } ++it; } - return to_tmpfs; + return upgrade_to_tmpfs; } void dir_node::collect_module_files(const char *module, int dfd) { @@ -103,20 +100,20 @@ void dir_node::collect_module_files(const char *module, int dfd) { return; for (dirent *entry; (entry = xreaddir(dir.get()));) { - inter_node *dn; if (entry->d_name == ".replace"sv) { - skip_mirror = true; + set_skip_mirror(true); continue; } if (entry->d_type == DT_DIR) { + inter_node *node; if (auto it = children.find(entry->d_name); it == children.end()) { - dn = emplace(entry->d_name, entry->d_name); + node = emplace(entry->d_name, entry->d_name); } else { - dn = dyn_cast(it->second); + node = dyn_cast(it->second); } - if (dn) { - dn->collect_module_files(module, dirfd(dir.get())); + if (node) { + node->collect_module_files(module, dirfd(dir.get())); } } else { emplace(entry->d_name, module, entry); @@ -169,7 +166,7 @@ void tmpfs_node::mount() { if (!isa(parent())) { auto worker_dir = MAGISKTMP + "/" WORKERDIR + dest; mkdirs(worker_dir.data(), 0); - create_and_mount(skip_mirror ? "replace" : "tmpfs", worker_dir); + create_and_mount(skip_mirror() ? "replace" : "tmpfs", worker_dir); } else { // We don't need another layer of tmpfs if parent is tmpfs mkdir(dest.data(), 0); diff --git a/native/src/core/node.hpp b/native/src/core/node.hpp index 46339f65d..aba9a44c2 100644 --- a/native/src/core/node.hpp +++ b/native/src/core/node.hpp @@ -55,18 +55,23 @@ public: protected: template node_entry(const char *name, uint8_t file_type, T*) - : _name(name), _file_type(file_type), _node_type(type_id()) {} + : _name(name), _file_type(file_type & 15), _node_type(type_id()) {} template explicit node_entry(T*) : _file_type(0), _node_type(type_id()) {} - void consume(node_entry *other); + virtual void consume(node_entry *other) { + _name.swap(other->_name); + _file_type = other->_file_type; + _parent = other->_parent; + delete other; + } + void create_and_mount(const char *reason, const string &src); - // Use top bit of _file_type for node exist status + // Use bit 7 of _file_type for exist status bool exist() const { return static_cast(_file_type & (1 << 7)); } void set_exist(bool b) { if (b) _file_type |= (1 << 7); else _file_type &= ~(1 << 7); } - uint8_t file_type() const { return static_cast(_file_type & ~(1 << 7)); } private: friend class dir_node; @@ -74,21 +79,21 @@ private: template friend bool isa(node_entry *node); + uint8_t file_type() const { return static_cast(_file_type & 15); } + // Node properties string _name; - uint8_t _file_type; - const uint8_t _node_type; - dir_node *_parent = nullptr; // Cache, it should only be used within prepare string _node_path; + + uint8_t _file_type; + const uint8_t _node_type; }; class dir_node : public node_entry { public: - friend void node_entry::consume(node_entry *other); - using map_type = map; using iterator = map_type::iterator; @@ -98,6 +103,10 @@ public: children.clear(); } + /************** + * Entrypoints + **************/ + // Traverse through module directories to generate a tree of module files void collect_module_files(const char *module, int dfd); @@ -160,16 +169,30 @@ protected: template dir_node(const char *name, T *self) : node_entry(name, DT_DIR, self) { if constexpr (std::is_same_v) - _root = self; + _root = self; } template dir_node(node_entry *node, T *self) : node_entry(self) { - consume(node); if constexpr (std::is_same_v) - _root = self; + _root = self; + dir_node::consume(node); } + void consume(node_entry *other) override { + if (auto o = dyn_cast(other)) { + children.merge(o->children); + for (auto &pair : children) + pair.second->_parent = this; + } + node_entry::consume(other); + } + + // Use bit 6 of _file_type + // Skip binding mirror for this directory + bool skip_mirror() const { return static_cast(_file_type & (1 << 6)); } + void set_skip_mirror(bool b) { if (b) _file_type |= (1 << 6); else _file_type &= ~(1 << 6); } + template T *iterator_to_node(iterator it) { return static_cast(it == children.end() ? nullptr : it->second); @@ -229,9 +252,6 @@ protected: // dir nodes host children map_type children; - // Skip binding mirror for this directory - bool skip_mirror = false; - private: // Root node lookup cache root_node *_root = nullptr; @@ -259,7 +279,7 @@ public: : node_entry(entry->d_name, entry->d_type, this), module(module) {} module_node(node_entry *node, const char *module) : node_entry(this), module(module) { - consume(node); + node_entry::consume(node); } void mount() override; @@ -294,20 +314,3 @@ const string &node_entry::node_path() { _node_path = _parent->node_path() + '/' + _name; return _node_path; } - -void node_entry::consume(node_entry *other) { - _name.swap(other->_name); - _file_type = other->_file_type; - _parent = other->_parent; - - // Merge children if both is dir - if (auto a = dyn_cast(this)) { - if (auto b = dyn_cast(other)) { - a->skip_mirror = b->skip_mirror; - a->children.merge(b->children); - for (auto &pair : a->children) - pair.second->_parent = a; - } - } - delete other; -}