1/* 2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "Block.h" 8 9#include <fs_cache.h> 10 11#include "Transaction.h" 12#include "Volume.h" 13 14 15void 16Block::TransferFrom(Block& other) 17{ 18 Put(); 19 20 fVolume = other.fVolume; 21 fData = other.fData; 22 fIndex = other.fIndex; 23 fTransaction = other.fTransaction; 24 25 other.fVolume = NULL; 26 other.fData = NULL; 27} 28 29 30bool 31Block::GetReadable(Volume* volume, uint64 blockIndex) 32{ 33 Put(); 34 35 return _Init(volume, blockIndex, 36 block_cache_get(volume->BlockCache(), blockIndex), NULL); 37} 38 39 40bool 41Block::GetWritable(Volume* volume, uint64 blockIndex, Transaction& transaction) 42{ 43 Put(); 44 45 status_t error = transaction.RegisterBlock(blockIndex); 46 if (error != B_OK) 47 return false; 48 49 return _Init(volume, blockIndex, 50 block_cache_get_writable(volume->BlockCache(), blockIndex, 51 transaction.ID()), 52 &transaction); 53} 54 55 56bool 57Block::GetZero(Volume* volume, uint64 blockIndex, Transaction& transaction) 58{ 59 Put(); 60 61 status_t error = transaction.RegisterBlock(blockIndex); 62 if (error != B_OK) 63 return false; 64 65 return _Init(volume, blockIndex, 66 block_cache_get_empty(volume->BlockCache(), blockIndex, 67 transaction.ID()), 68 &transaction); 69} 70 71 72status_t 73Block::MakeWritable(Transaction& transaction) 74{ 75 if (fVolume == NULL) 76 return B_BAD_VALUE; 77 if (fTransaction != NULL) 78 return B_OK; 79 80 status_t error = transaction.RegisterBlock(fIndex); 81 if (error != B_OK) 82 return error; 83 84 error = block_cache_make_writable(fVolume->BlockCache(), fIndex, 85 transaction.ID()); 86 if (error != B_OK) { 87 transaction.PutBlock(fIndex, NULL); 88 return error; 89 } 90 91 fTransaction = &transaction; 92 return B_OK; 93} 94 95 96void 97Block::Put() 98{ 99 if (fVolume != NULL) { 100 if (fTransaction != NULL) 101 fTransaction->PutBlock(fIndex, fData); 102 103 block_cache_put(fVolume->BlockCache(), fIndex); 104 fVolume = NULL; 105 fData = NULL; 106 } 107} 108 109 110bool 111Block::_Init(Volume* volume, uint64 blockIndex, const void* data, 112 Transaction* transaction) 113{ 114 if (data == NULL) 115 return false; 116 117 fVolume = volume; 118 fData = const_cast<void*>(data); 119 fIndex = blockIndex; 120 fTransaction = transaction; 121 122 return true; 123} 124