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