Add a variant of ReadFstabFromFile for /proc/mounts.

The variant excludes the code that is not for /proc/mounts, and
therefore saves code size when being called.

Also, after this change, the call to `SkipMountingPartitions` is skipped
for /proc/mounts because it is not needed.

Bug: 287958783
Test: atest CtsFsMgrTestCases
Change-Id: Ie243257fa2e87e666be7decf97ec36c806bc4524
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index c3c10ba..c85e831 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -51,6 +51,7 @@
 namespace {
 
 constexpr char kDefaultAndroidDtDir[] = "/proc/device-tree/firmware/android";
+constexpr char kProcMountsPath[] = "/proc/mounts";
 
 struct FlagList {
     const char *name;
@@ -699,9 +700,7 @@
     }
 }
 
-bool ReadFstabFromFile(const std::string& path, Fstab* fstab_out) {
-    const bool is_proc_mounts = (path == "/proc/mounts");
-
+static bool ReadFstabFromFileCommon(const std::string& path, Fstab* fstab_out) {
     std::string fstab_str;
     if (!android::base::ReadFileToString(path, &fstab_str, /* follow_symlinks = */ true)) {
         PERROR << __FUNCTION__ << "(): failed to read file: '" << path << "'";
@@ -709,11 +708,22 @@
     }
 
     Fstab fstab;
-    if (!ParseFstabFromString(fstab_str, is_proc_mounts, &fstab)) {
+    if (!ParseFstabFromString(fstab_str, path == kProcMountsPath, &fstab)) {
         LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << path << "'";
         return false;
     }
-    if (!is_proc_mounts) {
+
+    EnableMandatoryFlags(&fstab);
+
+    *fstab_out = std::move(fstab);
+    return true;
+}
+
+bool ReadFstabFromFile(const std::string& path, Fstab* fstab) {
+    if (!ReadFstabFromFileCommon(path, fstab)) {
+        return false;
+    }
+    if (path != kProcMountsPath) {
         if (!access(android::gsi::kGsiBootedIndicatorFile, F_OK)) {
             std::string dsu_slot;
             if (!android::gsi::GetActiveDsu(&dsu_slot)) {
@@ -725,20 +735,23 @@
                 PERROR << __FUNCTION__ << "(): failed to read DSU LP names";
                 return false;
             }
-            TransformFstabForDsu(&fstab, dsu_slot, Split(lp_names, ","));
+            TransformFstabForDsu(fstab, dsu_slot, Split(lp_names, ","));
         } else if (errno != ENOENT) {
             PERROR << __FUNCTION__ << "(): failed to access() DSU booted indicator";
             return false;
         }
+
+        SkipMountingPartitions(fstab, false /* verbose */);
     }
-
-    SkipMountingPartitions(&fstab, false /* verbose */);
-    EnableMandatoryFlags(&fstab);
-
-    *fstab_out = std::move(fstab);
     return true;
 }
 
+bool ReadFstabFromProcMounts(Fstab* fstab) {
+    // Don't call `ReadFstabFromFile` because the code for `path != kProcMountsPath` has an extra
+    // code size cost, even if it's never executed.
+    return ReadFstabFromFileCommon(kProcMountsPath, fstab);
+}
+
 // Returns fstab entries parsed from the device tree if they exist
 bool ReadFstabFromDt(Fstab* fstab, bool verbose) {
     std::string fstab_buf = ReadFstabFromDt();
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index a914b53..9cb1546 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -101,6 +101,7 @@
 bool SkipMountWithConfig(const std::string& skip_config, Fstab* fstab, bool verbose);
 
 bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
+bool ReadFstabFromProcMounts(Fstab* fstab);
 bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);
 bool ReadDefaultFstab(Fstab* fstab);
 bool SkipMountingPartitions(Fstab* fstab, bool verbose = false);