From c7ca3b6760d62651ad8c1a8fb2c2590c590720ad Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 22 Jan 2019 14:54:02 -0800 Subject: [PATCH] Expose IsFilePinned through FiemapWriter. This is needed for gsid to verify whether a file is pinned. Bug: 122556707 Test: manual test Change-Id: I662402294028597241ce11f86421f6ebb4a3cd6b --- fs_mgr/libfiemap_writer/fiemap_writer.cpp | 15 +++++++++++++++ fs_mgr/libfiemap_writer/fiemap_writer_test.cpp | 8 ++++++++ .../include/libfiemap_writer/fiemap_writer.h | 12 ++++++++++++ 3 files changed, 35 insertions(+) diff --git a/fs_mgr/libfiemap_writer/fiemap_writer.cpp b/fs_mgr/libfiemap_writer/fiemap_writer.cpp index 164fc9145..6ccdb5781 100644 --- a/fs_mgr/libfiemap_writer/fiemap_writer.cpp +++ b/fs_mgr/libfiemap_writer/fiemap_writer.cpp @@ -359,6 +359,21 @@ static bool IsFilePinned(int file_fd, const std::string& file_path, uint32_t fs_ return moved_blocks_nr == 0; } +bool FiemapWriter::HasPinnedExtents(const std::string& file_path) { + android::base::unique_fd fd(open(file_path.c_str(), O_NOFOLLOW | O_CLOEXEC | O_RDONLY)); + if (fd < 0) { + PLOG(ERROR) << "open: " << file_path; + return false; + } + + struct statfs64 sfs; + if (fstatfs64(fd, &sfs)) { + PLOG(ERROR) << "fstatfs64: " << file_path; + return false; + } + return IsFilePinned(fd, file_path, sfs.f_type); +} + static void LogExtent(uint32_t num, const struct fiemap_extent& ext) { LOG(INFO) << "Extent #" << num; LOG(INFO) << " fe_logical: " << ext.fe_logical; diff --git a/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp b/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp index 51015378c..3d20ff32d 100644 --- a/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp +++ b/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp @@ -51,6 +51,8 @@ class FiemapWriterTest : public ::testing::Test { testfile = ::android::base::StringPrintf("%s/testdata/%s", exec_dir.c_str(), tinfo->name()); } + void TearDown() override { unlink(testfile.c_str()); } + // name of the file we use for testing std::string testfile; }; @@ -102,6 +104,12 @@ TEST_F(FiemapWriterTest, CheckProgress) { EXPECT_EQ(invocations, 2); } +TEST_F(FiemapWriterTest, CheckPinning) { + auto ptr = FiemapWriter::Open(testfile, 4096); + ASSERT_NE(ptr, nullptr); + EXPECT_TRUE(FiemapWriter::HasPinnedExtents(testfile)); +} + TEST_F(FiemapWriterTest, CheckBlockDevicePath) { FiemapUniquePtr fptr = FiemapWriter::Open(testfile, 4096); EXPECT_EQ(fptr->size(), 4096); diff --git a/fs_mgr/libfiemap_writer/include/libfiemap_writer/fiemap_writer.h b/fs_mgr/libfiemap_writer/include/libfiemap_writer/fiemap_writer.h index ab78f9361..a0085cfe2 100644 --- a/fs_mgr/libfiemap_writer/include/libfiemap_writer/fiemap_writer.h +++ b/fs_mgr/libfiemap_writer/include/libfiemap_writer/fiemap_writer.h @@ -45,6 +45,18 @@ class FiemapWriter final { bool create = true, std::function progress = {}); + // Check that a file still has the same extents since it was last opened with FiemapWriter, + // assuming the file was not resized outside of FiemapWriter. Returns false either on error + // or if the file was not pinned. + // + // This will always return true on Ext4. On F2FS, it will return true if either of the + // following cases are true: + // - The file was never pinned. + // - The file is pinned and has not been moved by the GC. + // Thus, this method should only be called for pinned files (such as those returned by + // FiemapWriter::Open). + static bool HasPinnedExtents(const std::string& file_path); + // Syncs block device writes. bool Flush() const;