diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2021-03-11 11:58:29 +0000 |
---|---|---|
committer | Gabriel Masei <gabriel.masei@1and1.ro> | 2021-03-12 14:03:57 +0200 |
commit | de89da293a40385e0ef0194f8a0a0197eb39efe6 (patch) | |
tree | 3558cef7651cd754600589856673045f864b15e1 | |
parent | Don't steal focus from inputs in calc (diff) | |
download | online-feature/michael/overlayfs.tar.gz online-feature/michael/overlayfs.zip |
Optimize for overlayfs by forcing an initial copy to linkable/
feature/michael/overlayfs
built-in hard-link support performs extremely badly otherwise.
Change-Id: I26d5080590538cb6342d64e2e0a4023bbc84c427
Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
-rw-r--r-- | kit/Kit.cpp | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 7c68c21eca..9d427bd941 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -16,6 +16,8 @@ #include <dlfcn.h> #ifdef __linux__ #include <ftw.h> +#include <sys/vfs.h> +#include <linux/magic.h> #include <sys/capability.h> #include <sys/sysmacros.h> #endif @@ -150,12 +152,34 @@ namespace LinkOrCopyType linkOrCopyType; std::string sourceForLinkOrCopy; Path destinationForLinkOrCopy; + bool forceInitialCopy; // some stackable file-systems have very slow first hard link creation std::string linkableForLinkOrCopy; // Place to stash copies that we can hard-link from std::chrono::time_point<std::chrono::steady_clock> linkOrCopyStartTime; bool linkOrCopyVerboseLogging = false; unsigned linkOrCopyFileCount = 0; // Track to help quantify the link-or-copy performance. constexpr unsigned SlowLinkOrCopyLimitInSecs = 2; // After this many seconds, start spamming the logs. + bool detectSlowStackingFileSystem(const std::string &directory) + { +#ifdef __linux__ + struct statfs fs = {}; + if (::statfs(directory.c_str(), &fs) != 0) + { + LOG_SYS("statfs failed on '" << directory << "'"); + return false; + } + switch (fs.f_type) { +// case FUSE_SUPER_MAGIC: ? + case OVERLAYFS_SUPER_MAGIC: + return true; + default: + return false; + } +#else + return false; +#endif + } + /// Returns the LinkOrCopyType as a human-readable string (for logging). std::string linkOrCopyTypeString(LinkOrCopyType type) { @@ -253,17 +277,22 @@ namespace if (linkOrCopyVerboseLogging) LOG_INF("Linking file \"" << fpath << "\" to \"" << newPath << '"'); - // first try a simple hard-link - if (link(fpath, newPath.c_str()) == 0) - return; + if (!forceInitialCopy) + { + // first try a simple hard-link + if (link(fpath, newPath.c_str()) == 0) + return; + } + // else always copy before linking to linkable/ // incrementally build our 'linkable/' copy nearby static bool canChown = true; // only if we can get permissions right - if (errno == EXDEV && canChown) + if ((forceInitialCopy || errno == EXDEV) && canChown) { // then copy somewhere closer and hard link from there - LOG_TRC("link(\"" << fpath << "\", \"" << newPath << "\") failed: " << strerror(errno) - << ". Will try to link template."); + if (!forceInitialCopy) + LOG_TRC("link(\"" << fpath << "\", \"" << newPath << "\") failed: " << strerror(errno) + << ". Will try to link template."); std::string linkableCopy = linkableForLinkOrCopy + fpath; if (::link(linkableCopy.c_str(), newPath.c_str()) == 0) @@ -432,6 +461,7 @@ namespace linkableForLinkOrCopy = linkable; linkOrCopyFileCount = 0; linkOrCopyStartTime = std::chrono::steady_clock::now(); + forceInitialCopy = detectSlowStackingFileSystem(destination.toString()); if (nftw(source.c_str(), linkOrCopyFunction, 10, FTW_ACTIONRETVAL|FTW_PHYS) == -1) { |