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