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