1// Volume.h
2//
3// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18//
19// You can alternatively use *this file* under the terms of the the MIT
20// license included in this package.
21
22#ifndef VOLUME_H
23#define VOLUME_H
24
25#include <fs_interface.h>
26#include <SupportDefs.h>
27
28#include <util/DoublyLinkedList.h>
29
30#include "Entry.h"
31#include "List.h"
32#include "Locker.h"
33#include "Query.h"
34#include "String.h"
35
36class AllocationInfo;
37class Block;
38class BlockAllocator;
39class BlockReference;
40class Directory;
41class DirectoryEntryTable;
42class Entry;
43class EntryListener;
44class EntryListenerTree;
45class Index;
46class IndexDirectory;
47class LastModifiedIndex;
48class NameIndex;
49class Node;
50class NodeAttributeTable;
51class NodeListener;
52class NodeListenerTree;
53class NodeTable;
54class SizeIndex;
55
56const ino_t kRootParentID = 0;
57
58// NodeListenerValue
59class NodeListenerValue {
60public:
61	inline NodeListenerValue() {}
62	inline NodeListenerValue(int) {}
63	inline NodeListenerValue(NodeListener *listener, Node *node, uint32 flags)
64		: listener(listener), node(node), flags(flags) {}
65
66	inline bool operator==(const NodeListenerValue &other)
67		{ return listener == other.listener; }
68
69	NodeListener	*listener;
70	Node			*node;
71	uint32			flags;
72};
73typedef List<NodeListenerValue> NodeListenerList;
74
75// EntryListenerValue
76class EntryListenerValue {
77public:
78	inline EntryListenerValue() {}
79	inline EntryListenerValue(int) {}
80	inline EntryListenerValue(EntryListener *listener, Entry *entry,
81							  uint32 flags)
82		: listener(listener), entry(entry), flags(flags) {}
83
84	inline bool operator==(const EntryListenerValue &other)
85		{ return listener == other.listener; }
86
87	EntryListener	*listener;
88	Entry			*entry;
89	uint32			flags;
90};
91typedef List<EntryListenerValue> EntryListenerList;
92
93// Volume
94class Volume {
95public:
96							Volume(fs_volume* volume);
97							~Volume();
98
99	status_t Mount(uint32 flags);
100	status_t Unmount();
101
102	dev_t GetID() const { return fID; }
103	fs_volume* FSVolume() const { return fVolume; }
104
105	off_t GetBlockSize() const;
106	off_t CountBlocks() const;
107	off_t CountFreeBlocks() const;
108
109	status_t SetName(const char *name);
110	const char *GetName() const;
111
112	Directory *GetRootDirectory() const		{ return fRootDirectory; }
113
114	status_t NewVNode(Node *node);
115	status_t PublishVNode(Node *node);
116	status_t GetVNode(ino_t id, Node **node);
117	status_t GetVNode(Node *node);
118	status_t PutVNode(ino_t id);
119	status_t PutVNode(Node *node);
120	status_t RemoveVNode(Node *node);
121	status_t UnremoveVNode(Node *node);
122
123	// node table and listeners
124	status_t NodeAdded(Node *node);
125	status_t NodeRemoved(Node *node);
126	status_t FindNode(ino_t id, Node **node);
127	status_t AddNodeListener(NodeListener *listener, Node *node,
128							 uint32 flags);
129	status_t RemoveNodeListener(NodeListener *listener, Node *node);
130
131	// entry table and listeners
132	status_t EntryAdded(ino_t id, Entry *entry);
133	status_t EntryRemoved(ino_t id, Entry *entry);
134	status_t FindEntry(ino_t id, const char *name, Entry **entry);
135	status_t AddEntryListener(EntryListener *listener, Entry *entry,
136							  uint32 flags);
137	status_t RemoveEntryListener(EntryListener *listener, Entry *entry);
138
139	// node attribute table
140	status_t NodeAttributeAdded(ino_t id, Attribute *attribute);
141	status_t NodeAttributeRemoved(ino_t id, Attribute *attribute);
142	status_t FindNodeAttribute(ino_t id, const char *name,
143							   Attribute **attribute);
144
145	// indices
146	IndexDirectory *GetIndexDirectory() const	{ return fIndexDirectory; }
147	NameIndex *GetNameIndex() const;
148	LastModifiedIndex *GetLastModifiedIndex() const;
149	SizeIndex *GetSizeIndex() const;
150	Index *FindIndex(const char *name);
151	AttributeIndex *FindAttributeIndex(const char *name, uint32 type);
152
153	// queries
154	void AddQuery(Query *query);
155	void RemoveQuery(Query *query);
156	void UpdateLiveQueries(Entry *entry, Node* node, const char *attribute,
157			int32 type, const uint8 *oldKey, size_t oldLength,
158			const uint8 *newKey, size_t newLength);
159
160	ino_t NextNodeID() { return fNextNodeID++; }
161
162	status_t AllocateBlock(size_t size, BlockReference **block);
163	void FreeBlock(BlockReference *block);
164	BlockReference *ResizeBlock(BlockReference *block, size_t size);
165	// debugging only
166	bool CheckBlock(BlockReference *block, size_t size = 0);
167	void GetAllocationInfo(AllocationInfo &info);
168
169	bigtime_t GetAccessTime() const	{ return fAccessTime; }
170
171	// locking
172	bool ReadLock();
173	void ReadUnlock();
174	bool WriteLock();
175	void WriteUnlock();
176
177	bool IteratorLock();
178	void IteratorUnlock();
179
180protected:
181	fs_volume*				fVolume;
182
183private:
184	typedef DoublyLinkedList<Query>	QueryList;
185
186	dev_t					fID;
187	ino_t					fNextNodeID;
188	NodeTable				*fNodeTable;
189	DirectoryEntryTable		*fDirectoryEntryTable;
190	NodeAttributeTable		*fNodeAttributeTable;
191	IndexDirectory			*fIndexDirectory;
192	Directory				*fRootDirectory;
193	String					fName;
194	Locker					fLocker;
195	Locker					fIteratorLocker;
196	Locker					fQueryLocker;
197	NodeListenerTree		*fNodeListeners;
198	NodeListenerList		fAnyNodeListeners;
199	EntryListenerTree		*fEntryListeners;
200	EntryListenerList		fAnyEntryListeners;
201	QueryList				fQueries;
202	BlockAllocator			*fBlockAllocator;
203	off_t					fBlockSize;
204	off_t					fAllocatedBlocks;
205	bigtime_t				fAccessTime;
206	bool					fMounted;
207};
208
209#endif	// VOLUME_H
210