xref: /aosp_15_r20/external/icing/icing/legacy/index/icing-filesystem.h (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Methods for interacting with the filesystem.
16 
17 #ifndef ICING_LEGACY_INDEX_ICING_FILESYSTEM_H_
18 #define ICING_LEGACY_INDEX_ICING_FILESYSTEM_H_
19 
20 #include <sys/types.h>
21 
22 #include <cstddef>
23 #include <cstdint>
24 #include <cstdio>
25 #include <memory>
26 #include <string>
27 #include <unordered_set>
28 #include <utility>
29 #include <vector>
30 
31 namespace icing {
32 namespace lib {
33 
34 // Closes fd when it goes out of scope, if fd >= 0.
35 class IcingScopedFd {
36  public:
fd_(fd)37   explicit IcingScopedFd(int fd = -1) : fd_(fd) {}
38   IcingScopedFd(const IcingScopedFd &) = delete;
IcingScopedFd(IcingScopedFd && other)39   IcingScopedFd(IcingScopedFd &&other) : IcingScopedFd() {
40     *this = std::move(other);
41   }
42 
43   IcingScopedFd &operator=(const IcingScopedFd &) = delete;
44   IcingScopedFd &operator=(IcingScopedFd &&other) {
45     std::swap(fd_, other.fd_);
46     return *this;
47   }
48   ~IcingScopedFd();
49 
is_valid()50   bool is_valid() const { return fd_ >= 0; }
51   int operator*() const { return fd_; }
get()52   int get() const { return fd_; }
53   void reset(int fd = -1);
54 
55  private:
56   int fd_;
57 };
58 
59 struct IcingFILEDeleter {
operatorIcingFILEDeleter60   void operator()(FILE *fp) const {
61     if (fp) {
62       fclose(fp);
63     }
64   }
65 };
66 typedef std::unique_ptr<FILE, IcingFILEDeleter> IcingScopedFILE;
67 
68 // Class containing file operation methods.
69 // If you change methods in this class, don't forget to update the mock:
70 // java/com/google/android/gmscore/integ/modules/icing/jni/index/mock-filesystem.h
71 class IcingFilesystem {
72  public:
73   static const uint64_t kBadFileSize = static_cast<uint64_t>(-1);
74 
IcingFilesystem()75   constexpr IcingFilesystem() {}
~IcingFilesystem()76   virtual ~IcingFilesystem() {}
77 
78   // Deletes a file, returns true on success or if the file did
79   // not yet exist.
80   virtual bool DeleteFile(const char *file_name) const;
81 
82   // Deletes a directory, returns true on success or if the directory did
83   // not yet exist.
84   virtual bool DeleteDirectory(const char *dir_name) const;
85 
86   // Deletes a directory, including any contents, and returns true on
87   // success or if the directory did not yet exist.
88   virtual bool DeleteDirectoryRecursively(const char *dir_name) const;
89 
90   // Returns true if a file exists.  False if the file doesn't exist.
91   // If there is an error getting stat on the file, it logs the error and
92   // asserts.
93   virtual bool FileExists(const char *file_name) const;
94 
95   // Returns true if a directory exists.  False if the file doesn't exist.
96   // If there is an error getting stat on the file, it logs the error and
97   // asserts.
98   virtual bool DirectoryExists(const char *dir_name) const;
99 
100   // Return index to start of basename in file_name. Anything before
101   // basename is the dirname (including the final slash).
102   virtual int GetBasenameIndex(const char *file_name) const;
103 
104   // Return a string containing the basename.
105   virtual std::string GetBasename(const char *file_name) const;
106 
107   // Return a string containing the dirname.
108   virtual std::string GetDirname(const char *file_name) const;
109 
110   // Gets the names of the entries of a given directory. Does not include "."
111   // and "..". Returns false on error.
112   virtual bool ListDirectory(const char *dir_name,
113                              std::vector<std::string> *entries) const;
114 
115   // Adds the names of the entries of a given directory -- recursively if
116   // specified, and excluding files/directories named in exclude -- to entries.
117   // Regardless of exclude, does not include "." and "..".  Excluded files are
118   // excluded at every level.  Returns false on error.
119   //
120   // Example use case: list all files & directories in fooDir/, recursively,
121   // excluding anything named "tmp" or "cache" (presumed directories) and the
122   // files within them.
123   virtual bool ListDirectory(const char *dir_name,
124                              const std::unordered_set<std::string> &exclude,
125                              bool recursive,
126                              std::vector<std::string> *entries) const;
127 
128   // Use glob to return matched files into "matches". Returns false if
129   // glob had an error.
130   //
131   // Cannot match multiple directories so everything up the last slash
132   // must be literal.
133   virtual bool GetMatchingFiles(const char *glob,
134                                 std::vector<std::string> *matches) const;
135 
136   // Opens the file for read/write. Creates if not existing.  Returns
137   // -1 on fail or an open file descriptor on success.
138   virtual int OpenForWrite(const char *file_name) const;
139 
140   // Opens the file for read/write, and positions the file at the
141   // end for appending.  Creates if not existing.  Returns -1 on fail
142   // or an open file descriptor on success.
143   virtual int OpenForAppend(const char *file_name) const;
144 
145   // Opens a file for read only.  Fails if file does exist.  Returns
146   // file descriptor or -1 on fail.  Set quiet to true to suppress
147   // log warnings.
148   virtual int OpenForRead(const char *file_name) const;
149 
150   // Gets the size of a file, given an open file descriptor.
151   // Returns kBadFileSize on error.
152   virtual uint64_t GetFileSize(int fd) const;
153 
154   // Gets the size of a file, given a filename.
155   virtual uint64_t GetFileSize(const char *filename) const;
156 
157   // Truncates the file to the requested size.  Seeks to the
158   // end position of the file after truncate.  Returns false
159   // if fails.
160   virtual bool Truncate(int fd, uint64_t new_size) const;
161 
162   // Truncates the file to the requested size.
163   // Returns false if fails.
164   virtual bool Truncate(const char *filename, uint64_t new_size) const;
165 
166   // Grows the file to the requested size.  Does not change the
167   // position pointer.
168   virtual bool Grow(int fd, uint64_t new_size) const;
169 
170   // Implementation of Grow that calls Pwrite to directly append zero-filled
171   // byte arrays into the file. Does not change the position pointer.
172   //
173   // This is different from Grow (which uses ftruncate), which doesn't actually
174   // allocate an underlying disk block. Grow has lead to crashes in the past as
175   // there is no effective way to signal that disk block allocation failed, and
176   // we end up trying to access memory-mapped region with unallocated disk
177   // block.
178   //
179   // Using Pwrite forces block allocation and ensures that we can return false
180   // when the disk block is not allocated.
181   //
182   // Note: This method does not change the file size if new_size <= current
183   // file size. Caller should use Truncate for reducing the file size.
184   virtual bool GrowUsingPWrite(int fd, uint64_t new_size) const;
185 
186   // Writes to a file.  Returns true if all the data was successfully
187   // written.  Handles interrupted writes.
188   virtual bool Write(int fd, const void *data, size_t data_size) const;
189   virtual bool PWrite(int fd, off_t offset, const void *data,
190                       size_t data_size) const;
191 
192   // Syncs the file to disk (fdatasync). Returns true on success.
193   virtual bool DataSync(int fd) const;
194 
195   // Renames a file.  A file with new_name must not already exist.
196   virtual bool RenameFile(const char *old_name, const char *new_name) const;
197 
198   // Renames two files or directories so their names are swapped.
199   // Both names must already exist.
200   virtual bool SwapFiles(const char *one, const char *two) const;
201 
202   // Creates a directory if it does not yet exist.
203   virtual bool CreateDirectory(const char *dir_name) const;
204 
205   // Creates a directory if it does not yet exist, building the entire path
206   // if it does not yet exist.
207   virtual bool CreateDirectoryRecursively(const char *dir_name) const;
208 
209   // Copy a file.
210   virtual bool CopyFile(const char *src, const char *dst) const;
211 
212   // Compute an adler32 checksum over the [offset, offset+length) span
213   // of an open file.  Returns false if the file could not be read.
214   // The checksum is an input/output variable (whatever value is
215   // stored there will prime the checksum computation).  If length is
216   // 0, can be used to prime a checksum for future appends.
217   virtual bool ComputeChecksum(int fd, uint32_t *checksum, uint64_t offset,
218                                uint64_t length) const;
219 
220   // Compute the disk usage of the given file. Similarly to the
221   // 'du' command, it attempts to estimate the actual disk usage, so for
222   // sparse files it may return less than their length.
223   // Returns kBadFileSize on error.
224   virtual uint64_t GetDiskUsage(int fd) const;
225 
226   // Compute the disk usage of the given file or directory. Similarly to the
227   // 'du' command, it attempts to estimate the actual disk usage, so for
228   // sparse files it may return less than their length. Returns kBadFileSize on
229   // error.
230   // Does not recurse on directories.
231   virtual uint64_t GetFileDiskUsage(const char *path) const;
232 
233   // Compute the disk usage of the given file or directory. Similarly to the
234   // 'du' command, it attempts to estimate the actual disk usage, so for
235   // sparse files it may return less than their length. Returns kBadFileSize on
236   // error.
237   // Recurses on directories.
238   virtual uint64_t GetDiskUsage(const char *path) const;
239 
240   // Increments to_increment by size if size is valid, or sets to_increment
241   // to kBadFileSize if either size or to_increment is kBadFileSize.
242   static void IncrementByOrSetInvalid(uint64_t size, uint64_t *to_increment);
243 
244   // Return -1 if file_size is invalid. Otherwise, return file_size.
SanitizeFileSize(int64_t file_size)245   static int64_t SanitizeFileSize(int64_t file_size) {
246     return (file_size != kBadFileSize) ? file_size : -1;
247   }
248 };
249 
250 }  // namespace lib
251 }  // namespace icing
252 
253 #endif  // ICING_LEGACY_INDEX_ICING_FILESYSTEM_H_
254