scrub could be verifying backtrace for an inode for which some of its
ancestors might be replicas, e.g. (from a custom debug build) some
ancestors of an inode with divergent backtrace were replicas:
```
[inode 0x3000000502f [...122,head] /volumes/qa/sv_0/
b98de6ea-ed40-40d0-8e1a-
9433a337a387/client.0/tmp/payload.2/multiple_rsync_payload.190107/firmware/ rep@0.1 fragtree_t(*^3) v6663 f(v493 m2024-05-01T06:38:16.403080+0000 388=289+99) n(v139 rc2024-05-01T06:55:35.239345+0000
b467915716 4880=4534+346) old_inodes=24 (inest mix) (ifile mix) | lock=0 importing=0 dirfrag=1 0x55a85d244680]
```
In such cases, the backpointer version (inode_backpointer_t::version) of the
in-memory (cache) inode can fall behind the on-disk version causing scrub to
consider the inode backtrace as divergent (memory version < on-disk version).
Sample:
```
"ondisk_value":"(2)0x30000005bba:
[<0x3000000502f/mwl8k v2126>,
<0x30000005026/firmware v6663>,
<0x30000005025/multiple_rsync_payload.190107 v3041>,
<0x10000005894/payload.2 v4873>,
<0x10000000005/tmp v6193>,<0x10000000003/client.0 v5964>,
<0x10000000002/
b98de6ea-ed40-40d0-8e1a-
9433a337a387 v5817>
,<0x10000000001/sv_0 v5837>,
<0x10000000000/qa v6241>,
<0x1/volumes v4036>]
"memoryvalue":"(2)0x30000005bba:
[<0x3000000502f/mwl8k v2126>,
<0x30000005026/firmware v6663>,
<0x30000005025/multiple_rsync_payload.190107 v3041>,
<0x10000005894/payload.2 v4873>,
<0x10000000005/tmp v6081>,
<0x10000000003/client.0 v5942>,
<0x10000000002/
b98de6ea-ed40-40d0-8e1a-
9433a337a387 v5709>,
<0x10000000001/sv_0 v5819>,
<0x10000000000/qa v6121>,
<0x1/volumes v4022>]
```
Fixes: http://tracker.ceph.com/issues/64730
Signed-off-by: Venky Shankar <vshankar@redhat.com>
(cherry picked from commit
b98bb860a899ba86caf2d0e4d82b5882a13ae840)
return false;
}
+bool CInode::is_any_ancestor_inode_a_replica() {
+ CDentry *pdn = get_parent_dn();
+ while (pdn) {
+ CInode *diri = pdn->get_dir()->get_inode();
+ if (!diri->is_auth()) {
+ return true;
+ }
+ pdn = diri->get_parent_dn();
+ }
+
+ return false;
+}
+
bool CInode::is_projected_ancestor_of(const CInode *other) const
{
while (other) {
dout(20) << "divergent backtraces are acceptable when dn "
"is being purged or has been renamed or moved to a "
"different directory " << *in << dendl;
- }
+ } else if (in->is_any_ancestor_inode_a_replica()) {
+ results->backtrace.passed = true;
+ dout(20) << "divergent backtraces are acceptable when some "
+ "ancestor inodes are replicas " << *in << dendl;
+ }
} else {
results->backtrace.passed = true;
}
const CDir *get_projected_parent_dir() const;
CDir *get_projected_parent_dir();
CInode *get_parent_inode();
+
+ bool is_any_ancestor_inode_a_replica();
bool is_lt(const MDSCacheObject *r) const override {
const CInode *o = static_cast<const CInode*>(r);