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