xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEEntry.h (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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 : DoublyLinkedListLinkImpl<FUSEEntry> {
39 	FUSENode*	parent;
40 	char*		name;
41 	FUSENode*	node;
42 	FUSEEntry*	hashLink;
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 {
81 	ino_t			id;
82 	FUSEEntryList	entries;
83 	int				type;
84 	int32			refCount;
85 	int32			cacheCount;
86 	bool			dirty;
87 	FUSENode*		hashLink;
88 
89 	FUSENode(ino_t id, int type)
90 		:
91 		id(id),
92 		type(type),
93 		refCount(1),
94 		cacheCount(0),
95 		dirty(false)
96 	{
97 	}
98 
99 	FUSENode* Parent() const
100 	{
101 		FUSEEntry* entry = entries.Head();
102 		return entry != NULL ? entry->parent : NULL;
103 	}
104 };
105 
106 
107 struct FUSEEntryHashDefinition {
108 	typedef FUSEEntryRef	KeyType;
109 	typedef	FUSEEntry		ValueType;
110 
111 	size_t HashKey(const FUSEEntryRef& key) const
112 		{ return ((uint32)key.parentID ^ (uint32)(key.parentID >> 32)) * 37
113 			+ string_hash(key.name); }
114 	size_t Hash(const FUSEEntry* value) const
115 		{ return HashKey(FUSEEntryRef(value->parent->id, value->name)); }
116 	bool Compare(const FUSEEntryRef& key, const FUSEEntry* value) const
117 		{ return value->parent->id == key.parentID
118 			&& strcmp(value->name, key.name) == 0; }
119 	FUSEEntry*& GetLink(FUSEEntry* value) const
120 		{ return value->hashLink; }
121 };
122 
123 
124 struct FUSENodeHashDefinition {
125 	typedef ino_t		KeyType;
126 	typedef	FUSENode	ValueType;
127 
128 	size_t HashKey(ino_t key) const
129 		{ return (uint32)key ^ (uint32)(key >> 32); }
130 	size_t Hash(const FUSENode* value) const
131 		{ return HashKey(value->id); }
132 	bool Compare(ino_t key, const FUSENode* value) const
133 		{ return value->id == key; }
134 	FUSENode*& GetLink(FUSENode* value) const
135 		{ return value->hashLink; }
136 };
137 
138 
139 typedef BOpenHashTable<FUSEEntryHashDefinition> FUSEEntryTable;
140 typedef BOpenHashTable<FUSENodeHashDefinition> FUSENodeTable;
141 
142 
143 }	// namespace UserlandFS
144 
145 using UserlandFS::FUSENode;
146 
147 
148 #endif	// USERLAND_FS_FUSE_ENTRY_H
149