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