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 18 extern "C" { 19 20 // fs 21 static int netfs_mount(nspace_id nsid, const char *device, ulong flags, 22 void *parameters, size_t len, void **data, vnode_id *rootID); 23 static int netfs_unmount(void *ns); 24 //static int netfs_sync(void *ns); 25 static 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 29 static int netfs_read_vnode(void *ns, vnode_id vnid, char reenter, 30 void **node); 31 static int netfs_write_vnode(void *ns, void *node, char reenter); 32 static int netfs_remove_vnode(void *ns, void *node, char reenter); 33 34 // nodes 35 //static int netfs_fsync(void *ns, void *node); 36 static int netfs_read_stat(void *ns, void *node, struct stat *st); 37 static int netfs_write_stat(void *ns, void *node, struct stat *st, 38 long mask); 39 static int netfs_access(void *ns, void *node, int mode); 40 41 // files 42 static int netfs_create(void *ns, void *dir, const char *name, 43 int openMode, int mode, vnode_id *vnid, void **cookie); 44 static int netfs_open(void *ns, void *node, int openMode, void **cookie); 45 static int netfs_close(void *ns, void *node, void *cookie); 46 static int netfs_free_cookie(void *ns, void *node, void *cookie); 47 static int netfs_read(void *ns, void *node, void *cookie, off_t pos, 48 void *buffer, size_t *bufferSize); 49 static int netfs_write(void *ns, void *node, void *cookie, off_t pos, 50 const void *buffer, size_t *bufferSize); 51 static 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 56 static int netfs_link(void *ns, void *dir, const char *name, void *node); 57 static int netfs_unlink(void *ns, void *dir, const char *name); 58 static int netfs_symlink(void *ns, void *dir, const char *name, 59 const char *path); 60 static int netfs_read_link(void *ns, void *node, char *buffer, 61 size_t *bufferSize); 62 static int netfs_rename(void *ns, void *oldDir, const char *oldName, 63 void *newDir, const char *newName); 64 65 // directories 66 static int netfs_mkdir(void *ns, void *dir, const char *name, int mode); 67 static int netfs_rmdir(void *ns, void *dir, const char *name); 68 static int netfs_open_dir(void *ns, void *node, void **cookie); 69 static int netfs_close_dir(void *ns, void *node, void *cookie); 70 static int netfs_free_dir_cookie(void *ns, void *node, void *cookie); 71 static int netfs_read_dir(void *ns, void *node, void *cookie, 72 long *count, struct dirent *buffer, size_t bufferSize); 73 static int netfs_rewind_dir(void *ns, void *node, void *cookie); 74 static int netfs_walk(void *ns, void *dir, const char *entryName, 75 char **resolvedPath, vnode_id *vnid); 76 77 // attributes 78 static int netfs_open_attrdir(void *ns, void *node, void **cookie); 79 static int netfs_close_attrdir(void *ns, void *node, void *cookie); 80 static int netfs_free_attrdir_cookie(void *ns, void *node, void *cookie); 81 static int netfs_read_attrdir(void *ns, void *node, void *cookie, 82 long *count, struct dirent *buffer, size_t bufferSize); 83 static int netfs_read_attr(void *ns, void *node, const char *name, 84 int type, void *buffer, size_t *bufferSize, off_t pos); 85 static int netfs_rewind_attrdir(void *ns, void *node, void *cookie); 86 static int netfs_write_attr(void *ns, void *node, const char *name, 87 int type, const void *buffer, size_t *bufferSize, off_t pos); 88 static int netfs_remove_attr(void *ns, void *node, const char *name); 89 static int netfs_rename_attr(void *ns, void *node, const char *oldName, 90 const char *newName); 91 static int netfs_stat_attr(void *ns, void *node, const char *name, 92 struct attr_info *attrInfo); 93 94 // queries 95 static int netfs_open_query(void *ns, const char *queryString, ulong flags, 96 port_id port, long token, void **cookie); 97 static int netfs_close_query(void *ns, void *cookie); 98 static int netfs_free_query_cookie(void *ns, void *node, void *cookie); 99 static 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 */ 107 vnode_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 175 int32 api_version = B_CUR_FS_API_VERSION; 176 177 // #pragma mark - 178 // #pragma mark ----- fs ----- 179 180 // netfs_mount 181 static 182 int 183 netfs_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 221 static 222 int 223 netfs_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 245 static 246 int 247 netfs_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: %" B_PRIx32 " \n", error); 260 261 return error; 262 } 263 264 #endif 265 266 // netfs_read_fs_stat 267 static 268 int 269 netfs_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: %" B_PRIx32 " \n", error); 282 283 return error; 284 } 285 286 #if 0 // not used 287 288 // netfs_write_fs_stat 289 static 290 int 291 netfs_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: %" B_PRIx32 " \n", error); 304 305 return error; 306 } 307 308 #endif 309 310 // #pragma mark - 311 // #pragma mark ----- vnodes ----- 312 313 // netfs_read_vnode 314 static 315 int 316 netfs_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, %" B_PRIdINO ", %d, %p)\n", ns, vnid, reenter, 323 node); 324 325 status_t error = B_BAD_VALUE; 326 if (volume) 327 error = volume->ReadVNode(vnid, reenter, (Node**)node); 328 329 PRINT("netfs_read_vnode() done: (%" B_PRIx32 ", %p)\n", error, *node); 330 331 return error; 332 } 333 334 // netfs_write_vnode 335 static 336 int 337 netfs_write_vnode(void *ns, void *_node, char reenter) 338 { 339 Node* node = (Node*)_node; 340 // DANGER: If dbg_printf() is used, this thread will enter another FS and 341 // even perform a write operation. The is dangerous here, since this hook 342 // may be called out of the other FSs, since, for instance a put_vnode() 343 // called from another FS may cause the VFS layer to free vnodes and thus 344 // invoke this hook. 345 // PRINT(("netfs_write_vnode(%p, %p, %d)\n", ns, node, reenter)); 346 status_t error = node->GetVolume()->WriteVNode(node, reenter); 347 // PRINT(("netfs_write_vnode() done: %" B_PRIx32 "\n", error)); 348 return error; 349 } 350 351 // netfs_remove_vnode 352 static 353 int 354 netfs_remove_vnode(void *ns, void *_node, char reenter) 355 { 356 Node* node = (Node*)_node; 357 // DANGER: See netfs_write_vnode(). 358 // PRINT(("netfs_remove_vnode(%p, %p, %d)\n", ns, node, reenter)); 359 status_t error = node->GetVolume()->RemoveVNode(node, reenter); 360 // PRINT(("netfs_remove_vnode() done: %" B_PRIx32 "\n", error)); 361 return error; 362 } 363 364 // #pragma mark - 365 // #pragma mark ----- nodes ----- 366 367 #if 0 // not used 368 369 // netfs_fsync 370 static 371 int 372 netfs_fsync(void *ns, void *_node) 373 { 374 Node* node = (Node*)_node; 375 PRINT("netfs_fsync(%p, %p)\n", ns, node); 376 status_t error = node->GetVolume()->FSync(node); 377 PRINT("netfs_fsync() done: %" B_PRIx32 "\n", error); 378 return error; 379 } 380 381 #endif 382 383 // netfs_read_stat 384 static 385 int 386 netfs_read_stat(void *ns, void *_node, struct stat *st) 387 { 388 Node* node = (Node*)_node; 389 PRINT("netfs_read_stat(%p, %p, %p)\n", ns, node, st); 390 status_t error = node->GetVolume()->ReadStat(node, st); 391 PRINT("netfs_read_stat() done: %" B_PRIx32 "\n", error); 392 return error; 393 } 394 395 // netfs_write_stat 396 static 397 int 398 netfs_write_stat(void *ns, void *_node, struct stat *st, long mask) 399 { 400 Node* node = (Node*)_node; 401 PRINT("netfs_write_stat(%p, %p, %p, %ld)\n", ns, node, st, mask); 402 status_t error = node->GetVolume()->WriteStat(node, st, mask); 403 PRINT("netfs_write_stat() done: %" B_PRIx32 "\n", error); 404 return error; 405 } 406 407 // netfs_access 408 static 409 int 410 netfs_access(void *ns, void *_node, int mode) 411 { 412 Node* node = (Node*)_node; 413 PRINT("netfs_access(%p, %p, %d)\n", ns, node, mode); 414 status_t error = node->GetVolume()->Access(node, mode); 415 PRINT("netfs_access() done: %" B_PRIx32 "\n", error); 416 return error; 417 } 418 419 // #pragma mark - 420 // #pragma mark ----- files ----- 421 422 // netfs_create 423 static 424 int 425 netfs_create(void *ns, void *_dir, const char *name, int openMode, int mode, 426 vnode_id *vnid, void **cookie) 427 { 428 Node* dir = (Node*)_dir; 429 PRINT("netfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", ns, dir, 430 name, openMode, mode, vnid, cookie); 431 status_t error = dir->GetVolume()->Create(dir, name, openMode, mode, vnid, 432 cookie); 433 PRINT("netfs_create() done: (%" B_PRIx32 ", %" B_PRIdINO ", %p)\n", error, *vnid, 434 *cookie); 435 return error; 436 } 437 438 // netfs_open 439 static 440 int 441 netfs_open(void *ns, void *_node, int openMode, void **cookie) 442 { 443 Node* node = (Node*)_node; 444 PRINT("netfs_open(%p, %p, %d)\n", ns, node, openMode); 445 status_t error = node->GetVolume()->Open(node, openMode, cookie); 446 PRINT("netfs_open() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 447 return error; 448 } 449 450 // netfs_close 451 static 452 int 453 netfs_close(void *ns, void *_node, void *cookie) 454 { 455 Node* node = (Node*)_node; 456 PRINT("netfs_close(%p, %p, %p)\n", ns, node, cookie); 457 status_t error = node->GetVolume()->Close(node, cookie); 458 PRINT("netfs_close() done: %" B_PRIx32 "\n", error); 459 return error; 460 } 461 462 // netfs_free_cookie 463 static 464 int 465 netfs_free_cookie(void *ns, void *_node, void *cookie) 466 { 467 Node* node = (Node*)_node; 468 PRINT("netfs_free_cookie(%p, %p, %p)\n", ns, node, cookie); 469 status_t error = node->GetVolume()->FreeCookie(node, cookie); 470 PRINT("netfs_free_cookie() done: %" B_PRIx32 "\n", error); 471 return error; 472 } 473 474 // netfs_read 475 static 476 int 477 netfs_read(void *ns, void *_node, void *cookie, off_t pos, void *buffer, 478 size_t *bufferSize) 479 { 480 Node* node = (Node*)_node; 481 PRINT("netfs_read(%p, %p, %p, %" B_PRIdOFF ", %p, %lu)\n", ns, node, 482 cookie, pos, buffer, *bufferSize); 483 status_t error = node->GetVolume()->Read(node, cookie, pos, buffer, 484 *bufferSize, bufferSize); 485 PRINT("netfs_read() done: (%" B_PRIx32 ", %lu)\n", error, *bufferSize); 486 return error; 487 } 488 489 // netfs_write 490 static 491 int 492 netfs_write(void *ns, void *_node, void *cookie, off_t pos, 493 const void *buffer, size_t *bufferSize) 494 { 495 Node* node = (Node*)_node; 496 PRINT("netfs_write(%p, %p, %p, %" B_PRIdOFF ", %p, %lu)\n", ns, node, 497 cookie, pos, buffer, *bufferSize); 498 status_t error = node->GetVolume()->Write(node, cookie, pos, buffer, 499 *bufferSize, bufferSize); 500 PRINT("netfs_write() done: (%" B_PRIx32 ", %lu)\n", error, *bufferSize); 501 return error; 502 } 503 504 // netfs_ioctl 505 static 506 int 507 netfs_ioctl(void *ns, void *_node, void *cookie, int cmd, void *buffer, 508 size_t bufferSize) 509 { 510 Node* node = (Node*)_node; 511 PRINT("netfs_ioctl(%p, %p, %p, %d, %p, %lu)\n", ns, node, cookie, cmd, 512 buffer, bufferSize); 513 status_t error = node->GetVolume()->IOCtl(node, cookie, cmd, buffer, 514 bufferSize); 515 PRINT("netfs_ioctl() done: (%" B_PRIx32 ")\n", error); 516 return error; 517 } 518 519 // netfs_setflags 520 //static 521 //int 522 //netfs_setflags(void *ns, void *_node, void *cookie, int flags) 523 //{ 524 // Node* node = (Node*)_node; 525 // PRINT(("netfs_setflags(%p, %p, %p, %d)\n", ns, node, cookie, flags)); 526 // status_t error = node->GetVolume()->SetFlags(node, cookie, flags); 527 // PRINT(("netfs_setflags() done: (%lx)\n", error)); 528 // return error; 529 //} 530 531 // #pragma mark - 532 // #pragma mark ----- hard links / symlinks ----- 533 534 // netfs_link 535 static 536 int 537 netfs_link(void *ns, void *_dir, const char *name, void *_node) 538 { 539 Node* dir = (Node*)_dir; 540 Node* node = (Node*)_node; 541 PRINT("netfs_link(%p, %p, `%s', %p)\n", ns, dir, name, node); 542 status_t error = dir->GetVolume()->Link(dir, name, node); 543 PRINT("netfs_link() done: (%" B_PRIx32 ")\n", error); 544 return error; 545 } 546 547 // netfs_unlink 548 static 549 int 550 netfs_unlink(void *ns, void *_dir, const char *name) 551 { 552 Node* dir = (Node*)_dir; 553 PRINT("netfs_unlink(%p, %p, `%s')\n", ns, dir, name); 554 status_t error = dir->GetVolume()->Unlink(dir, name); 555 PRINT("netfs_unlink() done: (%" B_PRIx32 ")\n", error); 556 return error; 557 } 558 559 // netfs_symlink 560 static 561 int 562 netfs_symlink(void *ns, void *_dir, const char *name, const char *path) 563 { 564 Node* dir = (Node*)_dir; 565 PRINT("netfs_symlink(%p, %p, `%s', `%s')\n", ns, dir, name, path); 566 status_t error = dir->GetVolume()->Symlink(dir, name, path); 567 PRINT("netfs_symlink() done: (%" B_PRIx32 ")\n", error); 568 return error; 569 } 570 571 // netfs_read_link 572 static 573 int 574 netfs_read_link(void *ns, void *_node, char *buffer, size_t *bufferSize) 575 { 576 Node* node = (Node*)_node; 577 PRINT("netfs_read_link(%p, %p, %p, %lu)\n", ns, node, buffer, 578 *bufferSize); 579 status_t error = node->GetVolume()->ReadLink(node, buffer, *bufferSize, 580 bufferSize); 581 PRINT("netfs_read_link() done: (%" B_PRIx32 ", %lu)\n", error, 582 *bufferSize); 583 return error; 584 } 585 586 // netfs_rename 587 static 588 int 589 netfs_rename(void *ns, void *_oldDir, const char *oldName, void *_newDir, 590 const char *newName) 591 { 592 Node* oldDir = (Node*)_oldDir; 593 Node* newDir = (Node*)_newDir; 594 PRINT("netfs_rename(%p, %p, `%s', %p, `%s')\n", ns, oldDir, oldName, 595 newDir, newName); 596 status_t error = oldDir->GetVolume()->Rename(oldDir, oldName, 597 newDir, newName); 598 PRINT("netfs_rename() done: (%" B_PRIx32 ")\n", error); 599 return error; 600 } 601 602 // #pragma mark - 603 // #pragma mark ----- directories ----- 604 605 // netfs_mkdir 606 static 607 int 608 netfs_mkdir(void *ns, void *_dir, const char *name, int mode) 609 { 610 Node* dir = (Node*)_dir; 611 PRINT("netfs_mkdir(%p, %p, `%s', %d)\n", ns, dir, name, mode); 612 status_t error = dir->GetVolume()->MkDir(dir, name, mode); 613 PRINT("netfs_mkdir() done: (%" B_PRIx32 ")\n", error); 614 return error; 615 } 616 617 // netfs_rmdir 618 static 619 int 620 netfs_rmdir(void *ns, void *_dir, const char *name) 621 { 622 Node* dir = (Node*)_dir; 623 PRINT("netfs_rmdir(%p, %p, `%s')\n", ns, dir, name); 624 status_t error = dir->GetVolume()->RmDir(dir, name); 625 PRINT("netfs_rmdir() done: (%" B_PRIx32 ")\n", error); 626 return error; 627 } 628 629 // netfs_open_dir 630 static 631 int 632 netfs_open_dir(void *ns, void *_node, void **cookie) 633 { 634 Node* node = (Node*)_node; 635 PRINT("netfs_open_dir(%p, %p)\n", ns, node); 636 status_t error = node->GetVolume()->OpenDir(node, cookie); 637 PRINT("netfs_open_dir() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 638 return error; 639 } 640 641 // netfs_close_dir 642 static 643 int 644 netfs_close_dir(void *ns, void *_node, void *cookie) 645 { 646 Node* node = (Node*)_node; 647 PRINT("netfs_close_dir(%p, %p, %p)\n", ns, node, cookie); 648 status_t error = node->GetVolume()->CloseDir(node, cookie); 649 PRINT("netfs_close_dir() done: %" B_PRIx32 "\n", error); 650 return error; 651 } 652 653 // netfs_free_dir_cookie 654 static 655 int 656 netfs_free_dir_cookie(void *ns, void *_node, void *cookie) 657 { 658 Node* node = (Node*)_node; 659 PRINT("netfs_free_dir_cookie(%p, %p, %p)\n", ns, node, cookie); 660 status_t error = node->GetVolume()->FreeDirCookie(node, cookie); 661 PRINT("netfs_free_dir_cookie() done: %" B_PRIx32 " \n", error); 662 return error; 663 } 664 665 // netfs_read_dir 666 static 667 int 668 netfs_read_dir(void *ns, void *_node, void *cookie, long *count, 669 struct dirent *buffer, size_t bufferSize) 670 { 671 Node* node = (Node*)_node; 672 PRINT("netfs_read_dir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, cookie, 673 *count, buffer, bufferSize); 674 int32 _count = *count; 675 status_t error = node->GetVolume()->ReadDir(node, cookie, buffer, 676 bufferSize, _count, &_count); 677 *count = _count; 678 PRINT("netfs_read_dir() done: (%" B_PRIx32 ", %ld)\n", error, *count); 679 #if DEBUG 680 dirent* entry = buffer; 681 for (int32 i = 0; i < *count; i++) { 682 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 683 // we need to work around. 684 char name[B_FILE_NAME_LENGTH]; 685 int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); 686 strncpy(name, entry->d_name, nameLen); 687 name[nameLen] = '\0'; 688 PRINT(" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV 689 ", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO 690 ", d_reclen: %hu, d_name: `%s'\n", 691 entry->d_dev, entry->d_pdev, entry->d_ino, 692 entry->d_pino, entry->d_reclen, name); 693 entry = (dirent*)((char*)entry + entry->d_reclen); 694 } 695 #endif 696 697 return error; 698 } 699 700 // netfs_rewind_dir 701 static 702 int 703 netfs_rewind_dir(void *ns, void *_node, void *cookie) 704 { 705 Node* node = (Node*)_node; 706 PRINT("netfs_rewind_dir(%p, %p, %p)\n", ns, node, cookie); 707 status_t error = node->GetVolume()->RewindDir(node, cookie); 708 PRINT("netfs_rewind_dir() done: %" B_PRIx32 "\n", error); 709 return error; 710 } 711 712 // netfs_walk 713 static 714 int 715 netfs_walk(void *ns, void *_dir, const char *entryName, 716 char **resolvedPath, vnode_id *vnid) 717 { 718 Node* dir = (Node*)_dir; 719 PRINT("netfs_walk(%p, %p, `%s', %p, %p)\n", ns, dir, 720 entryName, resolvedPath, vnid); 721 status_t error = dir->GetVolume()->Walk(dir, entryName, resolvedPath, vnid); 722 PRINT("netfs_walk() done: (%" B_PRIx32 ", `%s', %" B_PRIdINO ")\n", error, 723 (resolvedPath ? *resolvedPath : NULL), *vnid); 724 return error; 725 } 726 727 // #pragma mark - 728 // #pragma mark ----- attributes ----- 729 730 // netfs_open_attrdir 731 static 732 int 733 netfs_open_attrdir(void *ns, void *_node, void **cookie) 734 { 735 Node* node = (Node*)_node; 736 PRINT("netfs_open_attrdir(%p, %p)\n", ns, node); 737 status_t error = node->GetVolume()->OpenAttrDir(node, cookie); 738 PRINT("netfs_open_attrdir() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 739 return error; 740 } 741 742 // netfs_close_attrdir 743 static 744 int 745 netfs_close_attrdir(void *ns, void *_node, void *cookie) 746 { 747 Node* node = (Node*)_node; 748 PRINT("netfs_close_attrdir(%p, %p, %p)\n", ns, node, cookie); 749 status_t error = node->GetVolume()->CloseAttrDir(node, cookie); 750 PRINT("netfs_close_attrdir() done: (%" B_PRIx32 ")\n", error); 751 return error; 752 } 753 754 // netfs_free_attrdir_cookie 755 static 756 int 757 netfs_free_attrdir_cookie(void *ns, void *_node, void *cookie) 758 { 759 Node* node = (Node*)_node; 760 PRINT("netfs_free_attrdir_cookie(%p, %p, %p)\n", ns, node, cookie); 761 status_t error = node->GetVolume()->FreeAttrDirCookie(node, cookie); 762 PRINT("netfs_free_attrdir_cookie() done: (%" B_PRIx32 ")\n", error); 763 return error; 764 } 765 766 // netfs_read_attrdir 767 static 768 int 769 netfs_read_attrdir(void *ns, void *_node, void *cookie, long *count, 770 struct dirent *buffer, size_t bufferSize) 771 { 772 Node* node = (Node*)_node; 773 PRINT("netfs_read_attrdir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, 774 cookie, *count, buffer, bufferSize); 775 int32 _count = *count; 776 status_t error = node->GetVolume()->ReadAttrDir(node, cookie, buffer, 777 bufferSize, _count, &_count); 778 *count = _count; 779 PRINT("netfs_read_attrdir() done: (%" B_PRIx32 ", %ld)\n", error, *count); 780 return error; 781 } 782 783 // netfs_rewind_attrdir 784 static 785 int 786 netfs_rewind_attrdir(void *ns, void *_node, void *cookie) 787 { 788 Node* node = (Node*)_node; 789 PRINT("netfs_rewind_attrdir(%p, %p, %p)\n", ns, node, cookie); 790 status_t error = node->GetVolume()->RewindAttrDir(node, cookie); 791 PRINT("netfs_rewind_attrdir() done: (%" B_PRIx32 ")\n", error); 792 return error; 793 } 794 795 // netfs_read_attr 796 static 797 int 798 netfs_read_attr(void *ns, void *_node, const char *name, int type, 799 void *buffer, size_t *bufferSize, off_t pos) 800 { 801 Node* node = (Node*)_node; 802 PRINT("netfs_read_attr(%p, %p, `%s', %d, %p, %lu, %" B_PRIdOFF ")\n", ns, 803 node, name, type, buffer, *bufferSize, pos); 804 status_t error = node->GetVolume()->ReadAttr(node, name, type, pos, buffer, 805 *bufferSize, bufferSize); 806 PRINT("netfs_read_attr() done: (%" B_PRIx32 ", %ld)\n", error, 807 *bufferSize); 808 return error; 809 } 810 811 // netfs_write_attr 812 static 813 int 814 netfs_write_attr(void *ns, void *_node, const char *name, int type, 815 const void *buffer, size_t *bufferSize, off_t pos) 816 { 817 Node* node = (Node*)_node; 818 PRINT("netfs_write_attr(%p, %p, `%s', %d, %p, %lu, %" B_PRIdOFF ")\n", ns, 819 node, name, type, buffer, *bufferSize, pos); 820 status_t error = node->GetVolume()->WriteAttr(node, name, type, pos, buffer, 821 *bufferSize, bufferSize); 822 PRINT("netfs_write_attr() done: (%" B_PRIx32 ", %ld)\n", error, 823 *bufferSize); 824 return error; 825 } 826 827 // netfs_remove_attr 828 static 829 int 830 netfs_remove_attr(void *ns, void *_node, const char *name) 831 { 832 Node* node = (Node*)_node; 833 PRINT("netfs_remove_attr(%p, %p, `%s')\n", ns, node, name); 834 status_t error = node->GetVolume()->RemoveAttr(node, name); 835 PRINT("netfs_remove_attr() done: (%" B_PRIx32 ")\n", error); 836 return error; 837 } 838 839 // netfs_rename_attr 840 static 841 int 842 netfs_rename_attr(void *ns, void *_node, const char *oldName, 843 const char *newName) 844 { 845 Node* node = (Node*)_node; 846 PRINT("netfs_rename_attr(%p, %p, `%s', `%s')\n", ns, node, oldName, 847 newName); 848 status_t error = node->GetVolume()->RenameAttr(node, oldName, newName); 849 PRINT("netfs_rename_attr() done: (%" B_PRIx32 ")\n", error); 850 return error; 851 } 852 853 // netfs_stat_attr 854 static 855 int 856 netfs_stat_attr(void *ns, void *_node, const char *name, 857 struct attr_info *attrInfo) 858 { 859 Node* node = (Node*)_node; 860 PRINT("netfs_stat_attr(%p, %p, `%s', %p)\n", ns, node, name, 861 attrInfo); 862 status_t error = node->GetVolume()->StatAttr(node, name, attrInfo); 863 PRINT("netfs_stat_attr() done: (%" B_PRIx32 ")\n", error); 864 return error; 865 } 866 867 // #pragma mark - 868 // #pragma mark ----- queries ----- 869 870 // netfs_open_query 871 static 872 int 873 netfs_open_query(void *ns, const char *queryString, ulong flags, 874 port_id port, long token, void **cookie) 875 { 876 VolumeManager* volumeManager = (VolumeManager*)ns; 877 Volume* volume = volumeManager->GetRootVolume(); 878 VolumePutter _(volume); 879 880 PRINT("netfs_open_query(%p, `%s', %lu, %" B_PRId32 ", %ld, %p)\n", ns, 881 queryString, flags, port, token, cookie); 882 883 status_t error = B_BAD_VALUE; 884 if (volume) { 885 error = volume->OpenQuery(queryString, flags, port, token, 886 (QueryIterator**)cookie); 887 } 888 889 PRINT("netfs_open_query() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 890 return error; 891 } 892 893 // netfs_close_query 894 static 895 int 896 netfs_close_query(void *ns, void *cookie) 897 { 898 PRINT("netfs_close_query(%p, %p)\n", ns, cookie); 899 900 status_t error = B_OK; 901 // no-op: we don't use this hook 902 903 PRINT("netfs_close_query() done: (%" B_PRIx32 ")\n", error); 904 return error; 905 } 906 907 // netfs_free_query_cookie 908 static 909 int 910 netfs_free_query_cookie(void *ns, void *node, void *cookie) 911 { 912 VolumeManager* volumeManager = (VolumeManager*)ns; 913 QueryIterator* iterator = (QueryIterator*)cookie; 914 915 PRINT("netfs_free_query_cookie(%p, %p)\n", ns, cookie); 916 917 status_t error = B_OK; 918 volumeManager->GetQueryManager()->PutIterator(iterator); 919 920 PRINT("netfs_free_query_cookie() done: (%" B_PRIx32 ")\n", error); 921 return error; 922 } 923 924 // netfs_read_query 925 static 926 int 927 netfs_read_query(void *ns, void *cookie, long *count, 928 struct dirent *buffer, size_t bufferSize) 929 { 930 VolumeManager* volumeManager = (VolumeManager*)ns; 931 Volume* volume = volumeManager->GetRootVolume(); 932 QueryIterator* iterator = (QueryIterator*)cookie; 933 VolumePutter _(volume); 934 935 PRINT("netfs_read_query(%p, %p, %ld, %p, %lu)\n", ns, cookie, 936 *count, buffer, bufferSize); 937 938 status_t error = B_BAD_VALUE; 939 if (volume) { 940 int32 _count = *count; 941 error = volume->ReadQuery(iterator, buffer, bufferSize, 942 _count, &_count); 943 *count = _count; 944 } 945 946 PRINT("netfs_read_query() done: (%" B_PRIx32 ", %ld)\n", error, *count); 947 return error; 948 } 949 950