Loading fs_mgr/fs_mgr.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,46 @@ bool fs_mgr_is_f2fs(const std::string& blk_device) { return sb == cpu_to_le32(F2FS_SUPER_MAGIC); } static void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb) { std::string block_device; if (!Realpath(entry_block_device, &block_device)) { PERROR << "Failed to realpath " << entry_block_device; return; } static constexpr std::string_view kDevBlockPrefix("/dev/block/"); if (!android::base::StartsWith(block_device, kDevBlockPrefix)) { LWARNING << block_device << " is not a block device"; return; } DeviceMapper& dm = DeviceMapper::Instance(); while (true) { std::string block_name = block_device; if (android::base::StartsWith(block_device, kDevBlockPrefix)) { block_name = block_device.substr(kDevBlockPrefix.length()); } std::string sys_partition = android::base::StringPrintf("/sys/class/block/%s/partition", block_name.c_str()); struct stat info; if (lstat(sys_partition.c_str(), &info) == 0) { // it has a partition like "sda12". block_name += "/.."; } std::string sys_ra = android::base::StringPrintf("/sys/class/block/%s/queue/read_ahead_kb", block_name.c_str()); std::string size = android::base::StringPrintf("%llu", (long long)size_kb); android::base::WriteStringToFile(size, sys_ra.c_str()); LINFO << "Set readahead_kb: " << size << " on " << sys_ra; auto parent = dm.GetParentBlockDeviceByPath(block_device); if (!parent) { return; } block_device = *parent; } } // // Prepare the filesystem on the given block device to be mounted. // Loading @@ -667,6 +707,11 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry& } mkdir(mount_point.c_str(), 0755); // Don't need to return error, since it's a salt if (entry.readahead_size_kb != -1) { SetReadAheadSize(blk_device, entry.readahead_size_kb); } int fs_stat = 0; if (is_extfs(entry.fs_type)) { Loading fs_mgr/fs_mgr_fstab.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,13 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } else { entry->reserved_size = static_cast<off64_t>(size); } } else if (StartsWith(flag, "readahead_size_kb=")) { int val; if (ParseInt(arg, &val, 0, 16 * 1024)) { entry->readahead_size_kb = val; } else { LWARNING << "Warning: readahead_size_kb= flag malformed (0 ~ 16MB): " << arg; } } else if (StartsWith(flag, "eraseblk=")) { // The erase block size flag is followed by an = and the flash erase block size. Get it, // check that it is a power of 2 and at least 4096, and return it. Loading fs_mgr/include_fstab/fstab/fstab.h +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ struct FstabEntry { int max_comp_streams = 0; off64_t zram_size = 0; off64_t reserved_size = 0; off64_t readahead_size_kb = -1; std::string encryption_options; off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; Loading fs_mgr/tests/fs_mgr_test.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -1097,3 +1097,59 @@ TEST(fs_mgr, UserdataMountedFromDefaultFstab) { ASSERT_NE(nullptr, fs_mgr_get_mounted_entry_for_userdata(&fstab, block_device)) << "/data wasn't mounted from default fstab"; } TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_Readahead_Size_KB) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); std::string fstab_contents = R"fs( source none0 swap defaults readahead_size_kb=blah source none1 swap defaults readahead_size_kb=128 source none2 swap defaults readahead_size_kb=5% source none3 swap defaults readahead_size_kb=5kb source none4 swap defaults readahead_size_kb=16385 source none5 swap defaults readahead_size_kb=-128 source none6 swap defaults readahead_size_kb=0 )fs"; ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path)); Fstab fstab; EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab)); ASSERT_EQ(7U, fstab.size()); FstabEntry::FsMgrFlags flags = {}; auto entry = fstab.begin(); EXPECT_EQ("none0", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none1", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(128, entry->readahead_size_kb); entry++; EXPECT_EQ("none2", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none3", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none4", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none5", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none6", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(0, entry->readahead_size_kb); } Loading
fs_mgr/fs_mgr.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,46 @@ bool fs_mgr_is_f2fs(const std::string& blk_device) { return sb == cpu_to_le32(F2FS_SUPER_MAGIC); } static void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb) { std::string block_device; if (!Realpath(entry_block_device, &block_device)) { PERROR << "Failed to realpath " << entry_block_device; return; } static constexpr std::string_view kDevBlockPrefix("/dev/block/"); if (!android::base::StartsWith(block_device, kDevBlockPrefix)) { LWARNING << block_device << " is not a block device"; return; } DeviceMapper& dm = DeviceMapper::Instance(); while (true) { std::string block_name = block_device; if (android::base::StartsWith(block_device, kDevBlockPrefix)) { block_name = block_device.substr(kDevBlockPrefix.length()); } std::string sys_partition = android::base::StringPrintf("/sys/class/block/%s/partition", block_name.c_str()); struct stat info; if (lstat(sys_partition.c_str(), &info) == 0) { // it has a partition like "sda12". block_name += "/.."; } std::string sys_ra = android::base::StringPrintf("/sys/class/block/%s/queue/read_ahead_kb", block_name.c_str()); std::string size = android::base::StringPrintf("%llu", (long long)size_kb); android::base::WriteStringToFile(size, sys_ra.c_str()); LINFO << "Set readahead_kb: " << size << " on " << sys_ra; auto parent = dm.GetParentBlockDeviceByPath(block_device); if (!parent) { return; } block_device = *parent; } } // // Prepare the filesystem on the given block device to be mounted. // Loading @@ -667,6 +707,11 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry& } mkdir(mount_point.c_str(), 0755); // Don't need to return error, since it's a salt if (entry.readahead_size_kb != -1) { SetReadAheadSize(blk_device, entry.readahead_size_kb); } int fs_stat = 0; if (is_extfs(entry.fs_type)) { Loading
fs_mgr/fs_mgr_fstab.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,13 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } else { entry->reserved_size = static_cast<off64_t>(size); } } else if (StartsWith(flag, "readahead_size_kb=")) { int val; if (ParseInt(arg, &val, 0, 16 * 1024)) { entry->readahead_size_kb = val; } else { LWARNING << "Warning: readahead_size_kb= flag malformed (0 ~ 16MB): " << arg; } } else if (StartsWith(flag, "eraseblk=")) { // The erase block size flag is followed by an = and the flash erase block size. Get it, // check that it is a power of 2 and at least 4096, and return it. Loading
fs_mgr/include_fstab/fstab/fstab.h +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ struct FstabEntry { int max_comp_streams = 0; off64_t zram_size = 0; off64_t reserved_size = 0; off64_t readahead_size_kb = -1; std::string encryption_options; off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; Loading
fs_mgr/tests/fs_mgr_test.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -1097,3 +1097,59 @@ TEST(fs_mgr, UserdataMountedFromDefaultFstab) { ASSERT_NE(nullptr, fs_mgr_get_mounted_entry_for_userdata(&fstab, block_device)) << "/data wasn't mounted from default fstab"; } TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_Readahead_Size_KB) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); std::string fstab_contents = R"fs( source none0 swap defaults readahead_size_kb=blah source none1 swap defaults readahead_size_kb=128 source none2 swap defaults readahead_size_kb=5% source none3 swap defaults readahead_size_kb=5kb source none4 swap defaults readahead_size_kb=16385 source none5 swap defaults readahead_size_kb=-128 source none6 swap defaults readahead_size_kb=0 )fs"; ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path)); Fstab fstab; EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab)); ASSERT_EQ(7U, fstab.size()); FstabEntry::FsMgrFlags flags = {}; auto entry = fstab.begin(); EXPECT_EQ("none0", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none1", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(128, entry->readahead_size_kb); entry++; EXPECT_EQ("none2", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none3", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none4", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none5", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none6", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(0, entry->readahead_size_kb); }