1/* 2 * Copyright 2001-2008, 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//! interface for the block cache 9 10#include <fs_cache.h> 11 12#include "Transaction.h" 13#include "Volume.h" 14 15 16class CachedBlock { 17public: 18 CachedBlock(Volume* volume); 19 CachedBlock(Volume* volume, off_t block); 20 ~CachedBlock(); 21 22 void Keep(); 23 void Unset(); 24 25 const uint8* SetTo(off_t block); 26 uint8* SetToWritable(Transaction& transaction, 27 off_t block, bool empty = false); 28 uint8* SetToWritableWithoutTransaction(off_t block, 29 bool empty = false); 30 31 const uint8* Block() const { return fBlock; } 32 off_t BlockNumber() const { return fBlockNumber; } 33 34private: 35 CachedBlock(const CachedBlock &); 36 CachedBlock &operator=(const CachedBlock &); 37 // no implementation 38 39 uint8* _SetToWritableEtc(int32 transaction, off_t block, 40 bool empty); 41 42protected: 43 Volume* fVolume; 44 off_t fBlockNumber; 45 uint8* fBlock; 46}; 47 48 49// inlines 50 51 52inline 53CachedBlock::CachedBlock(Volume* volume) 54 : 55 fVolume(volume), 56 fBlockNumber(0), 57 fBlock(NULL) 58{ 59} 60 61 62inline 63CachedBlock::CachedBlock(Volume* volume, off_t block) 64 : 65 fVolume(volume), 66 fBlockNumber(0), 67 fBlock(NULL) 68{ 69 SetTo(block); 70} 71 72 73inline 74CachedBlock::~CachedBlock() 75{ 76 Unset(); 77} 78 79 80inline void 81CachedBlock::Keep() 82{ 83 fBlock = NULL; 84} 85 86 87inline void 88CachedBlock::Unset() 89{ 90 if (fBlock != NULL) { 91 block_cache_put(fVolume->BlockCache(), fBlockNumber); 92 fBlock = NULL; 93 } 94} 95 96 97inline const uint8 * 98CachedBlock::SetTo(off_t block) 99{ 100 Unset(); 101 fBlockNumber = block; 102 return fBlock = (uint8 *)block_cache_get(fVolume->BlockCache(), block); 103} 104 105 106inline uint8* 107CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty) 108{ 109 return _SetToWritableEtc(transaction.ID(), block, empty); 110} 111 112 113inline uint8* 114CachedBlock::SetToWritableWithoutTransaction(off_t block, bool empty) 115{ 116 return _SetToWritableEtc((int32)-1, block, empty); 117} 118 119inline uint8* 120CachedBlock::_SetToWritableEtc(int32 transaction, off_t block, bool empty) 121{ 122 Unset(); 123 fBlockNumber = block; 124 125 if (empty) { 126 fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(), 127 block, transaction); 128 } else { 129 fBlock = (uint8*)block_cache_get_writable(fVolume->BlockCache(), 130 block, transaction); 131 } 132 133 return fBlock; 134} 135 136#endif // CACHED_BLOCK_H 137