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