xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
1 /*
2  * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef NODE_H
6 #define NODE_H
7 
8 
9 #include <fs_interface.h>
10 
11 #include <AutoLocker.h>
12 
13 #include <lock.h>
14 #include <util/DoublyLinkedList.h>
15 #include <util/OpenHashTable.h>
16 
17 #include "InlineReferenceable.h"
18 #include "String.h"
19 #include "StringKey.h"
20 
21 
22 class AttributeCookie;
23 class AttributeDirectoryCookie;
24 class AttributeIndexer;
25 class Directory;
26 class PackageNode;
27 
28 
29 // internal node flags
30 enum {
31 	NODE_FLAG_KNOWN_TO_VFS		= 0x01,
32 	NODE_FLAG_VFS_INIT_ERROR	= 0x02,
33 		// used by subclasses
34 };
35 
36 
37 class Node : public DoublyLinkedListLinkImpl<Node> {
38 public:
39 								Node(ino_t id);
40 	virtual						~Node();
41 
42 			void				AcquireReference();
43 			void				ReleaseReference();
44 			int32				CountReferences();
45 
46 	inline	bool				ReadLock();
47 	inline	void				ReadUnlock();
48 	inline	bool				WriteLock();
49 	inline	void				WriteUnlock();
50 
51 			ino_t				ID() const		{ return fID; }
52 			Directory*			Parent() const	{ return fParent; }
53 			const String&		Name() const	{ return fName; }
54 
55 			Node*&				NameHashTableNext()
56 									{ return fNameHashTableNext; }
57 			Node*&				IDHashTableNext()
58 									{ return fIDHashTableNext; }
59 
60 	virtual	status_t			Init(const String& name);
61 			void				SetID(ino_t id);
62 
63 	virtual	status_t			VFSInit(dev_t deviceID);
64 									// base class version must be called on
65 									// success
66 	virtual	void				VFSUninit();
67 									// base class version must be called
68 	inline	bool				IsKnownToVFS() const;
69 	inline	bool				HasVFSInitError() const;
70 
71 	virtual	mode_t				Mode() const = 0;
72 	virtual	uid_t				UserID() const;
73 	virtual	gid_t				GroupID() const;
74 	virtual	timespec			ModifiedTime() const = 0;
75 	virtual	off_t				FileSize() const = 0;
76 
77 	virtual	status_t			Read(off_t offset, void* buffer,
78 									size_t* bufferSize) = 0;
79 	virtual	status_t			Read(io_request* request) = 0;
80 
81 	virtual	status_t			ReadSymlink(void* buffer,
82 									size_t* bufferSize) = 0;
83 
84 	virtual	status_t			OpenAttributeDirectory(
85 									AttributeDirectoryCookie*& _cookie);
86 	virtual	status_t			OpenAttribute(const StringKey& name,
87 									int openMode, AttributeCookie*& _cookie);
88 
89 	virtual	status_t			IndexAttribute(AttributeIndexer* indexer);
90 	virtual	void*				IndexCookieForAttribute(const StringKey& name)
91 									const;
92 
93 private:
94 			friend class Directory;
95 
96 			void				_SetParent(Directory* parent);
97 
98 protected:
99 			rw_lock				fLock;
100 			ino_t				fID;
101 			Directory*			fParent;
102 			String				fName;
103 			Node*				fNameHashTableNext;
104 			Node*				fIDHashTableNext;
105 			uint32				fFlags;
106 			InlineReferenceable	fReferenceable;
107 };
108 
109 
110 bool
111 Node::ReadLock()
112 {
113 	return rw_lock_read_lock(&fLock) == B_OK;
114 }
115 
116 
117 void
118 Node::ReadUnlock()
119 {
120 	rw_lock_read_unlock(&fLock);
121 }
122 
123 
124 bool
125 Node::WriteLock()
126 {
127 	return rw_lock_write_lock(&fLock) == B_OK;
128 }
129 
130 
131 void
132 Node::WriteUnlock()
133 {
134 	rw_lock_write_unlock(&fLock);
135 }
136 
137 
138 bool
139 Node::IsKnownToVFS() const
140 {
141 	return (fFlags & NODE_FLAG_KNOWN_TO_VFS) != 0;
142 }
143 
144 
145 bool
146 Node::HasVFSInitError() const
147 {
148 	return (fFlags & NODE_FLAG_VFS_INIT_ERROR) != 0;
149 }
150 
151 
152 // #pragma mark -
153 
154 
155 struct NodeNameHashDefinition {
156 	typedef StringKey	KeyType;
157 	typedef	Node		ValueType;
158 
159 	size_t HashKey(const StringKey& key) const
160 	{
161 		return key.Hash();
162 	}
163 
164 	size_t Hash(const Node* value) const
165 	{
166 		return value->Name().Hash();
167 	}
168 
169 	bool Compare(const StringKey& key, const Node* value) const
170 	{
171 		return key == value->Name();
172 	}
173 
174 	Node*& GetLink(Node* value) const
175 	{
176 		return value->NameHashTableNext();
177 	}
178 };
179 
180 
181 struct NodeIDHashDefinition {
182 	typedef ino_t	KeyType;
183 	typedef	Node	ValueType;
184 
185 	size_t HashKey(ino_t key) const
186 	{
187 		return (uint64)(key >> 32) ^ (uint32)key;
188 	}
189 
190 	size_t Hash(const Node* value) const
191 	{
192 		return HashKey(value->ID());
193 	}
194 
195 	bool Compare(ino_t key, const Node* value) const
196 	{
197 		return value->ID() == key;
198 	}
199 
200 	Node*& GetLink(Node* value) const
201 	{
202 		return value->IDHashTableNext();
203 	}
204 };
205 
206 typedef DoublyLinkedList<Node> NodeList;
207 
208 typedef BOpenHashTable<NodeNameHashDefinition> NodeNameHashTable;
209 typedef BOpenHashTable<NodeIDHashDefinition> NodeIDHashTable;
210 
211 typedef AutoLocker<Node, AutoLockerReadLocking<Node> > NodeReadLocker;
212 typedef AutoLocker<Node, AutoLockerWriteLocking<Node> > NodeWriteLocker;
213 
214 
215 #endif	// NODE_H
216