Read a dentry's leaf name. Tries qstr.name (long names, kmalloc'd buffer) first; falls back to the inline shortname union (d_shortname/d_iname).
| 12 | // Read a dentry's leaf name. Tries qstr.name (long names, kmalloc'd buffer) |
| 13 | // first; falls back to the inline shortname union (d_shortname/d_iname). |
| 14 | std::string read_dentry_name(const Engine& eng, VAddr dentry_va, |
| 15 | const DentryOffsets& d) |
| 16 | { |
| 17 | if (dentry_va == 0) return {}; |
| 18 | |
| 19 | u32 name_len = 0; |
| 20 | VAddr name_ptr = 0; |
| 21 | kva_read_pod(eng, dentry_va + d.d_name + d.qstr_len, name_len); |
| 22 | kva_read_pod(eng, dentry_va + d.d_name + d.qstr_name, name_ptr); |
| 23 | |
| 24 | if (name_len > 0 && name_len <= 255 && name_ptr != 0) { |
| 25 | std::vector<char> buf(name_len + 1, 0); |
| 26 | if (kva_read(eng, name_ptr, buf.data(), name_len)) |
| 27 | return std::string(buf.data(), name_len); |
| 28 | } |
| 29 | |
| 30 | if (d.d_iname == 0) return {}; |
| 31 | constexpr std::size_t kInlineCap = 40; |
| 32 | std::vector<char> in(kInlineCap, 0); |
| 33 | if (kva_read(eng, dentry_va + d.d_iname, in.data(), kInlineCap)) { |
| 34 | std::size_t n = 0; |
| 35 | while (n < kInlineCap && in[n]) ++n; |
| 36 | return std::string(in.data(), n); |
| 37 | } |
| 38 | return {}; |
| 39 | } |
| 40 | |
| 41 | } // anonymous |
| 42 |
no test coverage detected