Skip to content

Commit aef054d

Browse files
committed
lq: not use links[0]
1 parent ece0322 commit aef054d

5 files changed

Lines changed: 154 additions & 28 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#pragma once
2+
3+
#include "lustre_types.hpp"
4+
5+
#include <string>
6+
#include <vector>
7+
8+
namespace duckdb {
9+
namespace lustre {
10+
11+
inline std::string BuildStripedShardLinkName(const LustreFID &shard_fid, uint32_t stripe_index) {
12+
return shard_fid.ToString() + ":" + std::to_string(stripe_index);
13+
}
14+
15+
inline const LinkEntry *FindStripedShardLink(const std::vector<LinkEntry> &links, const LustreFID &shard_fid,
16+
uint32_t stripe_index) {
17+
const auto expected_name = BuildStripedShardLinkName(shard_fid, stripe_index);
18+
for (const auto &link : links) {
19+
if (link.parent_fid.IsValid() && link.name == expected_name) {
20+
return &link;
21+
}
22+
}
23+
return nullptr;
24+
}
25+
26+
inline const LinkEntry *FindUniqueParentLink(const std::vector<LinkEntry> &links) {
27+
const LinkEntry *candidate = nullptr;
28+
LustreFID candidate_parent;
29+
30+
for (const auto &link : links) {
31+
if (!link.parent_fid.IsValid()) {
32+
continue;
33+
}
34+
if (!candidate) {
35+
candidate = &link;
36+
candidate_parent = link.parent_fid;
37+
continue;
38+
}
39+
if (link.parent_fid != candidate_parent) {
40+
return nullptr;
41+
}
42+
}
43+
return candidate;
44+
}
45+
46+
inline const LinkEntry *FindUniqueDirectoryLink(const std::vector<LinkEntry> &links) {
47+
const LinkEntry *candidate = nullptr;
48+
49+
for (const auto &link : links) {
50+
if (!link.parent_fid.IsValid()) {
51+
continue;
52+
}
53+
if (!candidate) {
54+
candidate = &link;
55+
continue;
56+
}
57+
if (link.parent_fid != candidate->parent_fid || link.name != candidate->name) {
58+
return nullptr;
59+
}
60+
}
61+
return candidate;
62+
}
63+
64+
inline const LinkEntry *SelectDirectoryParentLink(const std::vector<LinkEntry> &links) {
65+
return FindUniqueDirectoryLink(links);
66+
}
67+
68+
inline const LinkEntry *SelectStripedSlaveParentLink(const std::vector<LinkEntry> &links, const LustreFID &shard_fid,
69+
uint32_t stripe_index) {
70+
if (auto *match = FindStripedShardLink(links, shard_fid, stripe_index)) {
71+
return match;
72+
}
73+
return FindUniqueParentLink(links);
74+
}
75+
76+
} // namespace lustre
77+
} // namespace duckdb

src/lustre_dirmap.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "lustre_dirmap.hpp"
11+
#include "lustre_link_selection.hpp"
1112
#include "mdt_scanner.hpp"
1213

1314
#include "duckdb/common/exception.hpp"
@@ -292,14 +293,18 @@ static void GenerateDirMapRows(const LustreFID &fid, const LustreLMV &lmv,
292293
// Slave/shard: check if master is reachable on any scanned device.
293294
// If yes, skip (the master will emit this shard's mapping).
294295
LustreFID master_fid;
295-
if (!links.empty()) {
296-
master_fid = links[0].parent_fid;
296+
if (auto *master_link = SelectStripedSlaveParentLink(links, fid, lmv.lmv_master_mdt_index)) {
297+
master_fid = master_link->parent_fid;
297298
}
298299

299300
if (master_fid.IsValid() && lstate.IsFIDReachable(master_fid)) {
300301
return;
301302
}
302303

304+
if (!master_fid.IsValid()) {
305+
return;
306+
}
307+
303308
// Fallback: master not in scanned device set. Emit from slave perspective.
304309
LustreDirMapGlobalState::PendingRow row;
305310
row.dir_fid = master_fid;

src/lustre_fid2path.cpp

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "lustre_fid2path.hpp"
10+
#include "lustre_link_selection.hpp"
1011
#include "lustre_types.hpp"
1112
#include "mdt_scanner.hpp"
1213

@@ -25,6 +26,14 @@ namespace lustre {
2526
static const LustreFID ROOT_FID = {0x200000007ULL, 1, 0};
2627
static constexpr idx_t MAX_PATH_DEPTH = 4096;
2728

29+
static const LinkEntry *SelectParentTraversalLink(const LustreFID &fid, const LustreLMV &lmv,
30+
const vector<LinkEntry> &links) {
31+
if (lmv.IsSlave()) {
32+
return SelectStripedSlaveParentLink(links, fid, lmv.lmv_master_mdt_index);
33+
}
34+
return SelectDirectoryParentLink(links);
35+
}
36+
2837
//===----------------------------------------------------------------------===//
2938
// Bind Data - stores device paths (shared across threads)
3039
//===----------------------------------------------------------------------===//
@@ -122,7 +131,9 @@ static unique_ptr<FunctionLocalState> Fid2PathInitLocal(ExpressionState &state,
122131

123132
static bool BuildPathFromLink(Fid2PathLocalState &lstate, const string &name, LustreFID parent_fid, string &path_out) {
124133
vector<string> components;
125-
components.push_back(name);
134+
if (!name.empty()) {
135+
components.push_back(name);
136+
}
126137

127138
LustreFID current_fid = parent_fid;
128139
idx_t depth = 0;
@@ -144,9 +155,20 @@ static bool BuildPathFromLink(Fid2PathLocalState &lstate, const string &name, Lu
144155
return false;
145156
}
146157

147-
// Directories cannot have hardlinks on Linux, so first entry is sufficient
148-
components.push_back(links[0].name);
149-
current_fid = links[0].parent_fid;
158+
LustreLMV lmv;
159+
lstate.scanners[scanner_idx]->ReadInodeLMV(ino, lmv);
160+
161+
auto *parent_link = SelectParentTraversalLink(current_fid, lmv, links);
162+
if (!parent_link) {
163+
return false;
164+
}
165+
166+
// Slave stripes are implementation details. Follow their master link but
167+
// do not expose the synthetic shard name as a path component.
168+
if (!lmv.IsSlave()) {
169+
components.push_back(parent_link->name);
170+
}
171+
current_fid = parent_link->parent_fid;
150172
}
151173

152174
// Build path: reverse components and join with /
@@ -213,13 +235,27 @@ static void Fid2PathExecute(DataChunk &args, ExpressionState &state, Vector &res
213235
continue;
214236
}
215237

238+
LustreLMV lmv;
239+
lstate.scanners[scanner_idx]->ReadInodeLMV(ino, lmv);
240+
216241
// Build a path for each link entry (hardlink)
217242
bool any_success = false;
218-
for (auto &link : links) {
219-
string path;
220-
if (BuildPathFromLink(lstate, link.name, link.parent_fid, path)) {
221-
all_paths[i].push_back(std::move(path));
222-
any_success = true;
243+
if (lmv.IsSlave()) {
244+
auto *parent_link = SelectParentTraversalLink(current_fid, lmv, links);
245+
if (parent_link) {
246+
string path;
247+
if (BuildPathFromLink(lstate, string(), parent_link->parent_fid, path)) {
248+
all_paths[i].push_back(std::move(path));
249+
any_success = true;
250+
}
251+
}
252+
} else {
253+
for (auto &link : links) {
254+
string path;
255+
if (BuildPathFromLink(lstate, link.name, link.parent_fid, path)) {
256+
all_paths[i].push_back(std::move(path));
257+
any_success = true;
258+
}
223259
}
224260
}
225261

src/lustre_link_dirmap.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "lustre_link_dirmap.hpp"
11+
#include "lustre_link_selection.hpp"
1112
#include "lustre_types.hpp"
1213
#include "lustre_scan_state.hpp"
1314
#include "lustre_fid_filter.hpp"
@@ -182,16 +183,19 @@ struct LustreLinkDirMapLocalState : public LocalTableFunctionState {
182183
LustreFID link_fid;
183184
std::vector<LinkEntry> links;
184185
resolve_scanners[sidx]->ReadInodeLinkEA(ino, link_fid, links);
185-
if (!links.empty()) {
186-
entry.dir_fid = links[0].parent_fid;
187-
// Resolve dir_fid device
188-
ext2_ino_t dir_ino;
189-
idx_t dir_sidx;
190-
if (LookupFIDCrossMDT(entry.dir_fid, dir_ino, dir_sidx)) {
191-
entry.dir_device = resolve_device_paths[dir_sidx];
192-
} else {
193-
entry.dir_device.clear();
194-
}
186+
auto *master_link = SelectStripedSlaveParentLink(links, parent_fid, lmv.lmv_master_mdt_index);
187+
if (!master_link) {
188+
return false;
189+
}
190+
191+
entry.dir_fid = master_link->parent_fid;
192+
// Resolve dir_fid device
193+
ext2_ino_t dir_ino;
194+
idx_t dir_sidx;
195+
if (LookupFIDCrossMDT(entry.dir_fid, dir_ino, dir_sidx)) {
196+
entry.dir_device = resolve_device_paths[dir_sidx];
197+
} else {
198+
entry.dir_device.clear();
195199
}
196200
entry.source = "slave";
197201
entry.stripe_index = lmv.lmv_master_mdt_index;

src/lustre_link_inode_dirmap.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "lustre_link_inode_dirmap.hpp"
11+
#include "lustre_link_selection.hpp"
1112
#include "lustre_types.hpp"
1213
#include "lustre_scan_state.hpp"
1314
#include "lustre_fid_filter.hpp"
@@ -237,14 +238,17 @@ struct LIDLocalState : public LocalTableFunctionState {
237238
LustreFID link_fid;
238239
std::vector<LinkEntry> links;
239240
resolve_scanner->ReadInodeLinkEA(ino, link_fid, links);
240-
if (!links.empty()) {
241-
entry.dir_fid = links[0].parent_fid;
242-
ext2_ino_t dir_ino; idx_t dir_sidx;
243-
if (LookupFIDCrossMDT(g, entry.dir_fid, dir_ino, dir_sidx))
244-
entry.dir_device = g.device_paths[dir_sidx];
245-
else
246-
entry.dir_device.clear();
241+
auto *master_link = SelectStripedSlaveParentLink(links, parent_fid, lmv.lmv_master_mdt_index);
242+
if (!master_link) {
243+
return false;
247244
}
245+
246+
entry.dir_fid = master_link->parent_fid;
247+
ext2_ino_t dir_ino; idx_t dir_sidx;
248+
if (LookupFIDCrossMDT(g, entry.dir_fid, dir_ino, dir_sidx))
249+
entry.dir_device = g.device_paths[dir_sidx];
250+
else
251+
entry.dir_device.clear();
248252
entry.source = "slave";
249253
entry.stripe_index = lmv.lmv_master_mdt_index;
250254
entry.stripe_count = lmv.lmv_stripe_count;

0 commit comments

Comments
 (0)