1// netfs.cpp 2 3#include <new> 4 5#include <KernelExport.h> 6#include <fsproto.h> 7 8#include "DebugSupport.h" 9#include "Node.h" 10#include "ObjectTracker.h" 11#include "QueryManager.h" 12#include "RootVolume.h" 13#include "VolumeManager.h" 14 15// #pragma mark - 16// #pragma mark ----- prototypes ----- 17 18extern "C" { 19 20// fs 21static int netfs_mount(nspace_id nsid, const char *device, ulong flags, 22 void *parameters, size_t len, void **data, vnode_id *rootID); 23static int netfs_unmount(void *ns); 24//static int netfs_sync(void *ns); 25static int netfs_read_fs_stat(void *ns, struct fs_info *info); 26//static int netfs_write_fs_stat(void *ns, struct fs_info *info, long mask); 27 28// vnodes 29static int netfs_read_vnode(void *ns, vnode_id vnid, char reenter, 30 void **node); 31static int netfs_write_vnode(void *ns, void *node, char reenter); 32static int netfs_remove_vnode(void *ns, void *node, char reenter); 33 34// nodes 35//static int netfs_fsync(void *ns, void *node); 36static int netfs_read_stat(void *ns, void *node, struct stat *st); 37static int netfs_write_stat(void *ns, void *node, struct stat *st, 38 long mask); 39static int netfs_access(void *ns, void *node, int mode); 40 41// files 42static int netfs_create(void *ns, void *dir, const char *name, 43 int openMode, int mode, vnode_id *vnid, void **cookie); 44static int netfs_open(void *ns, void *node, int openMode, void **cookie); 45static int netfs_close(void *ns, void *node, void *cookie); 46static int netfs_free_cookie(void *ns, void *node, void *cookie); 47static int netfs_read(void *ns, void *node, void *cookie, off_t pos, 48 void *buffer, size_t *bufferSize); 49static int netfs_write(void *ns, void *node, void *cookie, off_t pos, 50 const void *buffer, size_t *bufferSize); 51static int netfs_ioctl(void *ns, void *node, void *cookie, int cmd, 52 void *buffer, size_t bufferSize); 53//static int netfs_setflags(void *ns, void *node, void *cookie, int flags); 54 55// hard links / symlinks 56static int netfs_link(void *ns, void *dir, const char *name, void *node); 57static int netfs_unlink(void *ns, void *dir, const char *name); 58static int netfs_symlink(void *ns, void *dir, const char *name, 59 const char *path); 60static int netfs_read_link(void *ns, void *node, char *buffer, 61 size_t *bufferSize); 62static int netfs_rename(void *ns, void *oldDir, const char *oldName, 63 void *newDir, const char *newName); 64 65// directories 66static int netfs_mkdir(void *ns, void *dir, const char *name, int mode); 67static int netfs_rmdir(void *ns, void *dir, const char *name); 68static int netfs_open_dir(void *ns, void *node, void **cookie); 69static int netfs_close_dir(void *ns, void *node, void *cookie); 70static int netfs_free_dir_cookie(void *ns, void *node, void *cookie); 71static int netfs_read_dir(void *ns, void *node, void *cookie, 72 long *count, struct dirent *buffer, size_t bufferSize); 73static int netfs_rewind_dir(void *ns, void *node, void *cookie); 74static int netfs_walk(void *ns, void *dir, const char *entryName, 75 char **resolvedPath, vnode_id *vnid); 76 77// attributes 78static int netfs_open_attrdir(void *ns, void *node, void **cookie); 79static int netfs_close_attrdir(void *ns, void *node, void *cookie); 80static int netfs_free_attrdir_cookie(void *ns, void *node, void *cookie); 81static int netfs_read_attrdir(void *ns, void *node, void *cookie, 82 long *count, struct dirent *buffer, size_t bufferSize); 83static int netfs_read_attr(void *ns, void *node, const char *name, 84 int type, void *buffer, size_t *bufferSize, off_t pos); 85static int netfs_rewind_attrdir(void *ns, void *node, void *cookie); 86static int netfs_write_attr(void *ns, void *node, const char *name, 87 int type, const void *buffer, size_t *bufferSize, off_t pos); 88static int netfs_remove_attr(void *ns, void *node, const char *name); 89static int netfs_rename_attr(void *ns, void *node, const char *oldName, 90 const char *newName); 91static int netfs_stat_attr(void *ns, void *node, const char *name, 92 struct attr_info *attrInfo); 93 94// queries 95static int netfs_open_query(void *ns, const char *queryString, ulong flags, 96 port_id port, long token, void **cookie); 97static int netfs_close_query(void *ns, void *cookie); 98static int netfs_free_query_cookie(void *ns, void *node, void *cookie); 99static int netfs_read_query(void *ns, void *cookie, long *count, 100 struct dirent *buffer, size_t bufferSize); 101 102} // extern "C" 103 104/* vnode_ops struct. Fill this in to tell the kernel how to call 105 functions in your driver. 106*/ 107vnode_ops fs_entry = { 108 &netfs_read_vnode, // read_vnode 109 &netfs_write_vnode, // write_vnode 110 &netfs_remove_vnode, // remove_vnode 111 NULL, // secure_vnode (not needed) 112 &netfs_walk, // walk 113 &netfs_access, // access 114 &netfs_create, // create 115 &netfs_mkdir, // mkdir 116 &netfs_symlink, // symlink 117 &netfs_link, // link 118 &netfs_rename, // rename 119 &netfs_unlink, // unlink 120 &netfs_rmdir, // rmdir 121 &netfs_read_link, // readlink 122 &netfs_open_dir, // opendir 123 &netfs_close_dir, // closedir 124 &netfs_free_dir_cookie, // free_dircookie 125 &netfs_rewind_dir, // rewinddir 126 &netfs_read_dir, // readdir 127 &netfs_open, // open file 128 &netfs_close, // close file 129 &netfs_free_cookie, // free cookie 130 &netfs_read, // read file 131 &netfs_write, // write file 132 NULL, // readv 133 NULL, // writev 134 &netfs_ioctl, // ioctl 135 NULL, // setflags file 136 &netfs_read_stat, // read stat 137 &netfs_write_stat, // write stat 138 NULL, // fsync 139 NULL, // initialize 140 &netfs_mount, // mount 141 &netfs_unmount, // unmount 142 NULL, // sync 143 &netfs_read_fs_stat, // read fs stat 144 NULL, // write fs stat 145 NULL, // select 146 NULL, // deselect 147 148 NULL, // open index dir 149 NULL, // close index dir 150 NULL, // free index dir cookie 151 NULL, // rewind index dir 152 NULL, // read index dir 153 NULL, // create index 154 NULL, // remove index 155 NULL, // rename index 156 NULL, // stat index 157 158 &netfs_open_attrdir, // open attr dir 159 &netfs_close_attrdir, // close attr dir 160 &netfs_free_attrdir_cookie, // free attr dir cookie 161 &netfs_rewind_attrdir, // rewind attr dir 162 &netfs_read_attrdir, // read attr dir 163 &netfs_write_attr, // write attr 164 &netfs_read_attr, // read attr 165 &netfs_remove_attr, // remove attr 166 &netfs_rename_attr, // rename attr 167 &netfs_stat_attr, // stat attr 168 169 &netfs_open_query, // open query 170 &netfs_close_query, // close query 171 &netfs_free_query_cookie, // free query cookie 172 &netfs_read_query, // read query 173}; 174 175int32 api_version = B_CUR_FS_API_VERSION; 176 177// #pragma mark - 178// #pragma mark ----- fs ----- 179 180// netfs_mount 181static 182int 183netfs_mount(nspace_id nsid, const char *device, ulong flags, 184 void *parameters, size_t len, void **data, vnode_id *rootID) 185{ 186 status_t error = B_OK; 187 init_debugging(); 188 189 #ifdef DEBUG_OBJECT_TRACKING 190 ObjectTracker::InitDefault(); 191 #endif 192 193 // create and init the volume manager 194 VolumeManager* volumeManager = new(std::nothrow) VolumeManager(nsid, flags); 195 Volume* rootVolume = NULL; 196 if (volumeManager) { 197 error = volumeManager->MountRootVolume(device, 198 (const char*)parameters, len, &rootVolume); 199 if (error != B_OK) { 200 delete volumeManager; 201 volumeManager = NULL; 202 } 203 } else 204 error = B_NO_MEMORY; 205 VolumePutter _(rootVolume); 206 207 // set results 208 if (error == B_OK) { 209 *data = volumeManager; 210 *rootID = rootVolume->GetRootID(); 211 } else { 212 #ifdef DEBUG_OBJECT_TRACKING 213 ObjectTracker::ExitDefault(); 214 #endif 215 exit_debugging(); 216 } 217 return error; 218} 219 220// netfs_unmount 221static 222int 223netfs_unmount(void *ns) 224{ 225 VolumeManager* volumeManager = (VolumeManager*)ns; 226 227 PRINT("netfs_unmount()\n"); 228 229 volumeManager->UnmountRootVolume(); 230 delete volumeManager; 231 232 #ifdef DEBUG_OBJECT_TRACKING 233 ObjectTracker::ExitDefault(); 234 #endif 235 236 PRINT("netfs_unmount() done\n"); 237 238 exit_debugging(); 239 return B_OK; 240} 241 242#if 0 // not used 243 244// netfs_sync 245static 246int 247netfs_sync(void *ns) 248{ 249 VolumeManager* volumeManager = (VolumeManager*)ns; 250 Volume* volume = volumeManager->GetRootVolume(); 251 VolumePutter _(volume); 252 253 PRINT("netfs_sync(%p)\n", ns); 254 255 status_t error = B_BAD_VALUE; 256 if (volume) 257 error = volume->Sync(); 258 259 PRINT("netfs_sync() done: %lx \n", error); 260 261 return error; 262} 263 264#endif 265 266// netfs_read_fs_stat 267static 268int 269netfs_read_fs_stat(void *ns, struct fs_info *info) 270{ 271 VolumeManager* volumeManager = (VolumeManager*)ns; 272 Volume* volume = volumeManager->GetRootVolume(); 273 VolumePutter _(volume); 274 275 PRINT("netfs_read_fs_stat(%p, %p)\n", ns, info); 276 277 status_t error = B_BAD_VALUE; 278 if (volume) 279 error = volume->ReadFSStat(info); 280 281 PRINT("netfs_read_fs_stat() done: %lx \n", error); 282 283 return error; 284} 285 286#if 0 // not used 287 288// netfs_write_fs_stat 289static 290int 291netfs_write_fs_stat(void *ns, struct fs_info *info, long mask) 292{ 293 VolumeManager* volumeManager = (VolumeManager*)ns; 294 Volume* volume = volumeManager->GetRootVolume(); 295 VolumePutter _(volume); 296 297 PRINT("netfs_write_fs_stat(%p, %p, %ld)\n", ns, info, mask); 298 299 status_t error = B_BAD_VALUE; 300 if (volume) 301 error = volume->WriteFSStat(info, mask); 302 303 PRINT("netfs_write_fs_stat() done: %lx \n", error); 304 305 return error; 306} 307 308#endif 309 310// #pragma mark - 311// #pragma mark ----- vnodes ----- 312 313// netfs_read_vnode 314static 315int 316netfs_read_vnode(void *ns, vnode_id vnid, char reenter, void **node) 317{ 318 VolumeManager* volumeManager = (VolumeManager*)ns; 319 Volume* volume = volumeManager->GetVolume(vnid); 320 VolumePutter _(volume); 321 322 PRINT("netfs_read_vnode(%p, %Ld, %d, %p)\n", ns, vnid, reenter, node); 323 324 status_t error = B_BAD_VALUE; 325 if (volume) 326 error = volume->ReadVNode(vnid, reenter, (Node**)node); 327 328 PRINT("netfs_read_vnode() done: (%lx, %p)\n", error, *node); 329 330 return error; 331} 332 333// netfs_write_vnode 334static 335int 336netfs_write_vnode(void *ns, void *_node, char reenter) 337{ 338 Node* node = (Node*)_node; 339// DANGER: If dbg_printf() is used, this thread will enter another FS and 340// even perform a write operation. The is dangerous here, since this hook 341// may be called out of the other FSs, since, for instance a put_vnode() 342// called from another FS may cause the VFS layer to free vnodes and thus 343// invoke this hook. 344// PRINT(("netfs_write_vnode(%p, %p, %d)\n", ns, node, reenter)); 345 status_t error = node->GetVolume()->WriteVNode(node, reenter); 346// PRINT(("netfs_write_vnode() done: %lx\n", error)); 347 return error; 348} 349 350// netfs_remove_vnode 351static 352int 353netfs_remove_vnode(void *ns, void *_node, char reenter) 354{ 355 Node* node = (Node*)_node; 356// DANGER: See netfs_write_vnode(). 357// PRINT(("netfs_remove_vnode(%p, %p, %d)\n", ns, node, reenter)); 358 status_t error = node->GetVolume()->RemoveVNode(node, reenter); 359// PRINT(("netfs_remove_vnode() done: %lx\n", error)); 360 return error; 361} 362 363// #pragma mark - 364// #pragma mark ----- nodes ----- 365 366#if 0 // not used 367 368// netfs_fsync 369static 370int 371netfs_fsync(void *ns, void *_node) 372{ 373 Node* node = (Node*)_node; 374 PRINT("netfs_fsync(%p, %p)\n", ns, node); 375 status_t error = node->GetVolume()->FSync(node); 376 PRINT("netfs_fsync() done: %lx\n", error); 377 return error; 378} 379 380#endif 381 382// netfs_read_stat 383static 384int 385netfs_read_stat(void *ns, void *_node, struct stat *st) 386{ 387 Node* node = (Node*)_node; 388 PRINT("netfs_read_stat(%p, %p, %p)\n", ns, node, st); 389 status_t error = node->GetVolume()->ReadStat(node, st); 390 PRINT("netfs_read_stat() done: %lx\n", error); 391 return error; 392} 393 394// netfs_write_stat 395static 396int 397netfs_write_stat(void *ns, void *_node, struct stat *st, long mask) 398{ 399 Node* node = (Node*)_node; 400 PRINT("netfs_write_stat(%p, %p, %p, %ld)\n", ns, node, st, mask); 401 status_t error = node->GetVolume()->WriteStat(node, st, mask); 402 PRINT("netfs_write_stat() done: %lx\n", error); 403 return error; 404} 405 406// netfs_access 407static 408int 409netfs_access(void *ns, void *_node, int mode) 410{ 411 Node* node = (Node*)_node; 412 PRINT("netfs_access(%p, %p, %d)\n", ns, node, mode); 413 status_t error = node->GetVolume()->Access(node, mode); 414 PRINT("netfs_access() done: %lx\n", error); 415 return error; 416} 417 418// #pragma mark - 419// #pragma mark ----- files ----- 420 421// netfs_create 422static 423int 424netfs_create(void *ns, void *_dir, const char *name, int openMode, int mode, 425 vnode_id *vnid, void **cookie) 426{ 427 Node* dir = (Node*)_dir; 428 PRINT("netfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", ns, dir, 429 name, openMode, mode, vnid, cookie); 430 status_t error = dir->GetVolume()->Create(dir, name, openMode, mode, vnid, 431 cookie); 432 PRINT("netfs_create() done: (%lx, %Ld, %p)\n", error, *vnid, 433 *cookie); 434 return error; 435} 436 437// netfs_open 438static 439int 440netfs_open(void *ns, void *_node, int openMode, void **cookie) 441{ 442 Node* node = (Node*)_node; 443 PRINT("netfs_open(%p, %p, %d)\n", ns, node, openMode); 444 status_t error = node->GetVolume()->Open(node, openMode, cookie); 445 PRINT("netfs_open() done: (%lx, %p)\n", error, *cookie); 446 return error; 447} 448 449// netfs_close 450static 451int 452netfs_close(void *ns, void *_node, void *cookie) 453{ 454 Node* node = (Node*)_node; 455 PRINT("netfs_close(%p, %p, %p)\n", ns, node, cookie); 456 status_t error = node->GetVolume()->Close(node, cookie); 457 PRINT("netfs_close() done: %lx\n", error); 458 return error; 459} 460 461// netfs_free_cookie 462static 463int 464netfs_free_cookie(void *ns, void *_node, void *cookie) 465{ 466 Node* node = (Node*)_node; 467 PRINT("netfs_free_cookie(%p, %p, %p)\n", ns, node, cookie); 468 status_t error = node->GetVolume()->FreeCookie(node, cookie); 469 PRINT("netfs_free_cookie() done: %lx\n", error); 470 return error; 471} 472 473// netfs_read 474static 475int 476netfs_read(void *ns, void *_node, void *cookie, off_t pos, void *buffer, 477 size_t *bufferSize) 478{ 479 Node* node = (Node*)_node; 480 PRINT("netfs_read(%p, %p, %p, %Ld, %p, %lu)\n", ns, node, cookie, pos, 481 buffer, *bufferSize); 482 status_t error = node->GetVolume()->Read(node, cookie, pos, buffer, 483 *bufferSize, bufferSize); 484 PRINT("netfs_read() done: (%lx, %lu)\n", error, *bufferSize); 485 return error; 486} 487 488// netfs_write 489static 490int 491netfs_write(void *ns, void *_node, void *cookie, off_t pos, 492 const void *buffer, size_t *bufferSize) 493{ 494 Node* node = (Node*)_node; 495 PRINT("netfs_write(%p, %p, %p, %Ld, %p, %lu)\n", ns, node, cookie, pos, 496 buffer, *bufferSize); 497 status_t error = node->GetVolume()->Write(node, cookie, pos, buffer, 498 *bufferSize, bufferSize); 499 PRINT("netfs_write() done: (%lx, %lu)\n", error, *bufferSize); 500 return error; 501} 502 503// netfs_ioctl 504static 505int 506netfs_ioctl(void *ns, void *_node, void *cookie, int cmd, void *buffer, 507 size_t bufferSize) 508{ 509 Node* node = (Node*)_node; 510 PRINT("netfs_ioctl(%p, %p, %p, %d, %p, %lu)\n", ns, node, cookie, cmd, 511 buffer, bufferSize); 512 status_t error = node->GetVolume()->IOCtl(node, cookie, cmd, buffer, 513 bufferSize); 514 PRINT("netfs_ioctl() done: (%lx)\n", error); 515 return error; 516} 517 518// netfs_setflags 519//static 520//int 521//netfs_setflags(void *ns, void *_node, void *cookie, int flags) 522//{ 523// Node* node = (Node*)_node; 524// PRINT(("netfs_setflags(%p, %p, %p, %d)\n", ns, node, cookie, flags)); 525// status_t error = node->GetVolume()->SetFlags(node, cookie, flags); 526// PRINT(("netfs_setflags() done: (%lx)\n", error)); 527// return error; 528//} 529 530// #pragma mark - 531// #pragma mark ----- hard links / symlinks ----- 532 533// netfs_link 534static 535int 536netfs_link(void *ns, void *_dir, const char *name, void *_node) 537{ 538 Node* dir = (Node*)_dir; 539 Node* node = (Node*)_node; 540 PRINT("netfs_link(%p, %p, `%s', %p)\n", ns, dir, name, node); 541 status_t error = dir->GetVolume()->Link(dir, name, node); 542 PRINT("netfs_link() done: (%lx)\n", error); 543 return error; 544} 545 546// netfs_unlink 547static 548int 549netfs_unlink(void *ns, void *_dir, const char *name) 550{ 551 Node* dir = (Node*)_dir; 552 PRINT("netfs_unlink(%p, %p, `%s')\n", ns, dir, name); 553 status_t error = dir->GetVolume()->Unlink(dir, name); 554 PRINT("netfs_unlink() done: (%lx)\n", error); 555 return error; 556} 557 558// netfs_symlink 559static 560int 561netfs_symlink(void *ns, void *_dir, const char *name, const char *path) 562{ 563 Node* dir = (Node*)_dir; 564 PRINT("netfs_symlink(%p, %p, `%s', `%s')\n", ns, dir, name, path); 565 status_t error = dir->GetVolume()->Symlink(dir, name, path); 566 PRINT("netfs_symlink() done: (%lx)\n", error); 567 return error; 568} 569 570// netfs_read_link 571static 572int 573netfs_read_link(void *ns, void *_node, char *buffer, size_t *bufferSize) 574{ 575 Node* node = (Node*)_node; 576 PRINT("netfs_read_link(%p, %p, %p, %lu)\n", ns, node, buffer, 577 *bufferSize); 578 status_t error = node->GetVolume()->ReadLink(node, buffer, *bufferSize, 579 bufferSize); 580 PRINT("netfs_read_link() done: (%lx, %lu)\n", error, *bufferSize); 581 return error; 582} 583 584// netfs_rename 585static 586int 587netfs_rename(void *ns, void *_oldDir, const char *oldName, void *_newDir, 588 const char *newName) 589{ 590 Node* oldDir = (Node*)_oldDir; 591 Node* newDir = (Node*)_newDir; 592 PRINT("netfs_rename(%p, %p, `%s', %p, `%s')\n", ns, oldDir, oldName, 593 newDir, newName); 594 status_t error = oldDir->GetVolume()->Rename(oldDir, oldName, 595 newDir, newName); 596 PRINT("netfs_rename() done: (%lx)\n", error); 597 return error; 598} 599 600// #pragma mark - 601// #pragma mark ----- directories ----- 602 603// netfs_mkdir 604static 605int 606netfs_mkdir(void *ns, void *_dir, const char *name, int mode) 607{ 608 Node* dir = (Node*)_dir; 609 PRINT("netfs_mkdir(%p, %p, `%s', %d)\n", ns, dir, name, mode); 610 status_t error = dir->GetVolume()->MkDir(dir, name, mode); 611 PRINT("netfs_mkdir() done: (%lx)\n", error); 612 return error; 613} 614 615// netfs_rmdir 616static 617int 618netfs_rmdir(void *ns, void *_dir, const char *name) 619{ 620 Node* dir = (Node*)_dir; 621 PRINT("netfs_rmdir(%p, %p, `%s')\n", ns, dir, name); 622 status_t error = dir->GetVolume()->RmDir(dir, name); 623 PRINT("netfs_rmdir() done: (%lx)\n", error); 624 return error; 625} 626 627// netfs_open_dir 628static 629int 630netfs_open_dir(void *ns, void *_node, void **cookie) 631{ 632 Node* node = (Node*)_node; 633 PRINT("netfs_open_dir(%p, %p)\n", ns, node); 634 status_t error = node->GetVolume()->OpenDir(node, cookie); 635 PRINT("netfs_open_dir() done: (%lx, %p)\n", error, *cookie); 636 return error; 637} 638 639// netfs_close_dir 640static 641int 642netfs_close_dir(void *ns, void *_node, void *cookie) 643{ 644 Node* node = (Node*)_node; 645 PRINT("netfs_close_dir(%p, %p, %p)\n", ns, node, cookie); 646 status_t error = node->GetVolume()->CloseDir(node, cookie); 647 PRINT("netfs_close_dir() done: %lx\n", error); 648 return error; 649} 650 651// netfs_free_dir_cookie 652static 653int 654netfs_free_dir_cookie(void *ns, void *_node, void *cookie) 655{ 656 Node* node = (Node*)_node; 657 PRINT("netfs_free_dir_cookie(%p, %p, %p)\n", ns, node, cookie); 658 status_t error = node->GetVolume()->FreeDirCookie(node, cookie); 659 PRINT("netfs_free_dir_cookie() done: %lx \n", error); 660 return error; 661} 662 663// netfs_read_dir 664static 665int 666netfs_read_dir(void *ns, void *_node, void *cookie, long *count, 667 struct dirent *buffer, size_t bufferSize) 668{ 669 Node* node = (Node*)_node; 670 PRINT("netfs_read_dir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, cookie, 671 *count, buffer, bufferSize); 672 status_t error = node->GetVolume()->ReadDir(node, cookie, buffer, 673 bufferSize, *count, count); 674 PRINT("netfs_read_dir() done: (%lx, %ld)\n", error, *count); 675 #if DEBUG 676 dirent* entry = buffer; 677 for (int32 i = 0; i < *count; i++) { 678 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 679 // we need to work around. 680 char name[B_FILE_NAME_LENGTH]; 681 int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); 682 strncpy(name, entry->d_name, nameLen); 683 name[nameLen] = '\0'; 684 PRINT(" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld," 685 " d_pino: %Ld, d_reclen: %hu, d_name: `%s'\n", 686 entry->d_dev, entry->d_pdev, entry->d_ino, 687 entry->d_pino, entry->d_reclen, name); 688 entry = (dirent*)((char*)entry + entry->d_reclen); 689 } 690 #endif 691 692 return error; 693} 694 695// netfs_rewind_dir 696static 697int 698netfs_rewind_dir(void *ns, void *_node, void *cookie) 699{ 700 Node* node = (Node*)_node; 701 PRINT("netfs_rewind_dir(%p, %p, %p)\n", ns, node, cookie); 702 status_t error = node->GetVolume()->RewindDir(node, cookie); 703 PRINT("netfs_rewind_dir() done: %lx\n", error); 704 return error; 705} 706 707// netfs_walk 708static 709int 710netfs_walk(void *ns, void *_dir, const char *entryName, 711 char **resolvedPath, vnode_id *vnid) 712{ 713 Node* dir = (Node*)_dir; 714 PRINT("netfs_walk(%p, %p, `%s', %p, %p)\n", ns, dir, 715 entryName, resolvedPath, vnid); 716 status_t error = dir->GetVolume()->Walk(dir, entryName, resolvedPath, vnid); 717 PRINT("netfs_walk() done: (%lx, `%s', %Ld)\n", error, 718 (resolvedPath ? *resolvedPath : NULL), *vnid); 719 return error; 720} 721 722// #pragma mark - 723// #pragma mark ----- attributes ----- 724 725// netfs_open_attrdir 726static 727int 728netfs_open_attrdir(void *ns, void *_node, void **cookie) 729{ 730 Node* node = (Node*)_node; 731 PRINT("netfs_open_attrdir(%p, %p)\n", ns, node); 732 status_t error = node->GetVolume()->OpenAttrDir(node, cookie); 733 PRINT("netfs_open_attrdir() done: (%lx, %p)\n", error, *cookie); 734 return error; 735} 736 737// netfs_close_attrdir 738static 739int 740netfs_close_attrdir(void *ns, void *_node, void *cookie) 741{ 742 Node* node = (Node*)_node; 743 PRINT("netfs_close_attrdir(%p, %p, %p)\n", ns, node, cookie); 744 status_t error = node->GetVolume()->CloseAttrDir(node, cookie); 745 PRINT("netfs_close_attrdir() done: (%lx)\n", error); 746 return error; 747} 748 749// netfs_free_attrdir_cookie 750static 751int 752netfs_free_attrdir_cookie(void *ns, void *_node, void *cookie) 753{ 754 Node* node = (Node*)_node; 755 PRINT("netfs_free_attrdir_cookie(%p, %p, %p)\n", ns, node, cookie); 756 status_t error = node->GetVolume()->FreeAttrDirCookie(node, cookie); 757 PRINT("netfs_free_attrdir_cookie() done: (%lx)\n", error); 758 return error; 759} 760 761// netfs_read_attrdir 762static 763int 764netfs_read_attrdir(void *ns, void *_node, void *cookie, long *count, 765 struct dirent *buffer, size_t bufferSize) 766{ 767 Node* node = (Node*)_node; 768 PRINT("netfs_read_attrdir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, 769 cookie, *count, buffer, bufferSize); 770 status_t error = node->GetVolume()->ReadAttrDir(node, cookie, buffer, 771 bufferSize, *count, count); 772 PRINT("netfs_read_attrdir() done: (%lx, %ld)\n", error, *count); 773 return error; 774} 775 776// netfs_rewind_attrdir 777static 778int 779netfs_rewind_attrdir(void *ns, void *_node, void *cookie) 780{ 781 Node* node = (Node*)_node; 782 PRINT("netfs_rewind_attrdir(%p, %p, %p)\n", ns, node, cookie); 783 status_t error = node->GetVolume()->RewindAttrDir(node, cookie); 784 PRINT("netfs_rewind_attrdir() done: (%lx)\n", error); 785 return error; 786} 787 788// netfs_read_attr 789static 790int 791netfs_read_attr(void *ns, void *_node, const char *name, int type, 792 void *buffer, size_t *bufferSize, off_t pos) 793{ 794 Node* node = (Node*)_node; 795 PRINT("netfs_read_attr(%p, %p, `%s', %d, %p, %lu, %Ld)\n", ns, node, 796 name, type, buffer, *bufferSize, pos); 797 status_t error = node->GetVolume()->ReadAttr(node, name, type, pos, buffer, 798 *bufferSize, bufferSize); 799 PRINT("netfs_read_attr() done: (%lx, %ld)\n", error, *bufferSize); 800 return error; 801} 802 803// netfs_write_attr 804static 805int 806netfs_write_attr(void *ns, void *_node, const char *name, int type, 807 const void *buffer, size_t *bufferSize, off_t pos) 808{ 809 Node* node = (Node*)_node; 810 PRINT("netfs_write_attr(%p, %p, `%s', %d, %p, %lu, %Ld)\n", ns, node, 811 name, type, buffer, *bufferSize, pos); 812 status_t error = node->GetVolume()->WriteAttr(node, name, type, pos, buffer, 813 *bufferSize, bufferSize); 814 PRINT("netfs_write_attr() done: (%lx, %ld)\n", error, *bufferSize); 815 return error; 816} 817 818// netfs_remove_attr 819static 820int 821netfs_remove_attr(void *ns, void *_node, const char *name) 822{ 823 Node* node = (Node*)_node; 824 PRINT("netfs_remove_attr(%p, %p, `%s')\n", ns, node, name); 825 status_t error = node->GetVolume()->RemoveAttr(node, name); 826 PRINT("netfs_remove_attr() done: (%lx)\n", error); 827 return error; 828} 829 830// netfs_rename_attr 831static 832int 833netfs_rename_attr(void *ns, void *_node, const char *oldName, 834 const char *newName) 835{ 836 Node* node = (Node*)_node; 837 PRINT("netfs_rename_attr(%p, %p, `%s', `%s')\n", ns, node, oldName, 838 newName); 839 status_t error = node->GetVolume()->RenameAttr(node, oldName, newName); 840 PRINT("netfs_rename_attr() done: (%lx)\n", error); 841 return error; 842} 843 844// netfs_stat_attr 845static 846int 847netfs_stat_attr(void *ns, void *_node, const char *name, 848 struct attr_info *attrInfo) 849{ 850 Node* node = (Node*)_node; 851 PRINT("netfs_stat_attr(%p, %p, `%s', %p)\n", ns, node, name, 852 attrInfo); 853 status_t error = node->GetVolume()->StatAttr(node, name, attrInfo); 854 PRINT("netfs_stat_attr() done: (%lx)\n", error); 855 return error; 856} 857 858// #pragma mark - 859// #pragma mark ----- queries ----- 860 861// netfs_open_query 862static 863int 864netfs_open_query(void *ns, const char *queryString, ulong flags, 865 port_id port, long token, void **cookie) 866{ 867 VolumeManager* volumeManager = (VolumeManager*)ns; 868 Volume* volume = volumeManager->GetRootVolume(); 869 VolumePutter _(volume); 870 871 PRINT("netfs_open_query(%p, `%s', %lu, %ld, %ld, %p)\n", ns, 872 queryString, flags, port, token, cookie); 873 874 status_t error = B_BAD_VALUE; 875 if (volume) { 876 error = volume->OpenQuery(queryString, flags, port, token, 877 (QueryIterator**)cookie); 878 } 879 880 PRINT("netfs_open_query() done: (%lx, %p)\n", error, *cookie); 881 return error; 882} 883 884// netfs_close_query 885static 886int 887netfs_close_query(void *ns, void *cookie) 888{ 889 PRINT("netfs_close_query(%p, %p)\n", ns, cookie); 890 891 status_t error = B_OK; 892 // no-op: we don't use this hook 893 894 PRINT("netfs_close_query() done: (%lx)\n", error); 895 return error; 896} 897 898// netfs_free_query_cookie 899static 900int 901netfs_free_query_cookie(void *ns, void *node, void *cookie) 902{ 903 VolumeManager* volumeManager = (VolumeManager*)ns; 904 QueryIterator* iterator = (QueryIterator*)cookie; 905 906 PRINT("netfs_free_query_cookie(%p, %p)\n", ns, cookie); 907 908 status_t error = B_OK; 909 volumeManager->GetQueryManager()->PutIterator(iterator); 910 911 PRINT("netfs_free_query_cookie() done: (%lx)\n", error); 912 return error; 913} 914 915// netfs_read_query 916static 917int 918netfs_read_query(void *ns, void *cookie, long *count, 919 struct dirent *buffer, size_t bufferSize) 920{ 921 VolumeManager* volumeManager = (VolumeManager*)ns; 922 Volume* volume = volumeManager->GetRootVolume(); 923 QueryIterator* iterator = (QueryIterator*)cookie; 924 VolumePutter _(volume); 925 926 PRINT("netfs_read_query(%p, %p, %ld, %p, %lu)\n", ns, cookie, 927 *count, buffer, bufferSize); 928 929 status_t error = B_BAD_VALUE; 930 if (volume) { 931 error = volume->ReadQuery(iterator, buffer, bufferSize, 932 *count, count); 933 } 934 935 PRINT("netfs_read_query() done: (%lx, %ld)\n", error, *count); 936 return error; 937} 938 939