libfstab: Add const overload of GetEntryForMountPoint()

Const version of GetEntryForMountPoint() accepts a pointer to const
Fstab and returns a pointer to const FstabEntry.

In order to refrain from adding more boilderplate, simplify the
implementation of GetEntryForMountPoint() to "return first entry of
GetEntriesForMountPoint()". The added overhead should be negligible as
fstab is usually small (around dozens of entries max), so iterating the
whole list is not computationally expensive.

Also templatize the implementation of GetEntriesByPred() to reduce the
amount of boilerplate.

Bug: 243501054
Test: Presubmit
Change-Id: I046d61d68385825656bb7bc7177c0d1d3e8b36e1
This commit is contained in:
Yi-Yo Chiang 2022-12-12 23:57:04 +08:00
parent 70d34f01a3
commit d45750aa2c
2 changed files with 32 additions and 19 deletions

View file

@ -488,13 +488,21 @@ std::set<std::string> ExtraBootDevices(const Fstab& fstab) {
return boot_devices;
}
template <typename Pred>
std::vector<FstabEntry*> GetEntriesByPred(Fstab* fstab, const Pred& pred) {
// Helper class that maps Fstab* -> FstabEntry; const Fstab* -> const FstabEntry.
template <typename FstabPtr>
struct FstabPtrEntry {
using is_const_fstab = std::is_const<std::remove_pointer_t<FstabPtr>>;
using type = std::conditional_t<is_const_fstab::value, const FstabEntry, FstabEntry>;
};
template <typename FstabPtr, typename FstabPtrEntryType = typename FstabPtrEntry<FstabPtr>::type,
typename Pred>
std::vector<FstabPtrEntryType*> GetEntriesByPred(FstabPtr fstab, const Pred& pred) {
if (fstab == nullptr) {
return {};
}
std::vector<FstabEntry*> entries;
for (auto&& entry : *fstab) {
std::vector<FstabPtrEntryType*> entries;
for (FstabPtrEntryType& entry : *fstab) {
if (pred(entry)) {
entries.push_back(&entry);
}
@ -835,25 +843,27 @@ bool ReadDefaultFstab(Fstab* fstab) {
return !fstab->empty();
}
FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path) {
if (fstab == nullptr) {
return nullptr;
}
for (auto& entry : *fstab) {
if (entry.mount_point == path) {
return &entry;
}
}
return nullptr;
}
std::vector<FstabEntry*> GetEntriesForMountPoint(Fstab* fstab, const std::string& path) {
return GetEntriesByPred(fstab,
[&path](const FstabEntry& entry) { return entry.mount_point == path; });
}
std::vector<const FstabEntry*> GetEntriesForMountPoint(const Fstab* fstab,
const std::string& path) {
return GetEntriesByPred(fstab,
[&path](const FstabEntry& entry) { return entry.mount_point == path; });
}
FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path) {
std::vector<FstabEntry*> entries = GetEntriesForMountPoint(fstab, path);
return entries.empty() ? nullptr : entries.front();
}
const FstabEntry* GetEntryForMountPoint(const Fstab* fstab, const std::string& path) {
std::vector<const FstabEntry*> entries = GetEntriesForMountPoint(fstab, path);
return entries.empty() ? nullptr : entries.front();
}
std::set<std::string> GetBootDevices() {
// First check bootconfig, then kernel commandline, then the device tree
std::string dt_file_name = get_android_dt_dir() + "/boot_devices";

View file

@ -105,10 +105,13 @@ bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);
bool ReadDefaultFstab(Fstab* fstab);
bool SkipMountingPartitions(Fstab* fstab, bool verbose = false);
FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path);
// The Fstab can contain multiple entries for the same mount point with different configurations.
std::vector<FstabEntry*> GetEntriesForMountPoint(Fstab* fstab, const std::string& path);
// Like GetEntriesForMountPoint() but return only the first entry or nullptr if no entry is found.
FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path);
const FstabEntry* GetEntryForMountPoint(const Fstab* fstab, const std::string& path);
// This method builds DSU fstab entries and transfer the fstab.
//
// fstab points to the unmodified fstab.