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#include <lock.h>
28
29#include <util/DoublyLinkedList.h>
30
31#include "Entry.h"
32#include "List.h"
33#include "Query.h"
34#include "String.h"
35
36class AllocationInfo;
37class Attribute;
38class AttributeIndex;
39class Directory;
40class DirectoryEntryTable;
41class Entry;
42class EntryListener;
43class EntryListenerTree;
44class Index;
45class IndexDirectory;
46class LastModifiedIndex;
47class NameIndex;
48class Node;
49class NodeListener;
50class NodeListenerTree;
51class NodeTable;
52class SizeIndex;
53
54const ino_t kRootParentID = 0;
55
56// NodeListenerValue
57class NodeListenerValue {
58public:
59	inline NodeListenerValue() {}
60	inline NodeListenerValue(int) {}
61	inline NodeListenerValue(NodeListener *listener, Node *node, uint32 flags)
62		: listener(listener), node(node), flags(flags) {}
63
64	inline bool operator==(const NodeListenerValue &other)
65		{ return listener == other.listener; }
66
67	NodeListener	*listener;
68	Node			*node;
69	uint32			flags;
70};
71typedef List<NodeListenerValue> NodeListenerList;
72
73// EntryListenerValue
74class EntryListenerValue {
75public:
76	inline EntryListenerValue() {}
77	inline EntryListenerValue(int) {}
78	inline EntryListenerValue(EntryListener *listener, Entry *entry,
79							  uint32 flags)
80		: listener(listener), entry(entry), flags(flags) {}
81
82	inline bool operator==(const EntryListenerValue &other)
83		{ return listener == other.listener; }
84
85	EntryListener	*listener;
86	Entry			*entry;
87	uint32			flags;
88};
89typedef List<EntryListenerValue> EntryListenerList;
90
91// Volume
92class Volume {
93public:
94							Volume(fs_volume* volume);
95							~Volume();
96
97	status_t Mount(uint32 flags);
98	status_t Unmount();
99
100	dev_t GetID() const { return fVolume != NULL ? fVolume->id : -1; }
101	fs_volume* FSVolume() const { return fVolume; }
102
103	off_t CountBlocks() const;
104	off_t CountFreeBlocks() const;
105
106	status_t SetName(const char *name);
107	const char *GetName() const;
108
109	Directory *GetRootDirectory() const		{ return fRootDirectory; }
110
111	status_t NewVNode(Node *node);
112	status_t PublishVNode(Node *node);
113	status_t GetVNode(ino_t id, Node **node);
114	status_t GetVNode(Node *node);
115	status_t PutVNode(ino_t id);
116	status_t PutVNode(Node *node);
117	status_t RemoveVNode(Node *node);
118	status_t UnremoveVNode(Node *node);
119
120	// node table and listeners
121	status_t NodeAdded(Node *node);
122	status_t NodeRemoved(Node *node);
123	status_t FindNode(ino_t id, Node **node);
124	status_t AddNodeListener(NodeListener *listener, Node *node,
125							 uint32 flags);
126	status_t RemoveNodeListener(NodeListener *listener, Node *node);
127
128	// entry table and listeners
129	status_t EntryAdded(ino_t id, Entry *entry);
130	status_t EntryRemoved(ino_t id, Entry *entry);
131	status_t FindEntry(ino_t id, const char *name, Entry **entry);
132	status_t AddEntryListener(EntryListener *listener, Entry *entry,
133							  uint32 flags);
134	status_t RemoveEntryListener(EntryListener *listener, Entry *entry);
135
136	// node attributes
137	status_t NodeAttributeAdded(ino_t id, Attribute *attribute);
138	status_t NodeAttributeRemoved(ino_t id, Attribute *attribute);
139
140	// indices
141	IndexDirectory *GetIndexDirectory() const	{ return fIndexDirectory; }
142	NameIndex *GetNameIndex() const;
143	LastModifiedIndex *GetLastModifiedIndex() const;
144	SizeIndex *GetSizeIndex() const;
145	Index *FindIndex(const char *name);
146	AttributeIndex *FindAttributeIndex(const char *name, uint32 type);
147
148	// queries
149	void AddQuery(Query *query);
150	void RemoveQuery(Query *query);
151	void UpdateLiveQueries(Entry *entry, Node* node, const char *attribute,
152			int32 type, const uint8 *oldKey, size_t oldLength,
153			const uint8 *newKey, size_t newLength);
154
155	ino_t NextNodeID() { return fNextNodeID++; }
156
157	void GetAllocationInfo(AllocationInfo &info);
158
159	bigtime_t GetAccessTime() const	{ return fAccessTime; }
160
161	// locking
162	bool ReadLock();
163	void ReadUnlock();
164	bool WriteLock();
165	void WriteUnlock();
166
167	bool IteratorLock();
168	void IteratorUnlock();
169
170protected:
171	fs_volume*				fVolume;
172
173private:
174	typedef DoublyLinkedList<Query>	QueryList;
175
176	ino_t					fNextNodeID;
177	NodeTable				*fNodeTable;
178	DirectoryEntryTable		*fDirectoryEntryTable;
179	IndexDirectory			*fIndexDirectory;
180	Directory				*fRootDirectory;
181	String					fName;
182	rw_lock					fLocker;
183	recursive_lock			fIteratorLocker;
184	recursive_lock			fQueryLocker;
185	NodeListenerTree		*fNodeListeners;
186	NodeListenerList		fAnyNodeListeners;
187	EntryListenerTree		*fEntryListeners;
188	EntryListenerList		fAnyEntryListeners;
189	QueryList				fQueries;
190	bigtime_t				fAccessTime;
191	bool					fMounted;
192};
193
194#endif	// VOLUME_H
195