1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <linux/fiemap.h> 20 #include <stdint.h> 21 #include <sys/types.h> 22 #include <unistd.h> 23 24 #include <functional> 25 #include <string> 26 #include <vector> 27 28 #include <android-base/unique_fd.h> 29 30 namespace android { 31 namespace fiemap_writer { 32 33 class FiemapWriter; 34 using FiemapUniquePtr = std::unique_ptr<FiemapWriter>; 35 36 class FiemapWriter final { 37 public: 38 // Factory method for FiemapWriter. 39 // The method returns FiemapUniquePtr that contains all the data necessary to be able to write 40 // to the given file directly using raw block i/o. The optional progress callback will be 41 // invoked, if create is true, while the file is being initialized. It receives the bytes 42 // written and the number of total bytes. If the callback returns false, the operation will 43 // fail. 44 // 45 // Note: when create is true, the file size will be aligned up to the nearest file system 46 // block. 47 static FiemapUniquePtr Open(const std::string& file_path, uint64_t file_size, 48 bool create = true, 49 std::function<bool(uint64_t, uint64_t)> progress = {}); 50 51 // Check that a file still has the same extents since it was last opened with FiemapWriter, 52 // assuming the file was not resized outside of FiemapWriter. Returns false either on error 53 // or if the file was not pinned. 54 // 55 // This will always return true on Ext4. On F2FS, it will return true if either of the 56 // following cases are true: 57 // - The file was never pinned. 58 // - The file is pinned and has not been moved by the GC. 59 // Thus, this method should only be called for pinned files (such as those returned by 60 // FiemapWriter::Open). 61 static bool HasPinnedExtents(const std::string& file_path); 62 63 // Returns the underlying block device of a file. This will look past device-mapper layers. 64 // If an intermediate device-mapper layer would not maintain a 1:1 mapping (i.e. is a non- 65 // trivial dm-linear), then this will fail. If device-mapper nodes are encountered, then 66 // |uses_dm| will be set to true. 67 static bool GetBlockDeviceForFile(const std::string& file_path, std::string* bdev_path, 68 bool* uses_dm = nullptr); 69 70 ~FiemapWriter() = default; 71 file_path()72 const std::string& file_path() const { return file_path_; }; size()73 uint64_t size() const { return file_size_; }; bdev_path()74 const std::string& bdev_path() const { return bdev_path_; }; block_size()75 uint64_t block_size() const { return block_size_; }; extents()76 const std::vector<struct fiemap_extent>& extents() { return extents_; }; fs_type()77 uint32_t fs_type() const { return fs_type_; } 78 79 // Non-copyable & Non-movable 80 FiemapWriter(const FiemapWriter&) = delete; 81 FiemapWriter& operator=(const FiemapWriter&) = delete; 82 FiemapWriter& operator=(FiemapWriter&&) = delete; 83 FiemapWriter(FiemapWriter&&) = delete; 84 85 private: 86 // Name of the file managed by this class. 87 std::string file_path_; 88 // Block device on which we have created the file. 89 std::string bdev_path_; 90 91 // Size in bytes of the file this class is writing 92 uint64_t file_size_; 93 94 // total size in bytes of the block device 95 uint64_t bdev_size_; 96 97 // Filesystem type where the file is being created. 98 // See: <uapi/linux/magic.h> for filesystem magic numbers 99 uint32_t fs_type_; 100 101 // block size as reported by the kernel of the underlying block device; 102 uint64_t block_size_; 103 104 // This file's fiemap 105 std::vector<struct fiemap_extent> extents_; 106 107 FiemapWriter() = default; 108 }; 109 110 } // namespace fiemap_writer 111 } // namespace android 112