} else if (type == BTRFS_FILE_EXTENT_PREALLOC) {
oss << ":prealloc";
}
+ // Generation of the physical extent, from the extent-tree EXTENT_ITEM.
+ // A bytenr is reused after its extent is freed and reallocated, so the
+ // same address can name different extents at different times; the
+ // allocation generation changes on reuse and stays fixed for one extent's
+ // lifetime, so it disambiguates lifetimes in log analysis (e.g. telling a
+ // long-lived canonical from a recycled address). file_extent_generation
+ // is unsuitable — it is per-reference and differs between reflinks of one
+ // physical extent. This is one extra extent-tree probe per formatted
+ // address; it is only paid when an address is rendered into a log line.
+ {
+ BtrfsExtentItemFetcher beif(root_fd);
+ const auto ei = beif.lower_bound(bytenr);
+ if (!!ei && ei.objectid() == bytenr) {
+ oss << "/" << ei.extent_generation();
+ }
+ }
oss << "}";
return oss.str();
}