mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 21:35:45 +02:00
roots: rework btrfs send workaround using btrfs-tree
Drop the cache since we no longer have to open a file every time we check a subvol's status. Also stop counting workaround events at the root level twice. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
4d59939b07
commit
f98599407f
@ -1,5 +1,6 @@
|
|||||||
#include "bees.h"
|
#include "bees.h"
|
||||||
|
|
||||||
|
#include "crucible/btrfs-tree.h"
|
||||||
#include "crucible/cache.h"
|
#include "crucible/cache.h"
|
||||||
#include "crucible/ntoa.h"
|
#include "crucible/ntoa.h"
|
||||||
#include "crucible/string.h"
|
#include "crucible/string.h"
|
||||||
@ -199,35 +200,14 @@ BeesRoots::transid_min()
|
|||||||
uint64_t
|
uint64_t
|
||||||
BeesRoots::transid_max_nocache()
|
BeesRoots::transid_max_nocache()
|
||||||
{
|
{
|
||||||
uint64_t rv = 0;
|
|
||||||
BEESNOTE("Calculating transid_max");
|
BEESNOTE("Calculating transid_max");
|
||||||
BEESTRACE("Calculating transid_max");
|
BEESTRACE("Calculating transid_max");
|
||||||
|
|
||||||
// We look for the root of the extent tree and read its transid.
|
// We look for the root of the extent tree and read its transid.
|
||||||
// Should run in O(1) time and be fairly reliable.
|
// Should run in O(1) time and be fairly reliable.
|
||||||
BtrfsIoctlSearchKey sk;
|
const auto bti = m_root_fetcher.root(BTRFS_EXTENT_TREE_OBJECTID);
|
||||||
sk.tree_id = BTRFS_ROOT_TREE_OBJECTID;
|
BEESTRACE("extracting transid from " << bti);
|
||||||
sk.min_type = sk.max_type = BTRFS_ROOT_ITEM_KEY;
|
const auto rv = bti.transid();
|
||||||
sk.min_objectid = sk.max_objectid = BTRFS_EXTENT_TREE_OBJECTID;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
sk.nr_items = 4;
|
|
||||||
BEESTRACE("transid_max search sk " << sk);
|
|
||||||
sk.do_ioctl(m_ctx->root_fd());
|
|
||||||
|
|
||||||
if (sk.m_result.empty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are just looking for the highest transid on the filesystem.
|
|
||||||
// We don't care which object it comes from.
|
|
||||||
for (auto i : sk.m_result) {
|
|
||||||
sk.next_min(i, BTRFS_ROOT_ITEM_KEY);
|
|
||||||
if (i.transid > rv) {
|
|
||||||
rv = i.transid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// transid must be greater than zero, or we did something very wrong
|
// transid must be greater than zero, or we did something very wrong
|
||||||
THROW_CHECK1(runtime_error, rv, rv > 0);
|
THROW_CHECK1(runtime_error, rv, rv > 0);
|
||||||
@ -376,7 +356,6 @@ void
|
|||||||
BeesRoots::clear_caches()
|
BeesRoots::clear_caches()
|
||||||
{
|
{
|
||||||
m_ctx->fd_cache()->clear();
|
m_ctx->fd_cache()->clear();
|
||||||
m_root_ro_cache.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -563,14 +542,11 @@ BeesRoots::state_load()
|
|||||||
|
|
||||||
BeesRoots::BeesRoots(shared_ptr<BeesContext> ctx) :
|
BeesRoots::BeesRoots(shared_ptr<BeesContext> ctx) :
|
||||||
m_ctx(ctx),
|
m_ctx(ctx),
|
||||||
|
m_root_fetcher(ctx->root_fd()),
|
||||||
m_crawl_state_file(ctx->home_fd(), crawl_state_filename()),
|
m_crawl_state_file(ctx->home_fd(), crawl_state_filename()),
|
||||||
m_crawl_thread("crawl_transid"),
|
m_crawl_thread("crawl_transid"),
|
||||||
m_writeback_thread("crawl_writeback")
|
m_writeback_thread("crawl_writeback")
|
||||||
{
|
{
|
||||||
m_root_ro_cache.func([&](uint64_t root) -> bool {
|
|
||||||
return is_root_ro_nocache(root);
|
|
||||||
});
|
|
||||||
m_root_ro_cache.max_size(BEES_ROOT_FD_CACHE_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -730,32 +706,22 @@ BeesRoots::open_root(uint64_t rootid)
|
|||||||
return m_ctx->fd_cache()->open_root(rootid);
|
return m_ctx->fd_cache()->open_root(rootid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
BeesRoots::is_root_ro_nocache(uint64_t root)
|
|
||||||
{
|
|
||||||
BEESTRACE("checking subvol flags on root " << root);
|
|
||||||
Fd root_fd = open_root(root);
|
|
||||||
BEESTRACE("checking subvol flags on root " << root << " path " << name_fd(root_fd));
|
|
||||||
|
|
||||||
uint64_t flags = 0;
|
|
||||||
DIE_IF_NON_ZERO(ioctl(root_fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags));
|
|
||||||
if (flags & BTRFS_SUBVOL_RDONLY) {
|
|
||||||
BEESLOGDEBUG("WORKAROUND: Avoiding RO root " << root);
|
|
||||||
BEESCOUNT(root_workaround_btrfs_send);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BeesRoots::is_root_ro(uint64_t root)
|
BeesRoots::is_root_ro(uint64_t root)
|
||||||
{
|
{
|
||||||
// If we are not implementing the workaround there is no need for cache
|
// If we are not working around btrfs send, all roots are rw to us
|
||||||
if (!m_workaround_btrfs_send) {
|
if (!m_workaround_btrfs_send) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_root_ro_cache(root);
|
BEESTRACE("checking subvol flags on root " << root);
|
||||||
|
|
||||||
|
const auto item = m_root_fetcher.root(root);
|
||||||
|
// If we can't access the subvol's root item...guess it's ro?
|
||||||
|
if (!item || item.root_flags() & BTRFS_ROOT_SUBVOL_RDONLY) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef BEES_H
|
#ifndef BEES_H
|
||||||
#define BEES_H
|
#define BEES_H
|
||||||
|
|
||||||
|
#include "crucible/btrfs-tree.h"
|
||||||
#include "crucible/cache.h"
|
#include "crucible/cache.h"
|
||||||
#include "crucible/chatter.h"
|
#include "crucible/chatter.h"
|
||||||
#include "crucible/error.h"
|
#include "crucible/error.h"
|
||||||
@ -533,6 +534,7 @@ public:
|
|||||||
class BeesRoots : public enable_shared_from_this<BeesRoots> {
|
class BeesRoots : public enable_shared_from_this<BeesRoots> {
|
||||||
shared_ptr<BeesContext> m_ctx;
|
shared_ptr<BeesContext> m_ctx;
|
||||||
|
|
||||||
|
BtrfsRootFetcher m_root_fetcher;
|
||||||
BeesStringFile m_crawl_state_file;
|
BeesStringFile m_crawl_state_file;
|
||||||
map<uint64_t, shared_ptr<BeesCrawl>> m_root_crawl_map;
|
map<uint64_t, shared_ptr<BeesCrawl>> m_root_crawl_map;
|
||||||
mutex m_mutex;
|
mutex m_mutex;
|
||||||
@ -545,7 +547,6 @@ class BeesRoots : public enable_shared_from_this<BeesRoots> {
|
|||||||
size_t m_transid_factor = BEES_TRANSID_FACTOR;
|
size_t m_transid_factor = BEES_TRANSID_FACTOR;
|
||||||
Task m_crawl_task;
|
Task m_crawl_task;
|
||||||
bool m_workaround_btrfs_send = false;
|
bool m_workaround_btrfs_send = false;
|
||||||
LRUCache<bool, uint64_t> m_root_ro_cache;
|
|
||||||
|
|
||||||
mutex m_tmpfiles_mutex;
|
mutex m_tmpfiles_mutex;
|
||||||
map<BeesFileId, Fd> m_tmpfiles;
|
map<BeesFileId, Fd> m_tmpfiles;
|
||||||
@ -558,7 +559,6 @@ class BeesRoots : public enable_shared_from_this<BeesRoots> {
|
|||||||
void insert_root(const BeesCrawlState &bcs);
|
void insert_root(const BeesCrawlState &bcs);
|
||||||
Fd open_root_nocache(uint64_t root);
|
Fd open_root_nocache(uint64_t root);
|
||||||
Fd open_root_ino_nocache(uint64_t root, uint64_t ino);
|
Fd open_root_ino_nocache(uint64_t root, uint64_t ino);
|
||||||
bool is_root_ro_nocache(uint64_t root);
|
|
||||||
uint64_t transid_min();
|
uint64_t transid_min();
|
||||||
uint64_t transid_max();
|
uint64_t transid_max();
|
||||||
uint64_t transid_max_nocache();
|
uint64_t transid_max_nocache();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user