1 /* 2 * Copyright 2001-2020, Axel Dörfler, axeld@pinc-software.de. 3 * This file may be used under the terms of the MIT License. 4 */ 5 #ifndef CACHED_BLOCK_H 6 #define CACHED_BLOCK_H 7 8 9 //! Interface for the block cache 10 11 12 #include "system_dependencies.h" 13 14 #include "Volume.h" 15 #include "Journal.h" 16 #include "Debug.h" 17 18 19 // The CachedBlock class is completely implemented as inlines. 20 // It should be used when cache single blocks to make sure they 21 // will be properly released after use (and it's also very 22 // convenient to use them). 23 24 class CachedBlock { 25 public: 26 CachedBlock(Volume* volume); 27 CachedBlock(CachedBlock* cached); 28 ~CachedBlock(); 29 30 inline void Keep(); 31 inline void Unset(); 32 33 inline status_t SetTo(off_t block, off_t base, size_t length); 34 inline status_t SetTo(off_t block); 35 inline status_t SetTo(block_run run); 36 inline status_t SetToWritable(Transaction& transaction, 37 off_t block, off_t base, size_t length, 38 bool empty = false); 39 inline status_t SetToWritable(Transaction& transaction, 40 off_t block, bool empty = false); 41 inline status_t SetToWritable(Transaction& transaction, 42 block_run run, bool empty = false); 43 inline status_t MakeWritable(Transaction& transaction); 44 45 const uint8* Block() const { return fBlock; } 46 uint8* WritableBlock() const { return fBlock; } 47 off_t BlockNumber() const { return fBlockNumber; } 48 uint32 BlockSize() const 49 { return fVolume->BlockSize(); } 50 uint32 BlockShift() const 51 { return fVolume->BlockShift(); } 52 53 private: 54 CachedBlock(const CachedBlock& other); 55 CachedBlock& operator=(const CachedBlock& other); 56 // no implementation 57 58 protected: 59 Volume* fVolume; 60 off_t fBlockNumber; 61 uint8* fBlock; 62 }; 63 64 65 // inlines 66 67 68 inline 69 CachedBlock::CachedBlock(Volume* volume) 70 : 71 fVolume(volume), 72 fBlockNumber(0), 73 fBlock(NULL) 74 { 75 } 76 77 78 inline 79 CachedBlock::CachedBlock(CachedBlock* cached) 80 : 81 fVolume(cached->fVolume), 82 fBlockNumber(cached->BlockNumber()), 83 fBlock(cached->fBlock) 84 { 85 cached->Keep(); 86 } 87 88 89 inline 90 CachedBlock::~CachedBlock() 91 { 92 Unset(); 93 } 94 95 96 inline void 97 CachedBlock::Keep() 98 { 99 fBlock = NULL; 100 } 101 102 103 inline void 104 CachedBlock::Unset() 105 { 106 if (fBlock != NULL) { 107 block_cache_put(fVolume->BlockCache(), fBlockNumber); 108 fBlock = NULL; 109 } 110 } 111 112 113 inline status_t 114 CachedBlock::SetTo(off_t block, off_t base, size_t length) 115 { 116 Unset(); 117 fBlockNumber = block; 118 return block_cache_get_etc(fVolume->BlockCache(), block, base, length, 119 (const void**)&fBlock); 120 } 121 122 123 inline status_t 124 CachedBlock::SetTo(off_t block) 125 { 126 return SetTo(block, block, 1); 127 } 128 129 130 inline status_t 131 CachedBlock::SetTo(block_run run) 132 { 133 return SetTo(fVolume->ToBlock(run)); 134 } 135 136 137 inline status_t 138 CachedBlock::SetToWritable(Transaction& transaction, off_t block, off_t base, 139 size_t length, bool empty) 140 { 141 Unset(); 142 fBlockNumber = block; 143 144 if (empty) { 145 fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(), 146 block, transaction.ID()); 147 return fBlock != NULL ? B_OK : B_NO_MEMORY; 148 } 149 150 return block_cache_get_writable_etc(fVolume->BlockCache(), 151 block, base, length, transaction.ID(), (void**)&fBlock); 152 } 153 154 155 inline status_t 156 CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty) 157 { 158 return SetToWritable(transaction, block, block, 1, empty); 159 } 160 161 162 inline status_t 163 CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty) 164 { 165 return SetToWritable(transaction, fVolume->ToBlock(run), empty); 166 } 167 168 169 inline status_t 170 CachedBlock::MakeWritable(Transaction& transaction) 171 { 172 if (fBlock == NULL) 173 return B_NO_INIT; 174 175 return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber, 176 transaction.ID()); 177 } 178 179 180 #endif // CACHED_BLOCK_H 181