1/* 2 * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include "kernel_interface.h" 7 8#include <dirent.h> 9 10#include <KernelExport.h> 11#include <fs_interface.h> 12 13#include "Debug.h" 14#include "FileSystem.h" 15#include "String.h" 16#include "UserlandFS.h" 17#include "Volume.h" 18 19 20// #pragma mark - general 21 22 23// parse_parameters 24static status_t 25parse_parameters(const char *parameters, String &fsName, 26 const char **fsParameters) 27{ 28 // check parameters 29 if (!parameters) 30 return B_BAD_VALUE; 31 32 int32 len = strlen(parameters); 33 34 // skip leading white space 35 for (; len > 0; parameters++, len--) { 36 if (*parameters != ' ' && *parameters != '\t' && *parameters != '\n') 37 break; 38 } 39 if (len == 0) 40 return B_BAD_VALUE; 41 42 // get the file system name 43 int32 fsNameLen = len; 44 for (int32 i = 0; i < len; i++) { 45 if (parameters[i] == ' ' || parameters[i] == '\t' 46 || parameters[i] == '\n') { 47 fsNameLen = i; 48 break; 49 } 50 } 51 52 fsName.SetTo(parameters, fsNameLen); 53 if (fsName.GetLength() == 0) { 54 exit_debugging(); 55 return B_NO_MEMORY; 56 } 57 parameters += fsNameLen; 58 len -= fsNameLen; 59 60 // skip leading white space of the FS parameters 61 for (; len > 0; parameters++, len--) { 62 if (*parameters != ' ' && *parameters != '\t' && *parameters != '\n') 63 break; 64 } 65 *fsParameters = parameters; 66 67 return B_OK; 68} 69 70// userlandfs_mount 71static status_t 72userlandfs_mount(fs_volume* fsVolume, const char* device, uint32 flags, 73 const char* args, ino_t* rootVnodeID) 74{ 75 PRINT(("userlandfs_mount(%p (%" B_PRId32 "), %s, 0x%" B_PRIx32 76 ", %s, %p)\n", fsVolume, fsVolume->id, device, flags, args, 77 rootVnodeID)); 78 79 status_t error = B_OK; 80 81 // get the parameters 82// TODO: The parameters are in driver settings format now. 83 String fsName; 84 const char* fsParameters; 85 error = parse_parameters(args, fsName, &fsParameters); 86 if (error != B_OK) 87 RETURN_ERROR(error); 88 89 // get the UserlandFS object 90 UserlandFS* userlandFS = UserlandFS::GetUserlandFS(); 91 if (!userlandFS) 92 RETURN_ERROR(B_ERROR); 93 94 // get the file system 95 FileSystem* fileSystem = NULL; 96 error = userlandFS->RegisterFileSystem(fsName.GetString(), &fileSystem); 97 if (error != B_OK) 98 RETURN_ERROR(error); 99 100 // mount the volume 101 Volume* volume = NULL; 102 error = fileSystem->Mount(fsVolume, device, flags, fsParameters, &volume); 103 if (error != B_OK) { 104 userlandFS->UnregisterFileSystem(fileSystem); 105 RETURN_ERROR(error); 106 } 107 108 fsVolume->private_volume = volume; 109 fsVolume->ops = volume->GetVolumeOps(); 110 *rootVnodeID = volume->GetRootID(); 111 112 PRINT(("userlandfs_mount() done: %p, %" B_PRIdINO "\n", 113 fsVolume->private_volume, *rootVnodeID)); 114 115 return error; 116} 117 118// userlandfs_unmount 119static status_t 120userlandfs_unmount(fs_volume* fsVolume) 121{ 122 Volume* volume = (Volume*)fsVolume->private_volume; 123 PRINT(("userlandfs_unmount(%p)\n", volume)); 124 125 FileSystem* fileSystem = volume->GetFileSystem(); 126 status_t error = volume->Unmount(); 127 // The error code the FS's unmount hook returns is completely irrelevant to 128 // the VFS. It considers the volume unmounted in any case. 129 volume->ReleaseReference(); 130 UserlandFS::GetUserlandFS()->UnregisterFileSystem(fileSystem); 131 132 PRINT(("userlandfs_unmount() done: %" B_PRIx32 "\n", error)); 133 return error; 134} 135 136// userlandfs_sync 137static status_t 138userlandfs_sync(fs_volume* fsVolume) 139{ 140 Volume* volume = (Volume*)fsVolume->private_volume; 141 PRINT(("userlandfs_sync(%p)\n", volume)); 142 status_t error = volume->Sync(); 143 PRINT(("userlandfs_sync() done: %" B_PRIx32 "\n", error)); 144 return error; 145} 146 147// userlandfs_read_fs_info 148static status_t 149userlandfs_read_fs_info(fs_volume* fsVolume, struct fs_info* info) 150{ 151 Volume* volume = (Volume*)fsVolume->private_volume; 152 PRINT(("userlandfs_read_fs_info(%p, %p)\n", volume, info)); 153 status_t error = volume->ReadFSInfo(info); 154 PRINT(("userlandfs_read_fs_info() done: %" B_PRIx32 "\n", error)); 155 return error; 156} 157 158// userlandfs_write_fs_info 159static status_t 160userlandfs_write_fs_info(fs_volume* fsVolume, const struct fs_info* info, 161 uint32 mask) 162{ 163 Volume* volume = (Volume*)fsVolume->private_volume; 164 PRINT(("userlandfs_write_fs_info(%p, %p, 0x%" B_PRIx32 ")\n", volume, info, 165 mask)); 166 status_t error = volume->WriteFSInfo(info, mask); 167 PRINT(("userlandfs_write_fs_info() done: %" B_PRIx32 "\n", error)); 168 return error; 169} 170 171 172// #pragma mark - vnodes 173 174 175// userlandfs_lookup 176static status_t 177userlandfs_lookup(fs_volume* fsVolume, fs_vnode* fsDir, const char* entryName, 178 ino_t* vnid) 179{ 180 Volume* volume = (Volume*)fsVolume->private_volume; 181 PRINT(("userlandfs_lookup(%p, %p, `%s', %p)\n", volume, fsDir->private_node, 182 entryName, vnid)); 183 status_t error = volume->Lookup(fsDir->private_node, entryName, vnid); 184 PRINT(("userlandfs_lookup() done: (%" B_PRIx32 ", %" B_PRIdINO ")\n", error, 185 *vnid)); 186 return error; 187} 188 189// userlandfs_get_vnode_name 190static status_t 191userlandfs_get_vnode_name(fs_volume* fsVolume, fs_vnode* fsNode, char* buffer, 192 size_t bufferSize) 193{ 194 Volume* volume = (Volume*)fsVolume->private_volume; 195 PRINT(("userlandfs_get_vnode_name(%p, %p, %p, %" B_PRIuSIZE ")\n", volume, 196 fsNode->private_node, buffer, bufferSize)); 197 status_t error = volume->GetVNodeName(fsNode->private_node, buffer, 198 bufferSize); 199 PRINT(("userlandfs_get_vnode_name() done: (%" B_PRIx32 ", \"%.*s\")\n", 200 error, (int)bufferSize, (error == B_OK ? buffer : NULL))); 201 return error; 202} 203 204// userlandfs_get_vnode 205static status_t 206userlandfs_get_vnode(fs_volume* fsVolume, ino_t vnid, fs_vnode* fsNode, 207 int* _type, uint32* _flags, bool reenter) 208{ 209 Volume* volume = (Volume*)fsVolume->private_volume; 210 PRINT(("userlandfs_get_vnode(%p, %" B_PRIdINO ", %p, %d)\n", volume, vnid, 211 fsNode->private_node, reenter)); 212 void* node; 213 fs_vnode_ops* ops; 214 status_t error = volume->ReadVNode(vnid, reenter, &node, &ops, _type, 215 _flags); 216 if (error == B_OK) { 217 fsNode->private_node = node; 218 fsNode->ops = ops; 219 } 220 221 PRINT(("userlandfs_get_vnode() done: (%" B_PRIx32 ", %p, %#x, %#" B_PRIx32 222 ")\n", error, node, *_type, *_flags)); 223 return error; 224} 225 226// userlandfs_put_vnode 227static status_t 228userlandfs_put_vnode(fs_volume* fsVolume, fs_vnode* fsNode, bool reenter) 229{ 230 Volume* volume = (Volume*)fsVolume->private_volume; 231// DANGER: If dbg_printf() is used, this thread will enter another FS and 232// even perform a write operation. The is dangerous here, since this hook 233// may be called out of the other FSs, since, for instance a put_vnode() 234// called from another FS may cause the VFS layer to free vnodes and thus 235// invoke this hook. 236// PRINT(("userlandfs_put_vnode(%p, %p, %d)\n", volume, fsNode->private_node, 237// reenter)); 238 status_t error = volume->WriteVNode(fsNode->private_node, reenter); 239// PRINT(("userlandfs_put_vnode() done: %" B_PRIx32 "\n", error)); 240 return error; 241} 242 243// userlandfs_remove_vnode 244static status_t 245userlandfs_remove_vnode(fs_volume* fsVolume, fs_vnode* fsNode, bool reenter) 246{ 247 Volume* volume = (Volume*)fsVolume->private_volume; 248// DANGER: See userlandfs_write_vnode(). 249// PRINT(("userlandfs_remove_vnode(%p, %p, %d)\n", volume, 250// fsNode->private_node, reenter)); 251 status_t error = volume->RemoveVNode(fsNode->private_node, reenter); 252// PRINT(("userlandfs_remove_vnode() done: %" B_PRIx32 "\n", error)); 253 return error; 254} 255 256 257// #pragma mark - asynchronous I/O 258 259 260// userlandfs_io 261status_t 262userlandfs_io(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 263 io_request* request) 264{ 265 Volume* volume = (Volume*)fsVolume->private_volume; 266 PRINT(("userlandfs_io(%p, %p, %p, %p)\n", volume, fsNode->private_node, 267 cookie, request)); 268 status_t error = volume->DoIO(fsNode->private_node, cookie, request); 269 PRINT(("userlandfs_io() done: (%" B_PRIx32 ")\n", error)); 270 return error; 271} 272 273 274// userlandfs_cancel_io 275status_t 276userlandfs_cancel_io(fs_volume* fsVolume, fs_vnode* fsNode, void *cookie, 277 io_request *request) 278{ 279 Volume* volume = (Volume*)fsVolume->private_volume; 280 PRINT(("userlandfs_cancel_io(%p, %p, %p, %p)\n", volume, 281 fsNode->private_node, cookie, request)); 282 status_t error = volume->CancelIO(fsNode->private_node, cookie, request); 283 PRINT(("userlandfs_cancel_io() done: (%" B_PRIx32 ")\n", error)); 284 return error; 285} 286 287 288// #pragma mark - common 289 290 291// userlandfs_ioctl 292static status_t 293userlandfs_ioctl(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, uint32 op, 294 void* buffer, size_t length) 295{ 296 Volume* volume = (Volume*)fsVolume->private_volume; 297 PRINT(("userlandfs_ioctl(%p, %p, %p, %" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n", 298 volume, fsNode->private_node, cookie, op, buffer, length)); 299 status_t error = volume->IOCtl(fsNode->private_node, cookie, op, buffer, 300 length); 301 PRINT(("userlandfs_ioctl() done: (%" B_PRIx32 ")\n", error)); 302 return error; 303} 304 305// userlandfs_set_flags 306static status_t 307userlandfs_set_flags(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 308 int flags) 309{ 310 Volume* volume = (Volume*)fsVolume->private_volume; 311 PRINT(("userlandfs_set_flags(%p, %p, %p, %d)\n", volume, 312 fsNode->private_node, cookie, flags)); 313 status_t error = volume->SetFlags(fsNode->private_node, cookie, flags); 314 PRINT(("userlandfs_set_flags() done: (%" B_PRIx32 ")\n", error)); 315 return error; 316} 317 318// userlandfs_select 319static status_t 320userlandfs_select(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 321 uint8 event, selectsync* sync) 322{ 323 Volume* volume = (Volume*)fsVolume->private_volume; 324 PRINT(("userlandfs_select(%p, %p, %p, %hhd, %p)\n", volume, 325 fsNode->private_node, cookie, event, sync)); 326 status_t error = volume->Select(fsNode->private_node, cookie, event, sync); 327 PRINT(("userlandfs_select() done: (%" B_PRIx32 ")\n", error)); 328 return error; 329} 330 331// userlandfs_deselect 332static status_t 333userlandfs_deselect(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 334 uint8 event, selectsync* sync) 335{ 336 Volume* volume = (Volume*)fsVolume->private_volume; 337 PRINT(("userlandfs_deselect(%p, %p, %p, %hhd, %p)\n", volume, 338 fsNode->private_node, cookie, event, sync)); 339 status_t error = volume->Deselect(fsNode->private_node, cookie, event, 340 sync); 341 PRINT(("userlandfs_deselect() done: (%" B_PRIx32 ")\n", error)); 342 return error; 343} 344 345// userlandfs_fsync 346static status_t 347userlandfs_fsync(fs_volume* fsVolume, fs_vnode* fsNode) 348{ 349 Volume* volume = (Volume*)fsVolume->private_volume; 350 PRINT(("userlandfs_fsync(%p, %p)\n", volume, fsNode->private_node)); 351 status_t error = volume->FSync(fsNode->private_node); 352 PRINT(("userlandfs_fsync() done: %" B_PRIx32 "\n", error)); 353 return error; 354} 355 356// userlandfs_read_symlink 357static status_t 358userlandfs_read_symlink(fs_volume* fsVolume, fs_vnode* fsLink, char* buffer, 359 size_t* bufferSize) 360{ 361 Volume* volume = (Volume*)fsVolume->private_volume; 362 PRINT(("userlandfs_read_symlink(%p, %p, %p, %" B_PRIuSIZE ")\n", volume, 363 fsLink->private_node, buffer, *bufferSize)); 364 status_t error = volume->ReadSymlink(fsLink->private_node, buffer, 365 *bufferSize, bufferSize); 366 PRINT(("userlandfs_read_symlink() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", 367 error, *bufferSize)); 368 return error; 369} 370 371// userlandfs_create_symlink 372static status_t 373userlandfs_create_symlink(fs_volume* fsVolume, fs_vnode* fsDir, 374 const char* name, const char* path, int mode) 375{ 376 Volume* volume = (Volume*)fsVolume->private_volume; 377 PRINT(("userlandfs_create_symlink(%p, %p, `%s', `%s', %d)\n", volume, 378 fsDir->private_node, name, path, mode)); 379 status_t error = volume->CreateSymlink(fsDir->private_node, name, path, 380 mode); 381 PRINT(("userlandfs_create_symlink() done: (%" B_PRIx32 ")\n", error)); 382 return error; 383} 384 385// userlandfs_link 386static status_t 387userlandfs_link(fs_volume* fsVolume, fs_vnode* fsDir, const char* name, 388 fs_vnode* fsNode) 389{ 390 Volume* volume = (Volume*)fsVolume->private_volume; 391 PRINT(("userlandfs_link(%p, %p, `%s', %p)\n", volume, 392 fsDir->private_node, name, fsNode->private_node)); 393 status_t error = volume->Link(fsDir->private_node, name, 394 fsNode->private_node); 395 PRINT(("userlandfs_link() done: (%" B_PRIx32 ")\n", error)); 396 return error; 397} 398 399// userlandfs_unlink 400static status_t 401userlandfs_unlink(fs_volume* fsVolume, fs_vnode* fsDir, const char* name) 402{ 403 Volume* volume = (Volume*)fsVolume->private_volume; 404 PRINT(("userlandfs_unlink(%p, %p, `%s')\n", volume, fsDir->private_node, 405 name)); 406 status_t error = volume->Unlink(fsDir->private_node, name); 407 PRINT(("userlandfs_unlink() done: (%" B_PRIx32 ")\n", error)); 408 return error; 409} 410 411// userlandfs_rename 412static status_t 413userlandfs_rename(fs_volume* fsVolume, fs_vnode* fsFromDir, 414 const char *fromName, fs_vnode* fsToDir, const char *toName) 415{ 416 Volume* volume = (Volume*)fsVolume->private_volume; 417 PRINT(("userlandfs_rename(%p, %p, `%s', %p, `%s')\n", volume, 418 fsFromDir->private_node, fromName, fsToDir->private_node, toName)); 419 status_t error = volume->Rename(fsFromDir->private_node, fromName, 420 fsToDir->private_node, toName); 421 PRINT(("userlandfs_rename() done: (%" B_PRIx32 ")\n", error)); 422 return error; 423} 424 425// userlandfs_access 426static status_t 427userlandfs_access(fs_volume* fsVolume, fs_vnode* fsNode, int mode) 428{ 429 Volume* volume = (Volume*)fsVolume->private_volume; 430 PRINT(("userlandfs_access(%p, %p, %d)\n", volume, fsNode->private_node, 431 mode)); 432 status_t error = volume->Access(fsNode->private_node, mode); 433 PRINT(("userlandfs_access() done: %" B_PRIx32 "\n", error)); 434 return error; 435} 436 437// userlandfs_read_stat 438static status_t 439userlandfs_read_stat(fs_volume* fsVolume, fs_vnode* fsNode, struct stat* st) 440{ 441 Volume* volume = (Volume*)fsVolume->private_volume; 442 PRINT(("userlandfs_read_stat(%p, %p, %p)\n", volume, fsNode->private_node, 443 st)); 444 status_t error = volume->ReadStat(fsNode->private_node, st); 445 PRINT(("userlandfs_read_stat() done: %" B_PRIx32 "\n", error)); 446 return error; 447} 448 449// userlandfs_write_stat 450static status_t 451userlandfs_write_stat(fs_volume* fsVolume, fs_vnode* fsNode, 452 const struct stat* st, uint32 mask) 453{ 454 Volume* volume = (Volume*)fsVolume->private_volume; 455 PRINT(("userlandfs_write_stat(%p, %p, %p, %" B_PRIu32 ")\n", volume, 456 fsNode->private_node, st, mask)); 457 status_t error = volume->WriteStat(fsNode->private_node, st, mask); 458 PRINT(("userlandfs_write_stat() done: %" B_PRIx32 "\n", error)); 459 return error; 460} 461 462 463// #pragma mark - files 464 465 466// userlandfs_create 467static status_t 468userlandfs_create(fs_volume* fsVolume, fs_vnode* fsDir, const char* name, 469 int openMode, int perms, void** cookie, ino_t* vnid) 470{ 471 Volume* volume = (Volume*)fsVolume->private_volume; 472 PRINT(("userlandfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", volume, 473 fsDir->private_node, name, openMode, perms, cookie, vnid)); 474 status_t error = volume->Create(fsDir->private_node, name, openMode, perms, 475 cookie, vnid); 476 PRINT(("userlandfs_create() done: (%" B_PRIx32 ", %" B_PRIdINO ", %p)\n", 477 error, *vnid, *cookie)); 478 return error; 479} 480 481// userlandfs_open 482static status_t 483userlandfs_open(fs_volume* fsVolume, fs_vnode* fsNode, int openMode, 484 void** cookie) 485{ 486 Volume* volume = (Volume*)fsVolume->private_volume; 487 PRINT(("userlandfs_open(%p, %p, %d)\n", volume, fsNode->private_node, 488 openMode)); 489 status_t error = volume->Open(fsNode->private_node, openMode, cookie); 490 PRINT(("userlandfs_open() done: (%" B_PRIx32 ", %p)\n", error, *cookie)); 491 return error; 492} 493 494// userlandfs_close 495static status_t 496userlandfs_close(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 497{ 498 Volume* volume = (Volume*)fsVolume->private_volume; 499 PRINT(("userlandfs_close(%p, %p, %p)\n", volume, fsNode->private_node, 500 cookie)); 501 status_t error = volume->Close(fsNode->private_node, cookie); 502 PRINT(("userlandfs_close() done: %" B_PRIx32 "\n", error)); 503 return error; 504} 505 506// userlandfs_free_cookie 507static status_t 508userlandfs_free_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 509{ 510 Volume* volume = (Volume*)fsVolume->private_volume; 511 PRINT(("userlandfs_free_cookie(%p, %p, %p)\n", volume, fsNode->private_node, 512 cookie)); 513 status_t error = volume->FreeCookie(fsNode->private_node, cookie); 514 PRINT(("userlandfs_free_cookie() done: %" B_PRIx32 "\n", error)); 515 return error; 516} 517 518// userlandfs_read 519static status_t 520userlandfs_read(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, off_t pos, 521 void* buffer, size_t* length) 522{ 523 Volume* volume = (Volume*)fsVolume->private_volume; 524 PRINT(("userlandfs_read(%p, %p, %p, %" B_PRIdOFF ", %p, %" B_PRIuSIZE ")\n", 525 volume, fsNode->private_node, cookie, pos, buffer, *length)); 526 status_t error = volume->Read(fsNode->private_node, cookie, pos, buffer, 527 *length, length); 528 PRINT(("userlandfs_read() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", error, 529 *length)); 530 return error; 531} 532 533// userlandfs_write 534static status_t 535userlandfs_write(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, off_t pos, 536 const void* buffer, size_t* length) 537{ 538 Volume* volume = (Volume*)fsVolume->private_volume; 539 PRINT(("userlandfs_write(%p, %p, %p, %" B_PRIdOFF ", %p, %" B_PRIuSIZE 540 ")\n", volume, fsNode->private_node, cookie, pos, buffer, *length)); 541 status_t error = volume->Write(fsNode->private_node, cookie, pos, buffer, 542 *length, length); 543 PRINT(("userlandfs_write() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", error, 544 *length)); 545 return error; 546} 547 548 549// #pragma mark - directories 550 551 552// userlandfs_create_dir 553static status_t 554userlandfs_create_dir(fs_volume* fsVolume, fs_vnode* fsParent, const char* name, 555 int perms) 556{ 557 Volume* volume = (Volume*)fsVolume->private_volume; 558 PRINT(("userlandfs_create_dir(%p, %p, `%s', %#x)\n", volume, 559 fsParent->private_node, name, perms)); 560 status_t error = volume->CreateDir(fsParent->private_node, name, perms); 561 PRINT(("userlandfs_create_dir() done: (%" B_PRIx32 ")\n", error)); 562 return error; 563} 564 565// userlandfs_remove_dir 566static status_t 567userlandfs_remove_dir(fs_volume* fsVolume, fs_vnode* fsParent, const char* name) 568{ 569 Volume* volume = (Volume*)fsVolume->private_volume; 570 PRINT(("userlandfs_remove_dir(%p, %p, `%s')\n", volume, 571 fsParent->private_node, name)); 572 status_t error = volume->RemoveDir(fsParent->private_node, name); 573 PRINT(("userlandfs_remove_dir() done: (%" B_PRIx32 ")\n", error)); 574 return error; 575} 576 577// userlandfs_open_dir 578static status_t 579userlandfs_open_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** cookie) 580{ 581 Volume* volume = (Volume*)fsVolume->private_volume; 582 PRINT(("userlandfs_open_dir(%p, %p)\n", volume, fsNode->private_node)); 583 status_t error = volume->OpenDir(fsNode->private_node, cookie); 584 PRINT(("userlandfs_open_dir() done: (%" B_PRIx32 ", %p)\n", error, 585 *cookie)); 586 return error; 587} 588 589// userlandfs_close_dir 590static status_t 591userlandfs_close_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 592{ 593 Volume* volume = (Volume*)fsVolume->private_volume; 594 PRINT(("userlandfs_close_dir(%p, %p, %p)\n", volume, fsNode->private_node, 595 cookie)); 596 status_t error = volume->CloseDir(fsNode->private_node, cookie); 597 PRINT(("userlandfs_close_dir() done: %" B_PRIx32 "\n", error)); 598 return error; 599} 600 601// userlandfs_free_dir_cookie 602static status_t 603userlandfs_free_dir_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 604{ 605 Volume* volume = (Volume*)fsVolume->private_volume; 606 PRINT(("userlandfs_free_dir_cookie(%p, %p, %p)\n", volume, 607 fsNode->private_node, cookie)); 608 status_t error = volume->FreeDirCookie(fsNode->private_node, cookie); 609 PRINT(("userlandfs_free_dir_cookie() done: %" B_PRIx32 "\n", error)); 610 return error; 611} 612 613// userlandfs_read_dir 614static status_t 615userlandfs_read_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 616 struct dirent* buffer, size_t bufferSize, uint32* count) 617{ 618 Volume* volume = (Volume*)fsVolume->private_volume; 619 PRINT(("userlandfs_read_dir(%p, %p, %p, %p, %" B_PRIuSIZE ", %" B_PRIu32 620 ")\n", volume, fsNode->private_node, cookie, buffer, bufferSize, 621 *count)); 622 status_t error = volume->ReadDir(fsNode->private_node, cookie, buffer, 623 bufferSize, *count, count); 624 PRINT(("userlandfs_read_dir() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n", 625 error, *count)); 626 #if DEBUG 627 dirent* entry = buffer; 628 for (uint32 i = 0; error == B_OK && i < *count; i++) { 629 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 630 // we need to work around. 631 char name[B_FILE_NAME_LENGTH]; 632 int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); 633 strncpy(name, entry->d_name, nameLen); 634 name[nameLen] = '\0'; 635 PRINT((" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV 636 ", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO ", " 637 "d_reclen: %" B_PRIu16 ", d_name: `%s'\n", 638 entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino, 639 entry->d_reclen, name)); 640 entry = (dirent*)((char*)entry + entry->d_reclen); 641 } 642 #endif 643 return error; 644} 645 646// userlandfs_rewind_dir 647static status_t 648userlandfs_rewind_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 649{ 650 Volume* volume = (Volume*)fsVolume->private_volume; 651 PRINT(("userlandfs_rewind_dir(%p, %p, %p)\n", volume, fsNode->private_node, 652 cookie)); 653 status_t error = volume->RewindDir(fsNode->private_node, cookie); 654 PRINT(("userlandfs_rewind_dir() done: %" B_PRIx32 "\n", error)); 655 return error; 656} 657 658 659// #pragma mark - attribute directories 660 661 662// userlandfs_open_attr_dir 663static status_t 664userlandfs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** cookie) 665{ 666 Volume* volume = (Volume*)fsVolume->private_volume; 667 PRINT(("userlandfs_open_attr_dir(%p, %p)\n", volume, fsNode->private_node)); 668 status_t error = volume->OpenAttrDir(fsNode->private_node, cookie); 669 PRINT(("userlandfs_open_attr_dir() done: (%" B_PRIx32 ", %p)\n", error, 670 *cookie)); 671 return error; 672} 673 674// userlandfs_close_attr_dir 675static status_t 676userlandfs_close_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 677{ 678 Volume* volume = (Volume*)fsVolume->private_volume; 679 PRINT(("userlandfs_close_attr_dir(%p, %p, %p)\n", volume, 680 fsNode->private_node, cookie)); 681 status_t error = volume->CloseAttrDir(fsNode->private_node, cookie); 682 PRINT(("userlandfs_close_attr_dir() done: (%" B_PRIx32 ")\n", error)); 683 return error; 684} 685 686// userlandfs_free_attr_dir_cookie 687static status_t 688userlandfs_free_attr_dir_cookie(fs_volume* fsVolume, fs_vnode* fsNode, 689 void* cookie) 690{ 691 Volume* volume = (Volume*)fsVolume->private_volume; 692 PRINT(("userlandfs_free_attr_dir_cookie(%p, %p, %p)\n", volume, 693 fsNode->private_node, cookie)); 694 status_t error = volume->FreeAttrDirCookie(fsNode->private_node, cookie); 695 PRINT(("userlandfs_free_attr_dir_cookie() done: (%" B_PRIx32 ")\n", error)); 696 return error; 697} 698 699// userlandfs_read_attr_dir 700static status_t 701userlandfs_read_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 702 struct dirent* buffer, size_t bufferSize, uint32* count) 703{ 704 Volume* volume = (Volume*)fsVolume->private_volume; 705 PRINT(("userlandfs_read_attr_dir(%p, %p, %p, %p, %" B_PRIuSIZE ", %" 706 B_PRIu32 ")\n", volume, fsNode->private_node, cookie, buffer, 707 bufferSize, *count)); 708 status_t error = volume->ReadAttrDir(fsNode->private_node, cookie, buffer, 709 bufferSize, *count, count); 710 PRINT(("userlandfs_read_attr_dir() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n", 711 error, *count)); 712 return error; 713} 714 715// userlandfs_rewind_attr_dir 716static status_t 717userlandfs_rewind_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 718{ 719 Volume* volume = (Volume*)fsVolume->private_volume; 720 PRINT(("userlandfs_rewind_attr_dir(%p, %p, %p)\n", volume, 721 fsNode->private_node, cookie)); 722 status_t error = volume->RewindAttrDir(fsNode->private_node, cookie); 723 PRINT(("userlandfs_rewind_attr_dir() done: (%" B_PRIx32 ")\n", error)); 724 return error; 725} 726 727 728// #pragma mark - attributes 729 730 731// userlandfs_create_attr 732status_t 733userlandfs_create_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name, 734 uint32 type, int openMode, void** cookie) 735{ 736 Volume* volume = (Volume*)fsVolume->private_volume; 737 PRINT(("userlandfs_create_attr(%p, %p, \"%s\", 0x%" B_PRIx32 ", %d, %p)\n", 738 volume, fsNode->private_node, name, type, openMode, cookie)); 739 status_t error = volume->CreateAttr(fsNode->private_node, name, type, 740 openMode, cookie); 741 PRINT(("userlandfs_create_attr() done: (%" B_PRIx32 ", %p)\n", error, 742 *cookie)); 743 return error; 744} 745 746// userlandfs_open_attr 747status_t 748userlandfs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name, 749 int openMode, void** cookie) 750{ 751 Volume* volume = (Volume*)fsVolume->private_volume; 752 PRINT(("userlandfs_open_attr(%p, %p, \"%s\", %d, %p)\n", volume, 753 fsNode->private_node, name, openMode, cookie)); 754 status_t error = volume->OpenAttr(fsNode->private_node, name, openMode, 755 cookie); 756 PRINT(("userlandfs_open_attr() done: (%" B_PRIx32 ", %p)\n", error, 757 *cookie)); 758 return error; 759} 760 761// userlandfs_close_attr 762status_t 763userlandfs_close_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 764{ 765 Volume* volume = (Volume*)fsVolume->private_volume; 766 PRINT(("userlandfs_close_attr(%p, %p, %p)\n", volume, fsNode->private_node, 767 cookie)); 768 status_t error = volume->CloseAttr(fsNode->private_node, cookie); 769 PRINT(("userlandfs_close_attr() done: %" B_PRIx32 "\n", error)); 770 return error; 771} 772 773// userlandfs_free_attr_cookie 774status_t 775userlandfs_free_attr_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie) 776{ 777 Volume* volume = (Volume*)fsVolume->private_volume; 778 PRINT(("userlandfs_free_attr_cookie(%p, %p, %p)\n", volume, 779 fsNode->private_node, cookie)); 780 status_t error = volume->FreeAttrCookie(fsNode->private_node, cookie); 781 PRINT(("userlandfs_free_attr_cookie() done: %" B_PRIx32 "\n", error)); 782 return error; 783} 784 785// userlandfs_read_attr 786static status_t 787userlandfs_read_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 788 off_t pos, void* buffer, size_t* length) 789{ 790 Volume* volume = (Volume*)fsVolume->private_volume; 791 PRINT(("userlandfs_read_attr(%p, %p, %p, %" B_PRIdOFF ", %p, %" 792 B_PRIuSIZE ")\n", volume, fsNode->private_node, cookie, pos, buffer, 793 *length)); 794 status_t error = volume->ReadAttr(fsNode->private_node, cookie, pos, buffer, 795 *length, length); 796 PRINT(("userlandfs_read_attr() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", 797 error, *length)); 798 return error; 799} 800 801// userlandfs_write_attr 802static status_t 803userlandfs_write_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 804 off_t pos, const void* buffer, size_t* length) 805{ 806 Volume* volume = (Volume*)fsVolume->private_volume; 807 PRINT(("userlandfs_write_attr(%p, %p, %p, %" B_PRIdOFF ", %p, %" B_PRIuSIZE 808 ")\n", volume, fsNode->private_node, cookie, pos, buffer, *length)); 809 status_t error = volume->WriteAttr(fsNode->private_node, cookie, pos, 810 buffer, *length, length); 811 PRINT(("userlandfs_write_attr() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", 812 error, *length)); 813 return error; 814} 815 816// userlandfs_read_attr_stat 817static status_t 818userlandfs_read_attr_stat(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 819 struct stat* st) 820{ 821 Volume* volume = (Volume*)fsVolume->private_volume; 822 PRINT(("userlandfs_read_attr_stat(%p, %p, %p, %p)\n", volume, 823 fsNode->private_node, cookie, st)); 824 status_t error = volume->ReadAttrStat(fsNode->private_node, cookie, st); 825 PRINT(("userlandfs_read_attr_stat() done: (%" B_PRIx32 ")\n", error)); 826 return error; 827} 828 829// userlandfs_write_attr_stat 830static status_t 831userlandfs_write_attr_stat(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, 832 const struct stat* st, int statMask) 833{ 834 Volume* volume = (Volume*)fsVolume->private_volume; 835 PRINT(("userlandfs_write_attr_stat(%p, %p, %p, %p, 0x%x)\n", volume, 836 fsNode->private_node, cookie, st, statMask)); 837 status_t error = volume->WriteAttrStat(fsNode->private_node, cookie, st, 838 statMask); 839 PRINT(("userlandfs_write_attr_stat() done: (%" B_PRIx32 ")\n", error)); 840 return error; 841} 842 843// userlandfs_rename_attr 844static status_t 845userlandfs_rename_attr(fs_volume* fsVolume, fs_vnode* fsFromNode, 846 const char* fromName, fs_vnode* fsToNode, const char* toName) 847{ 848 Volume* volume = (Volume*)fsVolume->private_volume; 849 PRINT(("userlandfs_rename_attr(%p, %p, `%s', %p, `%s')\n", volume, 850 fsFromNode->private_node, fromName, fsToNode->private_node, toName)); 851 status_t error = volume->RenameAttr(fsFromNode->private_node, fromName, 852 fsToNode->private_node, toName); 853 PRINT(("userlandfs_rename_attr() done: (%" B_PRIx32 ")\n", error)); 854 return error; 855} 856 857// userlandfs_remove_attr 858static status_t 859userlandfs_remove_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name) 860{ 861 Volume* volume = (Volume*)fsVolume->private_volume; 862 PRINT(("userlandfs_remove_attr(%p, %p, `%s')\n", volume, 863 fsNode->private_node, name)); 864 status_t error = volume->RemoveAttr(fsNode->private_node, name); 865 PRINT(("userlandfs_remove_attr() done: (%" B_PRIx32 ")\n", error)); 866 return error; 867} 868 869 870// #pragma mark - indices 871 872 873// userlandfs_open_index_dir 874static status_t 875userlandfs_open_index_dir(fs_volume* fsVolume, void** cookie) 876{ 877 Volume* volume = (Volume*)fsVolume->private_volume; 878 PRINT(("userlandfs_open_index_dir(%p, %p)\n", volume, cookie)); 879 status_t error = volume->OpenIndexDir(cookie); 880 PRINT(("userlandfs_open_index_dir() done: (%" B_PRIx32 ", %p)\n", error, 881 *cookie)); 882 return error; 883} 884 885// userlandfs_close_index_dir 886static status_t 887userlandfs_close_index_dir(fs_volume* fsVolume, void* cookie) 888{ 889 Volume* volume = (Volume*)fsVolume->private_volume; 890 PRINT(("userlandfs_close_index_dir(%p, %p)\n", volume, cookie)); 891 status_t error = volume->CloseIndexDir(cookie); 892 PRINT(("userlandfs_close_index_dir() done: (%" B_PRIx32 ")\n", error)); 893 return error; 894} 895 896// userlandfs_free_index_dir_cookie 897static status_t 898userlandfs_free_index_dir_cookie(fs_volume* fsVolume, void* cookie) 899{ 900 Volume* volume = (Volume*)fsVolume->private_volume; 901 PRINT(("userlandfs_free_index_dir_cookie(%p, %p)\n", volume, cookie)); 902 status_t error = volume->FreeIndexDirCookie(cookie); 903 PRINT(("userlandfs_free_index_dir_cookie() done: (%" B_PRIx32 ")\n", 904 error)); 905 return error; 906} 907 908// userlandfs_read_index_dir 909static status_t 910userlandfs_read_index_dir(fs_volume* fsVolume, void* cookie, 911 struct dirent* buffer, size_t bufferSize, uint32* count) 912{ 913 Volume* volume = (Volume*)fsVolume->private_volume; 914 PRINT(("userlandfs_read_index_dir(%p, %p, %p, %" B_PRIuSIZE ", %" B_PRIu32 915 ")\n", volume, cookie, buffer, bufferSize, *count)); 916 status_t error = volume->ReadIndexDir(cookie, buffer, bufferSize, 917 *count, count); 918 PRINT(("userlandfs_read_index_dir() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n", 919 error, *count)); 920 return error; 921} 922 923// userlandfs_rewind_index_dir 924static status_t 925userlandfs_rewind_index_dir(fs_volume* fsVolume, void* cookie) 926{ 927 Volume* volume = (Volume*)fsVolume->private_volume; 928 PRINT(("userlandfs_rewind_index_dir(%p, %p)\n", volume, cookie)); 929 status_t error = volume->RewindIndexDir(cookie); 930 PRINT(("userlandfs_rewind_index_dir() done: (%" B_PRIx32 ")\n", error)); 931 return error; 932} 933 934// userlandfs_create_index 935static status_t 936userlandfs_create_index(fs_volume* fsVolume, const char* name, uint32 type, 937 uint32 flags) 938{ 939 Volume* volume = (Volume*)fsVolume->private_volume; 940 PRINT(("userlandfs_create_index(%p, `%s', 0x%" B_PRIx32 ", 0x%" B_PRIx32 941 ")\n", volume, name, type, flags)); 942 status_t error = volume->CreateIndex(name, type, flags); 943 PRINT(("userlandfs_create_index() done: (%" B_PRIx32 ")\n", error)); 944 return error; 945} 946 947// userlandfs_remove_index 948static status_t 949userlandfs_remove_index(fs_volume* fsVolume, const char* name) 950{ 951 Volume* volume = (Volume*)fsVolume->private_volume; 952 PRINT(("userlandfs_remove_index(%p, `%s')\n", volume, name)); 953 status_t error = volume->RemoveIndex(name); 954 PRINT(("userlandfs_remove_index() done: (%" B_PRIx32 ")\n", error)); 955 return error; 956} 957 958// userlandfs_read_index_stat 959static status_t 960userlandfs_read_index_stat(fs_volume* fsVolume, const char* name, 961 struct stat* st) 962{ 963 Volume* volume = (Volume*)fsVolume->private_volume; 964 PRINT(("userlandfs_read_index_stat(%p, `%s', %p)\n", volume, name, st)); 965 status_t error = volume->ReadIndexStat(name, st); 966 PRINT(("userlandfs_read_index_stat() done: (%" B_PRIx32 ")\n", error)); 967 return error; 968} 969 970 971// #pragma mark - queries 972 973 974// userlandfs_open_query 975static status_t 976userlandfs_open_query(fs_volume* fsVolume, const char *queryString, 977 uint32 flags, port_id port, uint32 token, void** cookie) 978{ 979 Volume* volume = (Volume*)fsVolume->private_volume; 980 PRINT(("userlandfs_open_query(%p, `%s', %" B_PRIu32 ", %" B_PRId32 ", %" 981 B_PRIu32 ", %p)\n", volume, queryString, flags, port, token, cookie)); 982 status_t error = volume->OpenQuery(queryString, flags, port, token, cookie); 983 PRINT(("userlandfs_open_query() done: (%" B_PRIx32 ", %p)\n", error, 984 *cookie)); 985 return error; 986} 987 988// userlandfs_close_query 989static status_t 990userlandfs_close_query(fs_volume* fsVolume, void* cookie) 991{ 992 Volume* volume = (Volume*)fsVolume->private_volume; 993 PRINT(("userlandfs_close_query(%p, %p)\n", volume, cookie)); 994 status_t error = volume->CloseQuery(cookie); 995 PRINT(("userlandfs_close_query() done: (%" B_PRIx32 ")\n", error)); 996 return error; 997} 998 999// userlandfs_free_query_cookie 1000static status_t 1001userlandfs_free_query_cookie(fs_volume* fsVolume, void* cookie) 1002{ 1003 Volume* volume = (Volume*)fsVolume->private_volume; 1004 PRINT(("userlandfs_free_query_cookie(%p, %p)\n", volume, cookie)); 1005 status_t error = volume->FreeQueryCookie(cookie); 1006 PRINT(("userlandfs_free_query_cookie() done: (%" B_PRIx32 ")\n", error)); 1007 return error; 1008} 1009 1010// userlandfs_read_query 1011static status_t 1012userlandfs_read_query(fs_volume* fsVolume, void* cookie, 1013 struct dirent* buffer, size_t bufferSize, uint32* count) 1014{ 1015 Volume* volume = (Volume*)fsVolume->private_volume; 1016 PRINT(("userlandfs_read_query(%p, %p, %p, %" B_PRIuSIZE ", %" B_PRIu32 1017 ")\n", volume, cookie, buffer, bufferSize, *count)); 1018 status_t error = volume->ReadQuery(cookie, buffer, bufferSize, *count, 1019 count); 1020 PRINT(("userlandfs_read_query() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n", 1021 error, *count)); 1022 #if DEBUG 1023 if (error == B_OK && *count > 0) { 1024 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 1025 // we need to work around. 1026 char name[B_FILE_NAME_LENGTH]; 1027 int nameLen = strnlen(buffer->d_name, B_FILE_NAME_LENGTH - 1); 1028 strncpy(name, buffer->d_name, nameLen); 1029 name[nameLen] = '\0'; 1030 PRINT((" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV 1031 ", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO ", d_reclen: %" 1032 B_PRIu16 ", d_name: `%s'\n", buffer->d_dev, buffer->d_pdev, 1033 buffer->d_ino, buffer->d_pino, buffer->d_reclen, name)); 1034 } 1035 #endif 1036 return error; 1037} 1038 1039// userlandfs_rewind_query 1040static status_t 1041userlandfs_rewind_query(fs_volume* fsVolume, void* cookie) 1042{ 1043 Volume* volume = (Volume*)fsVolume->private_volume; 1044 PRINT(("userlandfs_rewind_query(%p, %p)\n", volume, cookie)); 1045 status_t error = volume->RewindQuery(cookie); 1046 PRINT(("userlandfs_rewind_query() done: (%" B_PRIx32 ")\n", error)); 1047 return error; 1048} 1049 1050 1051// userlandfs_initialize 1052/* 1053static status_t 1054userlandfs_initialize(const char *deviceName, void *parameters, 1055 size_t len) 1056{ 1057 // get the parameters 1058 String fsName; 1059 const char* fsParameters; 1060 int32 fsParameterLength; 1061 status_t error = parse_parameters(parameters, len, fsName, &fsParameters, 1062 &fsParameterLength); 1063 // make sure there is a UserlandFS we can work with 1064 UserlandFS* userlandFS = NULL; 1065 error = UserlandFS::RegisterUserlandFS(&userlandFS); 1066 if (error != B_OK) { 1067 exit_debugging(); 1068 return error; 1069 } 1070 // get the file system 1071 FileSystem* fileSystem = NULL; 1072 if (error == B_OK) 1073 error = userlandFS->RegisterFileSystem(fsName.GetString(), &fileSystem); 1074 // initialize the volume 1075 if (error == B_OK) { 1076 error = fileSystem->Initialize(deviceName, fsParameters, 1077 fsParameterLength); 1078 } 1079 // cleanup 1080 if (fileSystem) 1081 userlandFS->UnregisterFileSystem(fileSystem); 1082 UserlandFS::UnregisterUserlandFS(); 1083 return error; 1084}*/ 1085 1086 1087 1088// #pragma mark ----- module ----- 1089 1090 1091static status_t 1092userlandfs_std_ops(int32 op, ...) 1093{ 1094 switch (op) { 1095 case B_MODULE_INIT: 1096 { 1097 init_debugging(); 1098 PRINT(("userlandfs_std_ops(): B_MODULE_INIT\n")); 1099 1100 // make sure there is a UserlandFS we can work with 1101 UserlandFS* userlandFS = NULL; 1102 status_t error = UserlandFS::InitUserlandFS(&userlandFS); 1103 if (error != B_OK) { 1104 exit_debugging(); 1105 return error; 1106 } 1107 1108 return B_OK; 1109 } 1110 1111 case B_MODULE_UNINIT: 1112 PRINT(("userlandfs_std_ops(): B_MODULE_UNINIT\n")); 1113 UserlandFS::UninitUserlandFS(); 1114 exit_debugging(); 1115 return B_OK; 1116 1117 default: 1118 return B_ERROR; 1119 } 1120} 1121 1122 1123static file_system_module_info sUserlandFSModuleInfo = { 1124 { 1125 "file_systems/userlandfs" B_CURRENT_FS_API_VERSION, 1126 0, 1127 userlandfs_std_ops, 1128 }, 1129 1130 "userlandfs", // short name 1131 "Userland File System", // pretty name 1132 0, // DDM flags 1133 1134 // scanning 1135 NULL, // identify_partition() 1136 NULL, // scan_partition() 1137 NULL, // free_identify_partition_cookie() 1138 NULL, // free_partition_content_cookie() 1139 1140 // general operations 1141 &userlandfs_mount, 1142 1143 // capability querying 1144 NULL, // get_supported_operations() 1145 NULL, // validate_resize() 1146 NULL, // validate_move() 1147 NULL, // validate_set_content_name() 1148 NULL, // validate_set_content_parameters() 1149 NULL, // validate_initialize() 1150 1151 // shadow partition modification 1152 NULL, // shadow_changed() 1153 1154 // writing 1155 NULL, // defragment() 1156 NULL, // repair() 1157 NULL, // resize() 1158 NULL, // move() 1159 NULL, // set_content_name() 1160 NULL, // set_content_parameters() 1161 NULL // initialize() 1162}; 1163 1164 1165fs_volume_ops gUserlandFSVolumeOps = { 1166 // general operations 1167 &userlandfs_unmount, 1168 &userlandfs_read_fs_info, 1169 &userlandfs_write_fs_info, 1170 &userlandfs_sync, 1171 1172 &userlandfs_get_vnode, 1173 1174 // index directory & index operations 1175 &userlandfs_open_index_dir, 1176 &userlandfs_close_index_dir, 1177 &userlandfs_free_index_dir_cookie, 1178 &userlandfs_read_index_dir, 1179 &userlandfs_rewind_index_dir, 1180 1181 &userlandfs_create_index, 1182 &userlandfs_remove_index, 1183 &userlandfs_read_index_stat, 1184 1185 // query operations 1186 &userlandfs_open_query, 1187 &userlandfs_close_query, 1188 &userlandfs_free_query_cookie, 1189 &userlandfs_read_query, 1190 &userlandfs_rewind_query, 1191 1192 /* support for FS layers */ 1193 NULL, // all_layers_mounted() 1194 NULL, // create_sub_vnode() 1195 NULL // delete_sub_vnode() 1196}; 1197 1198 1199fs_vnode_ops gUserlandFSVnodeOps = { 1200 // vnode operations 1201 &userlandfs_lookup, 1202 &userlandfs_get_vnode_name, 1203 &userlandfs_put_vnode, 1204 &userlandfs_remove_vnode, 1205 1206 // VM file access 1207 NULL, // can_page() -- obsolete 1208 NULL, // read_pages() -- obsolete 1209 NULL, // write_pages() -- obsolete 1210 1211 // asynchronous I/O 1212 &userlandfs_io, 1213 &userlandfs_cancel_io, 1214 1215 // cache file access 1216 NULL, // get_file_map() -- not needed 1217 1218 // common operations 1219 &userlandfs_ioctl, 1220 &userlandfs_set_flags, 1221 &userlandfs_select, 1222 &userlandfs_deselect, 1223 &userlandfs_fsync, 1224 1225 &userlandfs_read_symlink, 1226 &userlandfs_create_symlink, 1227 1228 &userlandfs_link, 1229 &userlandfs_unlink, 1230 &userlandfs_rename, 1231 1232 &userlandfs_access, 1233 &userlandfs_read_stat, 1234 &userlandfs_write_stat, 1235 NULL, // preallocate() 1236 1237 // file operations 1238 &userlandfs_create, 1239 &userlandfs_open, 1240 &userlandfs_close, 1241 &userlandfs_free_cookie, 1242 &userlandfs_read, 1243 &userlandfs_write, 1244 1245 // directory operations 1246 &userlandfs_create_dir, 1247 &userlandfs_remove_dir, 1248 &userlandfs_open_dir, 1249 &userlandfs_close_dir, 1250 &userlandfs_free_dir_cookie, 1251 &userlandfs_read_dir, 1252 &userlandfs_rewind_dir, 1253 1254 // attribute directory operations 1255 &userlandfs_open_attr_dir, 1256 &userlandfs_close_attr_dir, 1257 &userlandfs_free_attr_dir_cookie, 1258 &userlandfs_read_attr_dir, 1259 &userlandfs_rewind_attr_dir, 1260 1261 // attribute operations 1262 &userlandfs_create_attr, 1263 &userlandfs_open_attr, 1264 &userlandfs_close_attr, 1265 &userlandfs_free_attr_cookie, 1266 &userlandfs_read_attr, 1267 &userlandfs_write_attr, 1268 1269 &userlandfs_read_attr_stat, 1270 &userlandfs_write_attr_stat, 1271 &userlandfs_rename_attr, 1272 &userlandfs_remove_attr, 1273 1274 // support for node and FS layers 1275 NULL, // create_special_node() 1276 NULL // get_super_vnode() 1277}; 1278 1279 1280module_info *modules[] = { 1281 (module_info *)&sUserlandFSModuleInfo, 1282 NULL, 1283}; 1284