1/*
2 * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef USERLAND_FS_FS_CAPABILITIES_H
6#define USERLAND_FS_FS_CAPABILITIES_H
7
8#include <string.h>
9#include <stdio.h>
10
11#include "Debug.h"
12
13enum client_fs_type {
14	CLIENT_FS_BEOS_KERNEL = 0,
15	CLIENT_FS_HAIKU_KERNEL,
16	CLIENT_FS_FUSE
17};
18
19// FS capabilities
20enum {
21	// FS operations
22	FS_CAPABILITY_MOUNT	= 0,
23
24	FS_CAPABILITY_COUNT
25};
26
27// Volume capabilities
28enum {
29	// general operations
30	FS_VOLUME_CAPABILITY_UNMOUNT,
31
32	FS_VOLUME_CAPABILITY_READ_FS_INFO,
33	FS_VOLUME_CAPABILITY_WRITE_FS_INFO,
34	FS_VOLUME_CAPABILITY_SYNC,
35
36	FS_VOLUME_CAPABILITY_GET_VNODE,
37
38	// index directory & index operations
39	FS_VOLUME_CAPABILITY_OPEN_INDEX_DIR,
40	FS_VOLUME_CAPABILITY_CLOSE_INDEX_DIR,
41	FS_VOLUME_CAPABILITY_FREE_INDEX_DIR_COOKIE,
42	FS_VOLUME_CAPABILITY_READ_INDEX_DIR,
43	FS_VOLUME_CAPABILITY_REWIND_INDEX_DIR,
44
45	FS_VOLUME_CAPABILITY_CREATE_INDEX,
46	FS_VOLUME_CAPABILITY_REMOVE_INDEX,
47	FS_VOLUME_CAPABILITY_READ_INDEX_STAT,
48
49	// query operations
50	FS_VOLUME_CAPABILITY_OPEN_QUERY,
51	FS_VOLUME_CAPABILITY_CLOSE_QUERY,
52	FS_VOLUME_CAPABILITY_FREE_QUERY_COOKIE,
53	FS_VOLUME_CAPABILITY_READ_QUERY,
54	FS_VOLUME_CAPABILITY_REWIND_QUERY,
55
56	// support for FS layers
57	FS_VOLUME_CAPABILITY_ALL_LAYERS_MOUNTED,
58	FS_VOLUME_CAPABILITY_CREATE_SUB_VNODE,
59	FS_VOLUME_CAPABILITY_DELETE_SUB_VNODE,
60
61	FS_VOLUME_CAPABILITY_COUNT
62};
63
64// VNode capabilities
65enum {
66	// vnode operations
67	FS_VNODE_CAPABILITY_LOOKUP,
68	FS_VNODE_CAPABILITY_GET_VNODE_NAME,
69
70	FS_VNODE_CAPABILITY_PUT_VNODE,
71	FS_VNODE_CAPABILITY_REMOVE_VNODE,
72
73	// VM file access
74	FS_VNODE_CAPABILITY_CAN_PAGE,
75	FS_VNODE_CAPABILITY_READ_PAGES,
76	FS_VNODE_CAPABILITY_WRITE_PAGES,
77
78	// asynchronous I/O
79	FS_VNODE_CAPABILITY_IO,
80	FS_VNODE_CAPABILITY_CANCEL_IO,
81
82	// cache file access
83	FS_VNODE_CAPABILITY_GET_FILE_MAP,
84
85	// common operations
86	FS_VNODE_CAPABILITY_IOCTL,
87	FS_VNODE_CAPABILITY_SET_FLAGS,
88	FS_VNODE_CAPABILITY_SELECT,
89	FS_VNODE_CAPABILITY_DESELECT,
90	FS_VNODE_CAPABILITY_FSYNC,
91
92	FS_VNODE_CAPABILITY_READ_SYMLINK,
93	FS_VNODE_CAPABILITY_CREATE_SYMLINK,
94
95	FS_VNODE_CAPABILITY_LINK,
96	FS_VNODE_CAPABILITY_UNLINK,
97	FS_VNODE_CAPABILITY_RENAME,
98
99	FS_VNODE_CAPABILITY_ACCESS,
100	FS_VNODE_CAPABILITY_READ_STAT,
101	FS_VNODE_CAPABILITY_WRITE_STAT,
102
103	// file operations
104	FS_VNODE_CAPABILITY_CREATE,
105	FS_VNODE_CAPABILITY_OPEN,
106	FS_VNODE_CAPABILITY_CLOSE,
107	FS_VNODE_CAPABILITY_FREE_COOKIE,
108	FS_VNODE_CAPABILITY_READ,
109	FS_VNODE_CAPABILITY_WRITE,
110
111	// directory operations
112	FS_VNODE_CAPABILITY_CREATE_DIR,
113	FS_VNODE_CAPABILITY_REMOVE_DIR,
114	FS_VNODE_CAPABILITY_OPEN_DIR,
115	FS_VNODE_CAPABILITY_CLOSE_DIR,
116	FS_VNODE_CAPABILITY_FREE_DIR_COOKIE,
117	FS_VNODE_CAPABILITY_READ_DIR,
118	FS_VNODE_CAPABILITY_REWIND_DIR,
119
120	// attribute directory operations
121	FS_VNODE_CAPABILITY_OPEN_ATTR_DIR,
122	FS_VNODE_CAPABILITY_CLOSE_ATTR_DIR,
123	FS_VNODE_CAPABILITY_FREE_ATTR_DIR_COOKIE,
124	FS_VNODE_CAPABILITY_READ_ATTR_DIR,
125	FS_VNODE_CAPABILITY_REWIND_ATTR_DIR,
126
127	// attribute operations
128	FS_VNODE_CAPABILITY_CREATE_ATTR,
129	FS_VNODE_CAPABILITY_OPEN_ATTR,
130	FS_VNODE_CAPABILITY_CLOSE_ATTR,
131	FS_VNODE_CAPABILITY_FREE_ATTR_COOKIE,
132	FS_VNODE_CAPABILITY_READ_ATTR,
133	FS_VNODE_CAPABILITY_WRITE_ATTR,
134
135	FS_VNODE_CAPABILITY_READ_ATTR_STAT,
136	FS_VNODE_CAPABILITY_WRITE_ATTR_STAT,
137	FS_VNODE_CAPABILITY_RENAME_ATTR,
138	FS_VNODE_CAPABILITY_REMOVE_ATTR,
139
140	// support for node and FS layers
141	FS_VNODE_CAPABILITY_CREATE_SPECIAL_NODE,
142	FS_VNODE_CAPABILITY_GET_SUPER_VNODE,
143
144	FS_VNODE_CAPABILITY_COUNT
145};
146
147namespace UserlandFSUtil {
148
149template<const int CapabilityCount>
150struct FSCapabilitiesBase {
151			uint8				capabilities[(CapabilityCount + 7) / 8];
152
153	inline	void				ClearAll();
154
155	inline	void				Set(uint32 capability, bool set = true);
156	inline	void				Clear(uint32 capability);
157	inline	bool				Get(uint32 capability) const;
158
159	inline	uint32				GetHashCode() const;
160
161	inline	bool				operator==(
162									const FSCapabilitiesBase<CapabilityCount>&
163										other) const;
164
165	inline	void				Dump() const;
166};
167
168
169// ClearAll
170template<const int CapabilityCount>
171inline void
172FSCapabilitiesBase<CapabilityCount>::ClearAll()
173{
174	memset(capabilities, 0, sizeof(capabilities));
175}
176
177
178// Set
179template<const int CapabilityCount>
180inline void
181FSCapabilitiesBase<CapabilityCount>::Set(uint32 capability, bool set)
182{
183	if (capability >= CapabilityCount)
184		return;
185
186	uint8 flag = uint8(1 << (capability % 8));
187	if (set)
188		capabilities[capability / 8] |= flag;
189	else
190		capabilities[capability / 8] &= ~flag;
191}
192
193
194// Clear
195template<const int CapabilityCount>
196inline void
197FSCapabilitiesBase<CapabilityCount>::Clear(uint32 capability)
198{
199	Set(capability, false);
200}
201
202
203// Get
204template<const int CapabilityCount>
205inline bool
206FSCapabilitiesBase<CapabilityCount>::Get(uint32 capability) const
207{
208	if (capability >= CapabilityCount)
209		return false;
210
211	uint8 flag = uint8(1 << (capability % 8));
212	return (capabilities[capability / 8] & flag);
213}
214
215
216// GetHashCode
217template<const int CapabilityCount>
218inline uint32
219FSCapabilitiesBase<CapabilityCount>::GetHashCode() const
220{
221	uint32 hashCode = 0;
222	int byteCount = sizeof(capabilities);
223	for (int i = 0; i < byteCount; i++)
224		hashCode = hashCode * 37 + capabilities[i];
225
226	return hashCode;
227}
228
229
230// ==
231template<const int CapabilityCount>
232inline bool
233FSCapabilitiesBase<CapabilityCount>::operator==(
234	const FSCapabilitiesBase<CapabilityCount>& other) const
235{
236	int byteCount = sizeof(capabilities);
237	for (int i = 0; i < byteCount; i++) {
238		if (capabilities[i] != other.capabilities[i])
239			return false;
240	}
241
242	return true;
243}
244
245
246// Dump
247template<const int CapabilityCount>
248inline void
249FSCapabilitiesBase<CapabilityCount>::Dump() const
250{
251	D(
252		char buffer[128];
253		int byteCount = sizeof(capabilities);
254		for (int i = 0; i < byteCount; i++)
255			sprintf(buffer + 2 * i, "%02x", (int)capabilities[i]);
256
257		PRINT(("FSCapabilities[%s]\n", buffer));
258	)
259}
260
261
262typedef FSCapabilitiesBase<FS_CAPABILITY_COUNT>			FSCapabilities;
263typedef FSCapabilitiesBase<FS_VOLUME_CAPABILITY_COUNT>	FSVolumeCapabilities;
264typedef FSCapabilitiesBase<FS_VNODE_CAPABILITY_COUNT>	FSVNodeCapabilities;
265
266}	// namespace UserlandFSUtil
267
268using UserlandFSUtil::FSCapabilities;
269using UserlandFSUtil::FSVolumeCapabilities;
270using UserlandFSUtil::FSVNodeCapabilities;
271
272#endif	// USERLAND_FS_FS_CAPABILITIES_H
273