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 24class CachedBlock { 25public: 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 53private: 54 CachedBlock(const CachedBlock& other); 55 CachedBlock& operator=(const CachedBlock& other); 56 // no implementation 57 58protected: 59 Volume* fVolume; 60 off_t fBlockNumber; 61 uint8* fBlock; 62}; 63 64 65// inlines 66 67 68inline 69CachedBlock::CachedBlock(Volume* volume) 70 : 71 fVolume(volume), 72 fBlockNumber(0), 73 fBlock(NULL) 74{ 75} 76 77 78inline 79CachedBlock::CachedBlock(CachedBlock* cached) 80 : 81 fVolume(cached->fVolume), 82 fBlockNumber(cached->BlockNumber()), 83 fBlock(cached->fBlock) 84{ 85 cached->Keep(); 86} 87 88 89inline 90CachedBlock::~CachedBlock() 91{ 92 Unset(); 93} 94 95 96inline void 97CachedBlock::Keep() 98{ 99 fBlock = NULL; 100} 101 102 103inline void 104CachedBlock::Unset() 105{ 106 if (fBlock != NULL) { 107 block_cache_put(fVolume->BlockCache(), fBlockNumber); 108 fBlock = NULL; 109 } 110} 111 112 113inline status_t 114CachedBlock::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 123inline status_t 124CachedBlock::SetTo(off_t block) 125{ 126 return SetTo(block, block, 1); 127} 128 129 130inline status_t 131CachedBlock::SetTo(block_run run) 132{ 133 return SetTo(fVolume->ToBlock(run)); 134} 135 136 137inline status_t 138CachedBlock::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 155inline status_t 156CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty) 157{ 158 return SetToWritable(transaction, block, block, 1, empty); 159} 160 161 162inline status_t 163CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty) 164{ 165 return SetToWritable(transaction, fVolume->ToBlock(run), empty); 166} 167 168 169inline status_t 170CachedBlock::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