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
BeOSKernelFileSystem(const char * fsName,beos_vnode_ops * fsOps)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
~BeOSKernelFileSystem()29 BeOSKernelFileSystem::~BeOSKernelFileSystem()
30 {
31 if (fBlockCacheInitialized)
32 beos_shutdown_block_cache();
33 }
34
35
36 // Init
37 status_t
Init()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
CreateVolume(Volume ** volume,dev_t id)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
DeleteVolume(Volume * volume)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
_InitCapabilities()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
get_beos_file_system_node_capabilities(FSVNodeCapabilities & capabilities)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
userlandfs_create_file_system(const char * fsName,image_id image,FileSystem ** _fileSystem)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