vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / file_systems / bfs / Volume.h
blob91f2d5728d9adfe006a9fde3ec2cc2356de8fbfd
1 /*
2 * Copyright 2001-2012, Axel Dörfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
4 */
5 #ifndef VOLUME_H
6 #define VOLUME_H
9 #include "system_dependencies.h"
11 #include "bfs.h"
12 #include "BlockAllocator.h"
15 class Journal;
16 class Inode;
17 class Query;
20 enum volume_flags {
21 VOLUME_READ_ONLY = 0x0001
24 enum volume_initialize_flags {
25 VOLUME_NO_INDICES = 0x0001,
28 typedef DoublyLinkedList<Inode> InodeList;
31 class Volume {
32 public:
33 Volume(fs_volume* volume);
34 ~Volume();
36 status_t Mount(const char* device, uint32 flags);
37 status_t Unmount();
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;
46 void Panic();
47 mutex& Lock();
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
101 // block bitmap
102 BlockAllocator& Allocator();
103 status_t AllocateForInode(Transaction& transaction,
104 const Inode* parent, mode_t type,
105 block_run& run);
106 status_t AllocateForInode(Transaction& transaction,
107 const block_run* parent, mode_t type,
108 block_run& run);
109 status_t Allocate(Transaction& transaction, Inode* inode,
110 off_t numBlocks, block_run& run,
111 uint16 minimum = 1);
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; }
118 // cache access
119 status_t WriteSuperBlock();
120 status_t FlushDevice();
122 // queries
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);
135 status_t Sync();
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);
144 private:
145 status_t _EraseUnusedBootBlock();
147 protected:
148 fs_volume* fVolume;
149 int fDevice;
150 disk_super_block fSuperBlock;
152 uint32 fDeviceBlockSize;
153 uint32 fBlockSize;
154 uint32 fBlockShift;
155 uint32 fAllocationGroupShift;
157 BlockAllocator fBlockAllocator;
158 mutex fLock;
159 Journal* fJournal;
160 vint32 fLogStart;
161 vint32 fLogEnd;
163 Inode* fRootNode;
164 Inode* fIndicesNode;
166 vint32 fDirtyCachedBlocks;
168 mutex fQueryLock;
169 SinglyLinkedList<Query> fQueries;
171 uint32 fFlags;
173 void* fBlockCache;
174 thread_id fCheckingThread;
176 InodeList fRemovedInodes;
180 // inline functions
182 inline bool
183 Volume::IsReadOnly() const
185 return fFlags & VOLUME_READ_ONLY;
189 inline mutex&
190 Volume::Lock()
192 return fLock;
196 inline BlockAllocator&
197 Volume::Allocator()
199 return fBlockAllocator;
203 inline status_t
204 Volume::AllocateForInode(Transaction& transaction, const block_run* parent,
205 mode_t type, block_run& run)
207 return fBlockAllocator.AllocateForInode(transaction, parent, type, run);
211 inline status_t
212 Volume::Allocate(Transaction& transaction, Inode* inode, off_t numBlocks,
213 block_run& run, uint16 minimum)
215 return fBlockAllocator.Allocate(transaction, inode, numBlocks, run,
216 minimum);
220 inline status_t
221 Volume::Free(Transaction& transaction, block_run run)
223 return fBlockAllocator.Free(transaction, run);
227 inline status_t
228 Volume::FlushDevice()
230 return block_cache_sync(fBlockCache);
234 inline Journal*
235 Volume::GetJournal(off_t /*refBlock*/) const
237 return fJournal;
241 #endif // VOLUME_H