xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.cpp (revision 95c9effd68127df2dce202d5e254a7c86560010a)
1 // BeOSKernelFileSystem.cpp
2 
3 #include "BeOSKernelFileSystem.h"
4 
5 #include <new>
6 
7 #include "beos_kernel_emu.h"
8 #include "BeOSKernelVolume.h"
9 #include "fs_cache.h"
10 #include "fs_interface.h"
11 
12 
13 static const int32 kMaxBlockCacheBlocks = 16384;
14 
15 
16 // constructor
17 BeOSKernelFileSystem::BeOSKernelFileSystem(const char* fsName,
18 	beos_vnode_ops* fsOps)
19 	:
20 	FileSystem(fsName),
21 	fFSOps(fsOps),
22 	fBlockCacheInitialized(false)
23 {
24 	_InitCapabilities();
25 }
26 
27 
28 // destructor
29 BeOSKernelFileSystem::~BeOSKernelFileSystem()
30 {
31 	if (fBlockCacheInitialized)
32 		beos_shutdown_block_cache();
33 }
34 
35 
36 // Init
37 status_t
38 BeOSKernelFileSystem::Init()
39 {
40 	// init the block cache
41 	status_t error = beos_init_block_cache(kMaxBlockCacheBlocks, 0);
42 	if (error != B_OK)
43 		RETURN_ERROR(error);
44 
45 	fBlockCacheInitialized = true;
46 	return B_OK;
47 }
48 
49 
50 // CreateVolume
51 status_t
52 BeOSKernelFileSystem::CreateVolume(Volume** volume, dev_t id)
53 {
54 	// check initialization and parameters
55 	if (!fFSOps || !volume)
56 		return B_BAD_VALUE;
57 
58 	// create the volume
59 	*volume = new(std::nothrow) BeOSKernelVolume(this, id, fFSOps,
60 		fVolumeCapabilities);
61 	if (!*volume)
62 		return B_NO_MEMORY;
63 	return B_OK;
64 }
65 
66 // DeleteVolume
67 status_t
68 BeOSKernelFileSystem::DeleteVolume(Volume* volume)
69 {
70 	if (!volume || !dynamic_cast<BeOSKernelVolume*>(volume))
71 		return B_BAD_VALUE;
72 	delete volume;
73 	return B_OK;
74 }
75 
76 // _InitCapabilities
77 void
78 BeOSKernelFileSystem::_InitCapabilities()
79 {
80 	fCapabilities.ClearAll();
81 	fVolumeCapabilities.ClearAll();
82 	fNodeCapabilities.ClearAll();
83 
84 	// FS interface type
85 	fClientFSType = CLIENT_FS_BEOS_KERNEL;
86 
87 	// FS operations
88 	fCapabilities.Set(FS_CAPABILITY_MOUNT, fFSOps->mount);
89 
90 
91 	// Volume operations
92 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_UNMOUNT, fFSOps->unmount);
93 
94 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_FS_INFO, fFSOps->rfsstat);
95 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_WRITE_FS_INFO,
96 		fFSOps->wfsstat);
97 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_SYNC, fFSOps->sync);
98 
99 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_GET_VNODE, fFSOps->read_vnode);
100 
101 	// index directory & index operations
102 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_OPEN_INDEX_DIR,
103 		fFSOps->open_indexdir);
104 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CLOSE_INDEX_DIR,
105 		fFSOps->close_indexdir);
106 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_FREE_INDEX_DIR_COOKIE,
107 		fFSOps->free_indexdircookie);
108 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_INDEX_DIR,
109 		fFSOps->read_indexdir);
110 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_REWIND_INDEX_DIR,
111 		fFSOps->rewind_indexdir);
112 
113 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CREATE_INDEX,
114 		fFSOps->create_index);
115 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_REMOVE_INDEX,
116 		fFSOps->remove_index);
117 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_INDEX_STAT,
118 		fFSOps->stat_index);
119 
120 	// query operations
121 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_OPEN_QUERY,
122 		fFSOps->open_query);
123 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CLOSE_QUERY,
124 		fFSOps->close_query);
125 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_FREE_QUERY_COOKIE,
126 		fFSOps->free_querycookie);
127 	fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_QUERY,
128 		fFSOps->read_query);
129 	// missing: FS_VOLUME_CAPABILITY_REWIND_QUERY,
130 
131 	// vnode operations
132 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LOOKUP, fFSOps->walk);
133 	// missing: FS_VNODE_CAPABILITY_GET_VNODE_NAME,
134 
135 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_PUT_VNODE, fFSOps->write_vnode);
136 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_VNODE,
137 		fFSOps->remove_vnode);
138 
139 	// VM file access
140 	// missing: FS_VNODE_CAPABILITY_CAN_PAGE,
141 	// missing: FS_VNODE_CAPABILITY_READ_PAGES,
142 	// missing: FS_VNODE_CAPABILITY_WRITE_PAGES,
143 
144 	// cache file access
145 	// missing: FS_VNODE_CAPABILITY_GET_FILE_MAP,
146 
147 	// common operations
148 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_IOCTL, fFSOps->ioctl);
149 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SET_FLAGS, fFSOps->setflags);
150 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SELECT, fFSOps->select);
151 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_DESELECT, fFSOps->deselect);
152 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FSYNC, fFSOps->fsync);
153 
154 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_SYMLINK, fFSOps->readlink);
155 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_SYMLINK, fFSOps->symlink);
156 
157 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LINK, fFSOps->link);
158 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_UNLINK, fFSOps->unlink);
159 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME, fFSOps->rename);
160 
161 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_ACCESS, fFSOps->access);
162 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_STAT, fFSOps->rstat);
163 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_STAT, fFSOps->wstat);
164 
165 	// file operations
166 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE, fFSOps->create);
167 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN, fFSOps->open);
168 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE, fFSOps->close);
169 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_COOKIE, fFSOps->free_cookie);
170 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ, fFSOps->read);
171 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE, fFSOps->write);
172 
173 	// directory operations
174 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_DIR, fFSOps->mkdir);
175 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_DIR, fFSOps->rmdir);
176 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_DIR, fFSOps->opendir);
177 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE_DIR, fFSOps->closedir);
178 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_DIR_COOKIE,
179 		fFSOps->free_dircookie);
180 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_DIR, fFSOps->readdir);
181 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_DIR, fFSOps->rewinddir);
182 
183 	// attribute directory operations
184 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_ATTR_DIR,
185 		fFSOps->open_attrdir);
186 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE_ATTR_DIR,
187 		fFSOps->close_attrdir);
188 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_DIR_COOKIE,
189 		fFSOps->free_attrdircookie);
190 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_DIR,
191 		fFSOps->read_attrdir);
192 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_ATTR_DIR,
193 		fFSOps->rewind_attrdir);
194 
195 	// attribute operations
196 	// we emulate open_attr() and free_attr_dir_cookie() if either read_attr()
197 	// or write_attr() is present
198 	bool hasAttributes = (fFSOps->read_attr || fFSOps->write_attr);
199 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_ATTR, hasAttributes);
200 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_ATTR, hasAttributes);
201 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE_ATTR, false);
202 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_COOKIE, hasAttributes);
203 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR, fFSOps->read_attr);
204 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_ATTR, fFSOps->write_attr);
205 
206 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_STAT,
207 		fFSOps->stat_attr);
208 	// missing: FS_VNODE_CAPABILITY_WRITE_ATTR_STAT
209 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME_ATTR, fFSOps->rename_attr);
210 	fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_ATTR, fFSOps->remove_attr);
211 }
212 
213 
214 // #pragma mark -
215 
216 
217 // get_beos_file_system_node_capabilities
218 //
219 // Service function for beos_kernel_emu.cpp. Declared in beos_kernel_emu.h.
220 void
221 get_beos_file_system_node_capabilities(FSVNodeCapabilities& capabilities)
222 {
223 	BeOSKernelFileSystem* fileSystem
224 		= static_cast<BeOSKernelFileSystem*>(FileSystem::GetInstance());
225 	fileSystem->GetNodeCapabilities(capabilities);
226 }
227 
228 
229 // #pragma mark - bootstrapping
230 
231 
232 status_t
233 userlandfs_create_file_system(const char* fsName, image_id image,
234 	FileSystem** _fileSystem)
235 {
236 	// get the symbols "fs_entry" and "api_version"
237 	beos_vnode_ops* fsOps;
238 	status_t error = get_image_symbol(image, "fs_entry", B_SYMBOL_TYPE_DATA,
239 		(void**)&fsOps);
240 	if (error != B_OK)
241 		RETURN_ERROR(error);
242 	int32* apiVersion;
243 	error = get_image_symbol(image, "api_version", B_SYMBOL_TYPE_DATA,
244 		(void**)&apiVersion);
245 	if (error != B_OK)
246 		RETURN_ERROR(error);
247 
248 	// check api version
249 	if (*apiVersion != BEOS_FS_API_VERSION)
250 		RETURN_ERROR(B_ERROR);
251 
252 	// create the file system
253 	BeOSKernelFileSystem* fileSystem
254 		= new(std::nothrow) BeOSKernelFileSystem(fsName, fsOps);
255 	if (!fileSystem)
256 		RETURN_ERROR(B_NO_MEMORY);
257 
258 	error = fileSystem->Init();
259 	if (error != B_OK) {
260 		delete fileSystem;
261 		return error;
262 	}
263 
264 	*_fileSystem = fileSystem;
265 	return B_OK;
266 }
267