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:
parent
4f0bc78a4c
commit
af250f7732
@ -196,22 +196,44 @@ BeesRoots::transid_min()
|
|||||||
uint64_t
|
uint64_t
|
||||||
BeesRoots::transid_max_nocache()
|
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 rv = 0;
|
||||||
uint64_t root = 0;
|
uint64_t root = BTRFS_FS_TREE_OBJECTID;
|
||||||
BEESNOTE("Calculating transid_max (" << rv << " as of root " << root << ")");
|
BEESNOTE("Calculating transid_max (" << rv << " as of root " << root << ")");
|
||||||
BEESTRACE("Calculating transid_max...");
|
BEESTRACE("Calculating transid_max...");
|
||||||
do {
|
|
||||||
root = next_root(root);
|
rv = btrfs_get_root_transid(root);
|
||||||
if (root) {
|
|
||||||
catch_all([&]() {
|
// XXX: Do we need any of this? Or is
|
||||||
auto transid = btrfs_get_root_transid(open_root(root));
|
// m_transid_re.update(btrfs_get_root_transid(BTRFS_FS_TREE_OBJECTID)) good enough?
|
||||||
rv = max(rv, transid);
|
|
||||||
});
|
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;
|
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
|
// BTRFS_FS_TREE_OBJECTID has no backref keys so we can't find it that way
|
||||||
if (root < BTRFS_FS_TREE_OBJECTID) {
|
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;
|
return BTRFS_FS_TREE_OBJECTID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,7 +676,7 @@ BeesRoots::next_root(uint64_t root)
|
|||||||
for (auto i : sk.m_result) {
|
for (auto i : sk.m_result) {
|
||||||
sk.next_min(i);
|
sk.next_min(i);
|
||||||
if (i.type == BTRFS_ROOT_BACKREF_KEY) {
|
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;
|
return i.objectid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user