1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-17 21:35:45 +02:00

roots: determine transid_max without open()ing every subvol root

Scan the roots tree directly for roots other than 5 (the FS root), and
use btrfs_get_root_transid on root_fd for root 5.  This avoids filling
up the root FD cache every time we want a new transid_max.  Now the only
reason we open a subvol root FD is to open a file within the subvol.

transid_max may be the same as the FS root's transid, in which case
the search loop is not necessary.  Place a counter (transid_max_miss)
to see if we ever need to look at root items. If this counter never goes
above zero, or does so very rarely, we can delete the search loop.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
Zygo Blaxell 2018-01-28 23:00:56 -05:00
parent 4f0bc78a4c
commit af250f7732

View File

@ -196,22 +196,44 @@ BeesRoots::transid_min()
uint64_t
BeesRoots::transid_max_nocache()
{
// FIXME: get transid_max from any of the many trees we are searching with
// TREE_SEARCH_V2. Here we are open()ing every subvol.
uint64_t rv = 0;
uint64_t root = 0;
uint64_t root = BTRFS_FS_TREE_OBJECTID;
BEESNOTE("Calculating transid_max (" << rv << " as of root " << root << ")");
BEESTRACE("Calculating transid_max...");
do {
root = next_root(root);
if (root) {
catch_all([&]() {
auto transid = btrfs_get_root_transid(open_root(root));
rv = max(rv, transid);
});
rv = btrfs_get_root_transid(root);
// XXX: Do we need any of this? Or is
// m_transid_re.update(btrfs_get_root_transid(BTRFS_FS_TREE_OBJECTID)) good enough?
BtrfsIoctlSearchKey sk;
sk.tree_id = BTRFS_ROOT_TREE_OBJECTID;
sk.min_type = sk.max_type = BTRFS_ROOT_BACKREF_KEY;
sk.min_objectid = root;
while (true) {
sk.nr_items = 1024;
sk.do_ioctl(m_ctx->root_fd());
if (sk.m_result.empty()) {
break;
}
} while (root);
for (auto i : sk.m_result) {
sk.next_min(i);
if (i.type == BTRFS_ROOT_BACKREF_KEY) {
if (i.transid > rv) {
BEESLOGDEBUG("transid_max root " << i.objectid << " parent " << i.offset << " transid " << i.transid);
BEESCOUNT(transid_max_miss);
}
root = i.objectid;
}
if (i.transid > rv) {
rv = i.transid;
}
}
}
m_transid_re.update(rv);
return rv;
}
@ -634,7 +656,7 @@ BeesRoots::next_root(uint64_t root)
// BTRFS_FS_TREE_OBJECTID has no backref keys so we can't find it that way
if (root < BTRFS_FS_TREE_OBJECTID) {
// BEESLOG("First root is BTRFS_FS_TREE_OBJECTID = " << BTRFS_FS_TREE_OBJECTID);
// BEESLOGDEBUG("First root is BTRFS_FS_TREE_OBJECTID = " << BTRFS_FS_TREE_OBJECTID);
return BTRFS_FS_TREE_OBJECTID;
}
@ -654,7 +676,7 @@ BeesRoots::next_root(uint64_t root)
for (auto i : sk.m_result) {
sk.next_min(i);
if (i.type == BTRFS_ROOT_BACKREF_KEY) {
// BEESLOG("Found root " << i.objectid << " parent " << i.offset);
// BEESLOGDEBUG("Found root " << i.objectid << " parent " << i.offset << " transid " << i.transid);
return i.objectid;
}
}