| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROMEOS_MEMORY_USERSPACE_SWAP_SWAP_STORAGE_H_ |
| #define CHROMEOS_MEMORY_USERSPACE_SWAP_SWAP_STORAGE_H_ |
| |
| #include "base/files/file_path.h" |
| #include "base/files/scoped_file.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/synchronization/lock.h" |
| #include "chromeos/chromeos_export.h" |
| #include "chromeos/memory/userspace_swap/region.h" |
| |
| namespace chromeos { |
| namespace memory { |
| namespace userspace_swap { |
| |
| // SwapFile is the implementation for a disk backed swap file. This class is |
| // thread safe as synchronization is handled internally where necessary. |
| class CHROMEOS_EXPORT SwapFile { |
| public: |
| virtual ~SwapFile(); |
| |
| enum Type { |
| // kStandard is a normal file without compression or encryption. |
| kStandard = 0, |
| // kCompressed is an optional compression layer. |
| kCompressed = (1 << 1), |
| // kEncrypted is an optional encryption layer. |
| kEncrypted = (1 << 2), |
| // You can use both modes with a bitwise or kCompressed | kEncrypted. |
| }; |
| |
| // Create a new swap file, this can only be called from the browser as |
| // renderer seccomp policies would not allow it. Note: kEncrypted is |
| // required for ALL swap files, this call will fail without kEncrypted. |
| static std::unique_ptr<SwapFile> Create(Type type); |
| |
| // GetBackingStoreFreeSpaceKB() returns the number of KB free on the backing |
| // device. |
| static uint64_t GetBackingStoreFreeSpaceKB(); |
| |
| // WriteToSwap will write a memory region from |source| into the swap file. |
| // Upon successful completion the method will return true and |swap_region| |
| // will contain the Region for where it was written in swap. This method will |
| // return false on error and errno will be set. |
| virtual bool WriteToSwap(const Region& source, Region* swap_region); |
| |
| // ReadFromSwap reads the |swap_region| from the swap file writing it into |
| // |dest|. The return value is the number of bytes read from the swap file. On |
| // error ReadFromSwap will return -1 and errno will be set. |
| virtual ssize_t ReadFromSwap(const Region& swap_region, const Region& dest); |
| |
| // DropFromSwap can be used to reclaim the disk blocks for |swap_region|, it |
| // punches a hole in the file to accomplish this and may not immediately be |
| // reflected when the block is still partially in use by another region. This |
| // method will return false on failure and errno will be set. |
| virtual bool DropFromSwap(const Region& swap_region); |
| |
| // GetUsageKB returns the number of KiB the swap file is currently using on |
| // disk. |
| virtual uint64_t GetUsageKB() const; |
| |
| // ReleaseFD is used for donating the internal fd. |
| base::ScopedFD ReleaseFD(); |
| |
| protected: |
| static bool GetDirectoryForSwapFile(base::FilePath* file_path); |
| |
| // Given an FD to an already open swap file wrap it into a SwapFile class, |
| // this is primarily for ease of testing each implementation. |
| static std::unique_ptr<SwapFile> WrapFD(base::ScopedFD swap_fd, Type type); |
| |
| explicit SwapFile(base::ScopedFD fd); |
| |
| base::ScopedFD fd_; |
| |
| private: |
| friend class SwapStorageTest; |
| |
| // We use this lock to serialize WriteToSwap calls. (Concurrent reads and |
| // drops are safe, because they use syscalls which do not rely on the file |
| // pointer, specifically pread(2) and fallocate(2) respectively). |
| base::Lock write_lock_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SwapFile); |
| }; |
| |
| } // namespace userspace_swap |
| } // namespace memory |
| } // namespace chromeos |
| |
| #endif // CHROMEOS_MEMORY_USERSPACE_SWAP_SWAP_STORAGE_H_ |