2 * Copyright 2001-2012, Axel Dörfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
9 #include "system_dependencies.h"
12 #include "BlockAllocator.h"
21 VOLUME_READ_ONLY
= 0x0001
24 enum volume_initialize_flags
{
25 VOLUME_NO_INDICES
= 0x0001,
28 typedef DoublyLinkedList
<Inode
> InodeList
;
33 Volume(fs_volume
* volume
);
36 status_t
Mount(const char* device
, uint32 flags
);
38 status_t
Initialize(int fd
, const char* name
,
39 uint32 blockSize
, uint32 flags
);
41 bool IsInitializing() const { return fVolume
== NULL
; }
43 bool IsValidSuperBlock() const;
44 bool IsValidInodeBlock(off_t block
) const;
45 bool IsReadOnly() const;
49 block_run
Root() const { return fSuperBlock
.root_dir
; }
50 Inode
* RootNode() const { return fRootNode
; }
51 block_run
Indices() const { return fSuperBlock
.indices
; }
52 Inode
* IndicesNode() const { return fIndicesNode
; }
53 block_run
Log() const { return fSuperBlock
.log_blocks
; }
54 vint32
& LogStart() { return fLogStart
; }
55 vint32
& LogEnd() { return fLogEnd
; }
56 int Device() const { return fDevice
; }
58 dev_t
ID() const { return fVolume
? fVolume
->id
: -1; }
59 fs_volume
* FSVolume() const { return fVolume
; }
60 const char* Name() const { return fSuperBlock
.name
; }
62 off_t
NumBlocks() const
63 { return fSuperBlock
.NumBlocks(); }
64 off_t
UsedBlocks() const
65 { return fSuperBlock
.UsedBlocks(); }
66 off_t
FreeBlocks() const
67 { return NumBlocks() - UsedBlocks(); }
69 uint32
DeviceBlockSize() const { return fDeviceBlockSize
; }
70 uint32
BlockSize() const { return fBlockSize
; }
71 uint32
BlockShift() const { return fBlockShift
; }
72 uint32
InodeSize() const
73 { return fSuperBlock
.InodeSize(); }
74 uint32
AllocationGroups() const
75 { return fSuperBlock
.AllocationGroups(); }
76 uint32
AllocationGroupShift() const
77 { return fAllocationGroupShift
; }
78 disk_super_block
& SuperBlock() { return fSuperBlock
; }
80 off_t
ToOffset(block_run run
) const
81 { return ToBlock(run
) << BlockShift(); }
82 off_t
ToBlock(block_run run
) const
83 { return ((((off_t
)run
.AllocationGroup())
84 << AllocationGroupShift())
85 | (off_t
)run
.Start()); }
86 block_run
ToBlockRun(off_t block
) const;
87 status_t
ValidateBlockRun(block_run run
);
89 off_t
ToVnode(block_run run
) const
90 { return ToBlock(run
); }
91 off_t
ToVnode(off_t block
) const { return block
; }
92 off_t
VnodeToBlock(ino_t id
) const { return (off_t
)id
; }
94 status_t
CreateIndicesRoot(Transaction
& transaction
);
96 status_t
CreateVolumeID(Transaction
& transaction
);
98 InodeList
& RemovedInodes() { return fRemovedInodes
; }
99 // This list is guarded by the transaction lock
102 BlockAllocator
& Allocator();
103 status_t
AllocateForInode(Transaction
& transaction
,
104 const Inode
* parent
, mode_t type
,
106 status_t
AllocateForInode(Transaction
& transaction
,
107 const block_run
* parent
, mode_t type
,
109 status_t
Allocate(Transaction
& transaction
, Inode
* inode
,
110 off_t numBlocks
, block_run
& run
,
112 status_t
Free(Transaction
& transaction
, block_run run
);
113 void SetCheckingThread(thread_id thread
)
114 { fCheckingThread
= thread
; }
115 bool IsCheckingThread() const
116 { return find_thread(NULL
) == fCheckingThread
; }
119 status_t
WriteSuperBlock();
120 status_t
FlushDevice();
123 void UpdateLiveQueries(Inode
* inode
,
124 const char* attribute
, int32 type
,
125 const uint8
* oldKey
, size_t oldLength
,
126 const uint8
* newKey
, size_t newLength
);
127 void UpdateLiveQueriesRenameMove(Inode
* inode
,
128 ino_t oldDirectoryID
, const char* oldName
,
129 ino_t newDirectoryID
, const char* newName
);
131 bool CheckForLiveQuery(const char* attribute
);
132 void AddQuery(Query
* query
);
133 void RemoveQuery(Query
* query
);
136 Journal
* GetJournal(off_t refBlock
) const;
138 void* BlockCache() { return fBlockCache
; }
140 static status_t
CheckSuperBlock(const uint8
* data
,
141 uint32
* _offset
= NULL
);
142 static status_t
Identify(int fd
, disk_super_block
* superBlock
);
145 status_t
_EraseUnusedBootBlock();
150 disk_super_block fSuperBlock
;
152 uint32 fDeviceBlockSize
;
155 uint32 fAllocationGroupShift
;
157 BlockAllocator fBlockAllocator
;
166 vint32 fDirtyCachedBlocks
;
169 SinglyLinkedList
<Query
> fQueries
;
174 thread_id fCheckingThread
;
176 InodeList fRemovedInodes
;
183 Volume::IsReadOnly() const
185 return fFlags
& VOLUME_READ_ONLY
;
196 inline BlockAllocator
&
199 return fBlockAllocator
;
204 Volume::AllocateForInode(Transaction
& transaction
, const block_run
* parent
,
205 mode_t type
, block_run
& run
)
207 return fBlockAllocator
.AllocateForInode(transaction
, parent
, type
, run
);
212 Volume::Allocate(Transaction
& transaction
, Inode
* inode
, off_t numBlocks
,
213 block_run
& run
, uint16 minimum
)
215 return fBlockAllocator
.Allocate(transaction
, inode
, numBlocks
, run
,
221 Volume::Free(Transaction
& transaction
, block_run run
)
223 return fBlockAllocator
.Free(transaction
, run
);
228 Volume::FlushDevice()
230 return block_cache_sync(fBlockCache
);
235 Volume::GetJournal(off_t
/*refBlock*/) const