xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h (revision 4bd0c1066b227cec4b79883bdef697c7a27f2e90)
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 #include <Referenceable.h>
13 
14 #include <lock.h>
15 #include <util/DoublyLinkedList.h>
16 #include <util/OpenHashTable.h>
17 
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 BReferenceable, public DoublyLinkedListLinkImpl<Node> {
38 public:
39 								Node(ino_t id);
40 	virtual						~Node();
41 
42 	inline	bool				ReadLock();
43 	inline	void				ReadUnlock();
44 	inline	bool				WriteLock();
45 	inline	void				WriteUnlock();
46 
47 			ino_t				ID() const		{ return fID; }
48 			Directory*			Parent() const	{ return fParent; }
49 			const String&		Name() const	{ return fName; }
50 
51 			Node*&				NameHashTableNext()
52 									{ return fNameHashTableNext; }
53 			Node*&				IDHashTableNext()
54 									{ return fIDHashTableNext; }
55 
56 	virtual	status_t			Init(Directory* parent, const String& name);
57 
58 	virtual	status_t			VFSInit(dev_t deviceID);
59 									// base class version must be called on
60 									// success
61 	virtual	void				VFSUninit();
62 									// base class version must be called
63 	inline	bool				IsKnownToVFS() const;
64 	inline	bool				HasVFSInitError() const;
65 
66 			void				SetID(ino_t id);
67 			void				SetParent(Directory* parent);
68 
69 	virtual	mode_t				Mode() const = 0;
70 	virtual	uid_t				UserID() const;
71 	virtual	gid_t				GroupID() const;
72 	virtual	timespec			ModifiedTime() const = 0;
73 	virtual	off_t				FileSize() const = 0;
74 
75 	virtual	status_t			Read(off_t offset, void* buffer,
76 									size_t* bufferSize) = 0;
77 	virtual	status_t			Read(io_request* request) = 0;
78 
79 	virtual	status_t			ReadSymlink(void* buffer,
80 									size_t* bufferSize) = 0;
81 
82 	virtual	status_t			OpenAttributeDirectory(
83 									AttributeDirectoryCookie*& _cookie);
84 	virtual	status_t			OpenAttribute(const StringKey& name,
85 									int openMode, AttributeCookie*& _cookie);
86 
87 	virtual	status_t			IndexAttribute(AttributeIndexer* indexer);
88 	virtual	void*				IndexCookieForAttribute(const StringKey& name)
89 									const;
90 
91 protected:
92 			rw_lock				fLock;
93 			ino_t				fID;
94 			Directory*			fParent;
95 			String				fName;
96 			Node*				fNameHashTableNext;
97 			Node*				fIDHashTableNext;
98 			uint32				fFlags;
99 };
100 
101 
102 bool
103 Node::ReadLock()
104 {
105 	return rw_lock_read_lock(&fLock) == B_OK;
106 }
107 
108 
109 void
110 Node::ReadUnlock()
111 {
112 	rw_lock_read_unlock(&fLock);
113 }
114 
115 
116 bool
117 Node::WriteLock()
118 {
119 	return rw_lock_write_lock(&fLock) == B_OK;
120 }
121 
122 
123 void
124 Node::WriteUnlock()
125 {
126 	rw_lock_write_unlock(&fLock);
127 }
128 
129 
130 bool
131 Node::IsKnownToVFS() const
132 {
133 	return (fFlags & NODE_FLAG_KNOWN_TO_VFS) != 0;
134 }
135 
136 
137 bool
138 Node::HasVFSInitError() const
139 {
140 	return (fFlags & NODE_FLAG_VFS_INIT_ERROR) != 0;
141 }
142 
143 
144 // #pragma mark -
145 
146 
147 struct NodeNameHashDefinition {
148 	typedef StringKey	KeyType;
149 	typedef	Node		ValueType;
150 
151 	size_t HashKey(const StringKey& key) const
152 	{
153 		return key.Hash();
154 	}
155 
156 	size_t Hash(const Node* value) const
157 	{
158 		return value->Name().Hash();
159 	}
160 
161 	bool Compare(const StringKey& key, const Node* value) const
162 	{
163 		return key == value->Name();
164 	}
165 
166 	Node*& GetLink(Node* value) const
167 	{
168 		return value->NameHashTableNext();
169 	}
170 };
171 
172 
173 struct NodeIDHashDefinition {
174 	typedef ino_t	KeyType;
175 	typedef	Node	ValueType;
176 
177 	size_t HashKey(ino_t key) const
178 	{
179 		return (uint64)(key >> 32) ^ (uint32)key;
180 	}
181 
182 	size_t Hash(const Node* value) const
183 	{
184 		return HashKey(value->ID());
185 	}
186 
187 	bool Compare(ino_t key, const Node* value) const
188 	{
189 		return value->ID() == key;
190 	}
191 
192 	Node*& GetLink(Node* value) const
193 	{
194 		return value->IDHashTableNext();
195 	}
196 };
197 
198 typedef DoublyLinkedList<Node> NodeList;
199 
200 typedef BOpenHashTable<NodeNameHashDefinition> NodeNameHashTable;
201 typedef BOpenHashTable<NodeIDHashDefinition> NodeIDHashTable;
202 
203 typedef AutoLocker<Node, AutoLockerReadLocking<Node> > NodeReadLocker;
204 typedef AutoLocker<Node, AutoLockerWriteLocking<Node> > NodeWriteLocker;
205 
206 
207 #endif	// NODE_H
208