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
15 void
TransferFrom(Block & other)16 Block::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
30 bool
GetReadable(Volume * volume,uint64 blockIndex)31 Block::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
40 bool
GetWritable(Volume * volume,uint64 blockIndex,Transaction & transaction)41 Block::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
56 bool
GetZero(Volume * volume,uint64 blockIndex,Transaction & transaction)57 Block::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
72 status_t
MakeWritable(Transaction & transaction)73 Block::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
96 void
Put()97 Block::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
110 bool
_Init(Volume * volume,uint64 blockIndex,const void * data,Transaction * transaction)111 Block::_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