From 9a97699dd9045715d9943cf98ca5573708eb1a53 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Tue, 30 Oct 2018 23:31:11 -0400 Subject: [PATCH] roots: reimplement transid_max_nocache using extent tree root ROOT_TREE contains the ROOT_ITEM for EXTENT_TREE. Every modification (that we care about) to a btrfs must go through EXTENT_TREE, and must modify the page in ROOT_TREE pointing to the root of EXTENT_TREE... which makes that a very good source for the filesystem transid. Remove the loop and the root lookups, and just look at one item for max_transid. Also note that every caller of transid_max_nocache() immediately feeds the return value to m_transid_re.update(), so don't do that inside transid_max_nocache(). Signed-off-by: Zygo Blaxell --- src/bees-roots.cc | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/bees-roots.cc b/src/bees-roots.cc index 2e92583..4d6bfe8 100644 --- a/src/bees-roots.cc +++ b/src/bees-roots.cc @@ -198,19 +198,15 @@ uint64_t BeesRoots::transid_max_nocache() { uint64_t rv = 0; - uint64_t root = BTRFS_FS_TREE_OBJECTID; - BEESNOTE("Calculating transid_max (" << rv << " as of root " << root << ")"); - BEESTRACE("Calculating transid_max..."); - - 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? + BEESNOTE("Calculating transid_max"); + BEESTRACE("Calculating transid_max"); + // We look for the root of the extent tree and read its transid. + // Should run in O(1) time and be fairly reliable. BtrfsIoctlSearchKey sk; sk.tree_id = BTRFS_ROOT_TREE_OBJECTID; - sk.min_type = sk.max_type = BTRFS_ROOT_BACKREF_KEY; - sk.min_objectid = root; + sk.min_type = sk.max_type = BTRFS_ROOT_ITEM_KEY; + sk.min_objectid = sk.max_objectid = BTRFS_EXTENT_TREE_OBJECTID; while (true) { sk.nr_items = 1024; @@ -220,21 +216,18 @@ BeesRoots::transid_max_nocache() 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); - 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); + + // transid must be greater than zero, or we did something very wrong + THROW_CHECK1(runtime_error, rv, rv > 0); return rv; }