xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEEntry.h (revision 4720c31bb08f5c6d1c8ddb616463c6fba9b350a1)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef USERLAND_FS_FUSE_ENTRY_H
6 #define USERLAND_FS_FUSE_ENTRY_H
7 
8 #include <new>
9 
10 #include <RWLockManager.h>
11 
12 #include <util/DoublyLinkedList.h>
13 #include <util/OpenHashTable.h>
14 
15 #include "String.h"
16 
17 #include "fuse_api.h"
18 
19 
20 namespace UserlandFS {
21 
22 struct FUSENode;
23 
24 
25 struct FUSEEntryRef {
26 	ino_t		parentID;
27 	const char*	name;
28 
29 	FUSEEntryRef(ino_t parentID, const char* name)
30 		:
31 		parentID(parentID),
32 		name(name)
33 	{
34 	}
35 };
36 
37 
38 struct FUSEEntry : public HashTableLink<FUSEEntry>,
39 		DoublyLinkedListLinkImpl<FUSEEntry> {
40 	FUSENode*	parent;
41 	char*		name;
42 	FUSENode*	node;
43 
44 	FUSEEntry()
45 		:
46 		name(NULL)
47 	{
48 	}
49 
50 	~FUSEEntry()
51 	{
52 		free(name);
53 	}
54 
55 
56 	static FUSEEntry* Create(FUSENode* parent, const char* name, FUSENode* node)
57 	{
58 		FUSEEntry* entry = new(std::nothrow) FUSEEntry;
59 		if (entry == NULL)
60 			return NULL;
61 
62 		char* clonedName = strdup(name);
63 		if (clonedName == NULL) {
64 			delete entry;
65 			return NULL;
66 		}
67 
68 		entry->parent = parent;
69 		entry->name = clonedName;
70 		entry->node = node;
71 
72 		return entry;
73 	}
74 };
75 
76 
77 typedef DoublyLinkedList<FUSEEntry> FUSEEntryList;
78 
79 
80 struct FUSENode : RWLockable, HashTableLink<FUSENode> {
81 	ino_t			id;
82 	FUSEEntryList	entries;
83 	int				type;
84 	int32			refCount;
85 	bool			dirty;
86 
87 	FUSENode(ino_t id, int type)
88 		:
89 		id(id),
90 		type(type),
91 		refCount(1),
92 		dirty(false)
93 	{
94 	}
95 
96 	FUSENode* Parent() const
97 	{
98 		FUSEEntry* entry = entries.Head();
99 		return entry != NULL ? entry->parent : NULL;
100 	}
101 };
102 
103 
104 struct FUSEEntryHashDefinition {
105 	typedef FUSEEntryRef	KeyType;
106 	typedef	FUSEEntry		ValueType;
107 
108 	size_t HashKey(const FUSEEntryRef& key) const
109 		{ return ((uint32)key.parentID ^ (uint32)(key.parentID >> 32)) * 37
110 			+ string_hash(key.name); }
111 	size_t Hash(const FUSEEntry* value) const
112 		{ return HashKey(FUSEEntryRef(value->parent->id, value->name)); }
113 	bool Compare(const FUSEEntryRef& key, const FUSEEntry* value) const
114 		{ return value->parent->id == key.parentID
115 			&& strcmp(value->name, key.name) == 0; }
116 	HashTableLink<FUSEEntry>* GetLink(FUSEEntry* value) const
117 		{ return value; }
118 };
119 
120 
121 struct FUSENodeHashDefinition {
122 	typedef ino_t		KeyType;
123 	typedef	FUSENode	ValueType;
124 
125 	size_t HashKey(ino_t key) const
126 		{ return (uint32)key ^ (uint32)(key >> 32); }
127 	size_t Hash(const FUSENode* value) const
128 		{ return HashKey(value->id); }
129 	bool Compare(ino_t key, const FUSENode* value) const
130 		{ return value->id == key; }
131 	HashTableLink<FUSENode>* GetLink(FUSENode* value) const
132 		{ return value; }
133 };
134 
135 
136 typedef OpenHashTable<FUSEEntryHashDefinition> FUSEEntryTable;
137 typedef OpenHashTable<FUSENodeHashDefinition> FUSENodeTable;
138 
139 
140 }	// namespace UserlandFS
141 
142 using UserlandFS::FUSENode;
143 
144 
145 #endif	// USERLAND_FS_FUSE_ENTRY_H
146