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 fBlock(NULL) 76 { 77 } 78 79 80 inline 81 CachedBlock::CachedBlock(Volume *volume, off_t block) 82 : 83 fVolume(volume), 84 fBlock(NULL) 85 { 86 SetTo(block); 87 } 88 89 90 inline 91 CachedBlock::CachedBlock(Volume *volume, block_run run) 92 : 93 fVolume(volume), 94 fBlock(NULL) 95 { 96 SetTo(volume->ToBlock(run)); 97 } 98 99 100 inline 101 CachedBlock::CachedBlock(CachedBlock *cached) 102 : 103 fVolume(cached->fVolume), 104 fBlockNumber(cached->BlockNumber()), 105 fBlock(cached->fBlock) 106 { 107 cached->Keep(); 108 } 109 110 111 inline 112 CachedBlock::~CachedBlock() 113 { 114 Unset(); 115 } 116 117 118 inline void 119 CachedBlock::Keep() 120 { 121 fBlock = NULL; 122 } 123 124 125 inline void 126 CachedBlock::Unset() 127 { 128 if (fBlock != NULL) 129 block_cache_put(fVolume->BlockCache(), fBlockNumber); 130 } 131 132 133 inline const uint8 * 134 CachedBlock::SetTo(off_t block, off_t base, size_t length) 135 { 136 Unset(); 137 fBlockNumber = block; 138 return fBlock = (uint8 *)block_cache_get_etc(fVolume->BlockCache(), block, base, length); 139 } 140 141 142 inline const uint8 * 143 CachedBlock::SetTo(off_t block) 144 { 145 return SetTo(block, block, 1); 146 } 147 148 149 inline const uint8 * 150 CachedBlock::SetTo(block_run run) 151 { 152 return SetTo(fVolume->ToBlock(run)); 153 } 154 155 156 inline uint8 * 157 CachedBlock::SetToWritable(Transaction &transaction, off_t block, off_t base, size_t length, bool empty) 158 { 159 Unset(); 160 fBlockNumber = block; 161 162 if (empty) 163 return fBlock = (uint8 *)block_cache_get_empty(fVolume->BlockCache(), block, transaction.ID()); 164 165 return fBlock = (uint8 *)block_cache_get_writable_etc(fVolume->BlockCache(), 166 block, base, length, transaction.ID()); 167 } 168 169 170 inline uint8 * 171 CachedBlock::SetToWritable(Transaction &transaction, off_t block, bool empty) 172 { 173 return SetToWritable(transaction, block, block, 1, empty); 174 } 175 176 177 inline uint8 * 178 CachedBlock::SetToWritable(Transaction &transaction, block_run run, bool empty) 179 { 180 return SetToWritable(transaction, fVolume->ToBlock(run), empty); 181 } 182 183 184 inline status_t 185 CachedBlock::MakeWritable(Transaction &transaction) 186 { 187 if (fBlock == NULL) 188 return B_NO_INIT; 189 190 return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber, transaction.ID()); 191 } 192 193 194 #endif /* CACHED_BLOCK_H */ 195