Skip to content

Commit a66a68b

Browse files
committed
tools/cephfs/DataScan: skip linkages that have been removed
Also: injected_inos may need to store multiple injected primary links found in the metadata pool. This is especially true now that we may have multiple primary links to a directory due to prior commit tools/cephfs/DataScan: create all ancestors during scan_inodes Fixes: https://tracker.ceph.com/issues/63301 Signed-off-by: Patrick Donnelly <[email protected]>
1 parent ff44ab5 commit a66a68b

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

src/tools/cephfs/DataScan.cc

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,10 +1068,18 @@ int DataScan::scan_links()
10681068
dirfrag_t dirfrag() const {
10691069
return dirfrag_t(dirino, frag);
10701070
}
1071+
void print(std::ostream& os) const {
1072+
os << "link_info_t(diri=" << dirino << "." << frag << " name=" << name << " v=" << version << " l=" << nlink << ")";
1073+
}
1074+
bool operator==(const link_info_t& o) const {
1075+
return dirino == o.dirino
1076+
&& frag == o.frag
1077+
&& name == o.name;
1078+
}
10711079
};
10721080
map<inodeno_t, list<link_info_t> > dup_primaries;
10731081
map<inodeno_t, link_info_t> bad_nlink_inos;
1074-
map<inodeno_t, link_info_t> injected_inos;
1082+
multimap<inodeno_t, link_info_t> injected_inos;
10751083

10761084
map<dirfrag_t, set<string> > to_remove;
10771085

@@ -1202,7 +1210,7 @@ int DataScan::scan_links()
12021210
make_move_iterator(end(srnode.snaps)));
12031211
}
12041212
if (dnfirst == CEPH_NOSNAP) {
1205-
injected_inos[ino] = link_info_t(dir_ino, frag_id, dname, inode.inode);
1213+
injected_inos.insert({ino, link_info_t(dir_ino, frag_id, dname, inode.inode)});
12061214
dout(20) << "adding " << ino << " for future processing to fix dnfirst" << dendl;
12071215
}
12081216
}
@@ -1270,6 +1278,7 @@ int DataScan::scan_links()
12701278

12711279
link_info_t newest;
12721280
for (auto& q : p.second) {
1281+
dout(10) << " primary: " << q << dendl;
12731282
if (q.version > newest.version) {
12741283
newest = q;
12751284
} else if (q.version == newest.version &&
@@ -1278,6 +1287,7 @@ int DataScan::scan_links()
12781287
newest = q;
12791288
}
12801289
}
1290+
dout(10) << "newest is: " << newest << dendl;
12811291

12821292
for (auto& q : p.second) {
12831293
// in the middle of dir fragmentation?
@@ -1293,6 +1303,17 @@ int DataScan::scan_links()
12931303
to_remove[q.dirfrag()].insert(key);
12941304
derr << "Remove duplicated ino 0x" << p.first << " from "
12951305
<< q.dirfrag() << "/" << q.name << dendl;
1306+
{
1307+
/* we've removed the injected linkage: don't fix it later */
1308+
auto range = injected_inos.equal_range(p.first);
1309+
for (auto it = range.first; it != range.second; ) {
1310+
if (it->second == q) {
1311+
it = injected_inos.erase(it);
1312+
} else {
1313+
++it;
1314+
}
1315+
}
1316+
}
12961317
}
12971318

12981319
int nlink = 0;
@@ -1307,6 +1328,8 @@ int DataScan::scan_links()
13071328
<< " has " << newest.nlink << dendl;
13081329
bad_nlink_inos[p.first] = newest;
13091330
bad_nlink_inos[p.first].nlink = nlink;
1331+
} else {
1332+
bad_nlink_inos.erase(p.first);
13101333
}
13111334
}
13121335
dup_primaries.clear();

0 commit comments

Comments
 (0)