• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 <stdint.h>
20 
21 #include <functional>
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include <android-base/unique_fd.h>
27 
28 #include "fiemap_writer.h"
29 
30 namespace android {
31 namespace fiemap_writer {
32 
33 // Wrapper around FiemapWriter that is able to split images across files if
34 // necessary.
35 class SplitFiemap final {
36   public:
37     using ProgressCallback = std::function<bool(uint64_t, uint64_t)>;
38 
39     // Create a new split fiemap file. If |max_piece_size| is 0, the number of
40     // pieces will be determined automatically by detecting the filesystem.
41     // Otherwise, the file will be split evenly (with the remainder in the
42     // final file).
43     static std::unique_ptr<SplitFiemap> Create(const std::string& file_path, uint64_t file_size,
44                                                uint64_t max_piece_size,
45                                                ProgressCallback progress = {});
46 
47     // Open an existing split fiemap file.
48     static std::unique_ptr<SplitFiemap> Open(const std::string& file_path);
49 
50     ~SplitFiemap();
51 
52     // Return a list of all files created for a split file.
53     static bool GetSplitFileList(const std::string& file_path, std::vector<std::string>* list);
54 
55     // Destroy all components of a split file. If the root file does not exist,
56     // this returns true and does not report an error.
57     static bool RemoveSplitFiles(const std::string& file_path, std::string* message = nullptr);
58 
59     // Return whether all components of a split file still have pinned extents.
60     bool HasPinnedExtents() const;
61 
62     // Helper method for writing data that spans files. Note there is no seek
63     // method (yet); this starts at 0 and increments the position by |bytes|.
64     bool Write(const void* data, uint64_t bytes);
65 
66     // Flush all writes to all split files.
67     bool Flush();
68 
69     const std::vector<struct fiemap_extent>& extents();
70     uint32_t block_size() const;
size()71     uint64_t size() const { return total_size_; }
72     const std::string& bdev_path() const;
73 
74     // Non-copyable & Non-movable
75     SplitFiemap(const SplitFiemap&) = delete;
76     SplitFiemap& operator=(const SplitFiemap&) = delete;
77     SplitFiemap& operator=(SplitFiemap&&) = delete;
78     SplitFiemap(SplitFiemap&&) = delete;
79 
80   private:
81     SplitFiemap() = default;
82     void AddFile(FiemapUniquePtr&& file);
83 
84     bool creating_ = false;
85     std::string list_file_;
86     std::vector<FiemapUniquePtr> files_;
87     std::vector<struct fiemap_extent> extents_;
88     uint64_t total_size_ = 0;
89 
90     // Most recently open file and position for Write().
91     size_t cursor_index_ = 0;
92     uint64_t cursor_file_pos_ = 0;
93     android::base::unique_fd cursor_fd_;
94 };
95 
96 }  // namespace fiemap_writer
97 }  // namespace android
98