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 #ifndef __Fuchsia__ 8 #error Fuchsia-only Header 9 #endif 10 11 #include <digest/digest.h> 12 #include <fbl/intrusive_wavl_tree.h> 13 #include <fbl/function.h> 14 #include <fbl/mutex.h> 15 #include <fbl/ref_ptr.h> 16 #include <fs/vnode.h> 17 18 namespace blobfs { 19 20 using digest::Digest; 21 22 // Forward declared because CacheNode needs a mechanism for accessing the class 23 // when it runs out of strong references. 24 class BlobCache; 25 26 // An abstract blob-backed Vnode, which is managed by the BlobCache. 27 class CacheNode : public fs::Vnode, fbl::Recyclable<CacheNode> { 28 public: 29 // Intrusive methods and structures. 30 using WAVLTreeNodeState = fbl::WAVLTreeNodeState<CacheNode*>; 31 struct TypeWavlTraits { node_stateTypeWavlTraits32 static WAVLTreeNodeState& node_state(CacheNode& b) { return b.type_wavl_state_; } 33 }; 34 InContainer()35 bool InContainer() const { 36 return type_wavl_state_.InContainer(); 37 } 38 39 // TODO(ZX-3137): This constructor is only used for the "Directory" Vnode. 40 // Once distinct Vnodes are utilized for "blobs" and "the blob directory", 41 // this constructor should be deleted. 42 CacheNode(); 43 explicit CacheNode(const Digest& digest); 44 virtual ~CacheNode(); 45 46 // Invoked by fbl::RefPtr when all strong references to RefPtr<CacheNode> go out of scope. 47 // 48 // If a derived class wishes to participate in the Cache's lifetime management, 49 // they must implement the following: 50 // 51 // void fbl_recycle() final { 52 // CacheNode::fbl_recycle(); 53 // } 54 void fbl_recycle() override; 55 56 // Returns a reference to the BlobCache. 57 // 58 // The BlobCache must outlive all CacheNodes; this method is invoked from the recycler 59 // of a CacheNode. 60 // 61 // The implementation of this method must not invoke any other CacheNode methods. 62 // The implementation of this method must not attempt to acquire a reference to |this|. 63 virtual BlobCache& Cache() = 0; 64 65 // Identifies if the node should be recycled when it is terminated, 66 // keeping it cached (although possibly in a reduced state). 67 // 68 // This should be true as long as the blob exists on persistent storage, and 69 // would be visible again on reboot. 70 // 71 // The implementation of this method must not invoke any other CacheNode methods. 72 // The implementation of this method must not attempt to acquire a reference to |this|. 73 virtual bool ShouldCache() const = 0; 74 75 // Places the Vnode into a low-memory state. This function may be invoked when 76 // migrating the node from a "live cache" to a "closed cache". 77 // 78 // The implementation of this method must not invoke any other CacheNode methods. 79 // The implementation of this method must not attempt to acquire a reference to |this|. 80 virtual void ActivateLowMemory() = 0; 81 82 // Returns the node's digest. GetKey()83 const uint8_t* GetKey() const { 84 return &digest_[0]; 85 } 86 87 private: 88 friend struct TypeWavlTraits; 89 WAVLTreeNodeState type_wavl_state_ = {}; 90 uint8_t digest_[Digest::kLength] = {}; 91 }; 92 93 } // namespace blobfs 94