1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <inttypes.h> 8 #include <memory> 9 10 #include <fbl/macros.h> 11 #include <lib/ftl/ndm-driver.h> 12 #include <zircon/types.h> 13 14 struct XfsVol; 15 16 namespace ftl { 17 18 // Interface for an upper-layer (block device) view of an FTL. 19 class FtlInstance { 20 public: ~FtlInstance()21 virtual ~FtlInstance() {} 22 23 // Notified when an FTL volume is created. A block device can be created 24 // with up to num_pages blocks of page_size bytes each. The implementation 25 // should return true to acknowledge the success of the operation. 26 virtual bool OnVolumeAdded(uint32_t page_size, uint32_t num_pages) = 0; 27 }; 28 29 // Exposes the upper layer (block device) interface of the FTL. 30 class Volume { 31 public: 32 // Basic stats about the state of the device. 33 struct Stats { 34 size_t ram_used; 35 uint32_t wear_count; 36 int garbage_level; // Percentage of free space that can be garbage-collected. 37 }; 38 Volume()39 Volume() {} ~Volume()40 virtual ~Volume() {} 41 42 // Performs the object initialization. Returns an error string, or nullptr 43 // on success. Will synchronously call FtlInstance::OnVolumeAdded on success. 44 virtual const char* Init(std::unique_ptr<NdmDriver> driver) = 0; 45 46 // Removes the volume and re-attaches to it. This is roughly equivalent to 47 // what a shutdown / restart would to in the real world (this functionality 48 // is basically intended for testing). Returns an error string, or nullptr 49 // on success. Will synchronously call FtlInstance::OnVolumeAdded on success. 50 virtual const char* ReAttach() = 0; 51 52 // Synchronously Read or Write num_pages starting at first_page. 53 virtual zx_status_t Read(uint32_t first_page, int num_pages, void* buffer) = 0; 54 virtual zx_status_t Write(uint32_t first_page, int num_pages, const void* buffer) = 0; 55 56 // Issues a command to format the FTL (aka, delete all data). 57 virtual zx_status_t Format() = 0; 58 59 // Marks the volume as in use (Mount) or not (Unmount). 60 virtual zx_status_t Mount() = 0; 61 virtual zx_status_t Unmount() = 0; 62 63 // Flushes all data to the device. 64 virtual zx_status_t Flush() = 0; 65 66 // Marks num_pages starting from first_page as not-needed. 67 virtual zx_status_t Trim(uint32_t first_page, uint32_t num_pages) = 0; 68 69 // Goes through one cycle of synchronous garbage collection. Returns ZX_OK 70 // on success and ZX_ERR_STOP where there is no more work to do. 71 virtual zx_status_t GarbageCollect() = 0; 72 73 // Returns basic stats about the device. 74 virtual zx_status_t GetStats(Stats* stats) = 0; 75 }; 76 77 // Implementation of the Volume interface. 78 class VolumeImpl : public Volume { 79 public: VolumeImpl(FtlInstance * owner)80 VolumeImpl(FtlInstance* owner) : owner_(owner) {} ~VolumeImpl()81 ~VolumeImpl() final {} 82 83 // Volume interface. 84 const char* Init(std::unique_ptr<NdmDriver> driver) final; 85 const char* ReAttach() final; 86 zx_status_t Read(uint32_t first_page, int num_pages, void* buffer) final; 87 zx_status_t Write(uint32_t first_page, int num_pages, const void* buffer) final; 88 zx_status_t Format() final; 89 zx_status_t Mount() final; 90 zx_status_t Unmount() final; 91 zx_status_t Flush() final; 92 zx_status_t Trim(uint32_t first_page, uint32_t num_pages) final; 93 zx_status_t GarbageCollect() final; 94 zx_status_t GetStats(Stats* stats) final; 95 96 // Internal notification of added volumes. This is forwarded to 97 // FtlInstance::OnVolumeAdded. 98 bool OnVolumeAdded(const XfsVol* ftl); 99 100 DISALLOW_COPY_ASSIGN_AND_MOVE(VolumeImpl); 101 102 private: 103 // Returns true if the volume was created successfully. 104 bool Created() const; 105 106 // Creates the underlying NDM volume and mounts it. If successful, |owner_| 107 // will be notified about the new volume inside this call. 108 const char* Attach(); 109 110 // Members that are initialized when the volume is created (OnVolumeAdded): 111 void* vol_ = nullptr; // FTL volume handle for callbacks. 112 const char* name_ = nullptr; // Volume name from driver. 113 int (*report_)(void* vol, uint32_t msg, ...) = nullptr; 114 int (*write_pages_)(const void* buffer, uint32_t first_page, int count, void* vol) = nullptr; 115 int (*read_pages_)(void* buffer, uint32_t first_page, int count, void* vol) = nullptr; 116 117 FtlInstance* owner_; 118 std::unique_ptr<NdmDriver> driver_; 119 }; 120 121 } // namespace ftl 122