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: %lx \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: %lx \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: %lx \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, %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 334 static 335 int 336 netfs_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 351 static 352 int 353 netfs_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 369 static 370 int 371 netfs_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 383 static 384 int 385 netfs_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 395 static 396 int 397 netfs_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 407 static 408 int 409 netfs_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 422 static 423 int 424 netfs_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 438 static 439 int 440 netfs_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 450 static 451 int 452 netfs_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 462 static 463 int 464 netfs_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 474 static 475 int 476 netfs_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 489 static 490 int 491 netfs_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 504 static 505 int 506 netfs_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 534 static 535 int 536 netfs_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 547 static 548 int 549 netfs_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 559 static 560 int 561 netfs_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 571 static 572 int 573 netfs_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 585 static 586 int 587 netfs_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 604 static 605 int 606 netfs_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 616 static 617 int 618 netfs_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 628 static 629 int 630 netfs_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 640 static 641 int 642 netfs_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 652 static 653 int 654 netfs_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 664 static 665 int 666 netfs_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 696 static 697 int 698 netfs_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 708 static 709 int 710 netfs_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 726 static 727 int 728 netfs_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 738 static 739 int 740 netfs_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 750 static 751 int 752 netfs_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 762 static 763 int 764 netfs_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 777 static 778 int 779 netfs_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 789 static 790 int 791 netfs_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 804 static 805 int 806 netfs_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 819 static 820 int 821 netfs_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 831 static 832 int 833 netfs_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 845 static 846 int 847 netfs_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 862 static 863 int 864 netfs_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 885 static 886 int 887 netfs_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 899 static 900 int 901 netfs_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 916 static 917 int 918 netfs_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