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 580 // TODO: If this were to be implemented (which it isn't, it currently just 581 // returns B_BAD_VALUE) then this will need to be changed to return the 582 // length of the node and not the number of bytes read into buffer. 583 status_t error = node->GetVolume()->ReadLink(node, buffer, *bufferSize, 584 bufferSize); 585 PRINT("netfs_read_link() done: (%" B_PRIx32 ", %lu)\n", error, 586 *bufferSize); 587 return error; 588 } 589 590 // netfs_rename 591 static 592 int 593 netfs_rename(void *ns, void *_oldDir, const char *oldName, void *_newDir, 594 const char *newName) 595 { 596 Node* oldDir = (Node*)_oldDir; 597 Node* newDir = (Node*)_newDir; 598 PRINT("netfs_rename(%p, %p, `%s', %p, `%s')\n", ns, oldDir, oldName, 599 newDir, newName); 600 status_t error = oldDir->GetVolume()->Rename(oldDir, oldName, 601 newDir, newName); 602 PRINT("netfs_rename() done: (%" B_PRIx32 ")\n", error); 603 return error; 604 } 605 606 // #pragma mark - 607 // #pragma mark ----- directories ----- 608 609 // netfs_mkdir 610 static 611 int 612 netfs_mkdir(void *ns, void *_dir, const char *name, int mode) 613 { 614 Node* dir = (Node*)_dir; 615 PRINT("netfs_mkdir(%p, %p, `%s', %d)\n", ns, dir, name, mode); 616 status_t error = dir->GetVolume()->MkDir(dir, name, mode); 617 PRINT("netfs_mkdir() done: (%" B_PRIx32 ")\n", error); 618 return error; 619 } 620 621 // netfs_rmdir 622 static 623 int 624 netfs_rmdir(void *ns, void *_dir, const char *name) 625 { 626 Node* dir = (Node*)_dir; 627 PRINT("netfs_rmdir(%p, %p, `%s')\n", ns, dir, name); 628 status_t error = dir->GetVolume()->RmDir(dir, name); 629 PRINT("netfs_rmdir() done: (%" B_PRIx32 ")\n", error); 630 return error; 631 } 632 633 // netfs_open_dir 634 static 635 int 636 netfs_open_dir(void *ns, void *_node, void **cookie) 637 { 638 Node* node = (Node*)_node; 639 PRINT("netfs_open_dir(%p, %p)\n", ns, node); 640 status_t error = node->GetVolume()->OpenDir(node, cookie); 641 PRINT("netfs_open_dir() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 642 return error; 643 } 644 645 // netfs_close_dir 646 static 647 int 648 netfs_close_dir(void *ns, void *_node, void *cookie) 649 { 650 Node* node = (Node*)_node; 651 PRINT("netfs_close_dir(%p, %p, %p)\n", ns, node, cookie); 652 status_t error = node->GetVolume()->CloseDir(node, cookie); 653 PRINT("netfs_close_dir() done: %" B_PRIx32 "\n", error); 654 return error; 655 } 656 657 // netfs_free_dir_cookie 658 static 659 int 660 netfs_free_dir_cookie(void *ns, void *_node, void *cookie) 661 { 662 Node* node = (Node*)_node; 663 PRINT("netfs_free_dir_cookie(%p, %p, %p)\n", ns, node, cookie); 664 status_t error = node->GetVolume()->FreeDirCookie(node, cookie); 665 PRINT("netfs_free_dir_cookie() done: %" B_PRIx32 " \n", error); 666 return error; 667 } 668 669 // netfs_read_dir 670 static 671 int 672 netfs_read_dir(void *ns, void *_node, void *cookie, long *count, 673 struct dirent *buffer, size_t bufferSize) 674 { 675 Node* node = (Node*)_node; 676 PRINT("netfs_read_dir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, cookie, 677 *count, buffer, bufferSize); 678 int32 _count = *count; 679 status_t error = node->GetVolume()->ReadDir(node, cookie, buffer, 680 bufferSize, _count, &_count); 681 *count = _count; 682 PRINT("netfs_read_dir() done: (%" B_PRIx32 ", %ld)\n", error, *count); 683 #if DEBUG 684 dirent* entry = buffer; 685 for (int32 i = 0; i < *count; i++) { 686 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 687 // we need to work around. 688 char name[B_FILE_NAME_LENGTH]; 689 int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); 690 strncpy(name, entry->d_name, nameLen); 691 name[nameLen] = '\0'; 692 PRINT(" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV 693 ", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO 694 ", d_reclen: %hu, d_name: `%s'\n", 695 entry->d_dev, entry->d_pdev, entry->d_ino, 696 entry->d_pino, entry->d_reclen, name); 697 entry = (dirent*)((char*)entry + entry->d_reclen); 698 } 699 #endif 700 701 return error; 702 } 703 704 // netfs_rewind_dir 705 static 706 int 707 netfs_rewind_dir(void *ns, void *_node, void *cookie) 708 { 709 Node* node = (Node*)_node; 710 PRINT("netfs_rewind_dir(%p, %p, %p)\n", ns, node, cookie); 711 status_t error = node->GetVolume()->RewindDir(node, cookie); 712 PRINT("netfs_rewind_dir() done: %" B_PRIx32 "\n", error); 713 return error; 714 } 715 716 // netfs_walk 717 static 718 int 719 netfs_walk(void *ns, void *_dir, const char *entryName, 720 char **resolvedPath, vnode_id *vnid) 721 { 722 Node* dir = (Node*)_dir; 723 PRINT("netfs_walk(%p, %p, `%s', %p, %p)\n", ns, dir, 724 entryName, resolvedPath, vnid); 725 status_t error = dir->GetVolume()->Walk(dir, entryName, resolvedPath, vnid); 726 PRINT("netfs_walk() done: (%" B_PRIx32 ", `%s', %" B_PRIdINO ")\n", error, 727 (resolvedPath ? *resolvedPath : NULL), *vnid); 728 return error; 729 } 730 731 // #pragma mark - 732 // #pragma mark ----- attributes ----- 733 734 // netfs_open_attrdir 735 static 736 int 737 netfs_open_attrdir(void *ns, void *_node, void **cookie) 738 { 739 Node* node = (Node*)_node; 740 PRINT("netfs_open_attrdir(%p, %p)\n", ns, node); 741 status_t error = node->GetVolume()->OpenAttrDir(node, cookie); 742 PRINT("netfs_open_attrdir() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 743 return error; 744 } 745 746 // netfs_close_attrdir 747 static 748 int 749 netfs_close_attrdir(void *ns, void *_node, void *cookie) 750 { 751 Node* node = (Node*)_node; 752 PRINT("netfs_close_attrdir(%p, %p, %p)\n", ns, node, cookie); 753 status_t error = node->GetVolume()->CloseAttrDir(node, cookie); 754 PRINT("netfs_close_attrdir() done: (%" B_PRIx32 ")\n", error); 755 return error; 756 } 757 758 // netfs_free_attrdir_cookie 759 static 760 int 761 netfs_free_attrdir_cookie(void *ns, void *_node, void *cookie) 762 { 763 Node* node = (Node*)_node; 764 PRINT("netfs_free_attrdir_cookie(%p, %p, %p)\n", ns, node, cookie); 765 status_t error = node->GetVolume()->FreeAttrDirCookie(node, cookie); 766 PRINT("netfs_free_attrdir_cookie() done: (%" B_PRIx32 ")\n", error); 767 return error; 768 } 769 770 // netfs_read_attrdir 771 static 772 int 773 netfs_read_attrdir(void *ns, void *_node, void *cookie, long *count, 774 struct dirent *buffer, size_t bufferSize) 775 { 776 Node* node = (Node*)_node; 777 PRINT("netfs_read_attrdir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, 778 cookie, *count, buffer, bufferSize); 779 int32 _count = *count; 780 status_t error = node->GetVolume()->ReadAttrDir(node, cookie, buffer, 781 bufferSize, _count, &_count); 782 *count = _count; 783 PRINT("netfs_read_attrdir() done: (%" B_PRIx32 ", %ld)\n", error, *count); 784 return error; 785 } 786 787 // netfs_rewind_attrdir 788 static 789 int 790 netfs_rewind_attrdir(void *ns, void *_node, void *cookie) 791 { 792 Node* node = (Node*)_node; 793 PRINT("netfs_rewind_attrdir(%p, %p, %p)\n", ns, node, cookie); 794 status_t error = node->GetVolume()->RewindAttrDir(node, cookie); 795 PRINT("netfs_rewind_attrdir() done: (%" B_PRIx32 ")\n", error); 796 return error; 797 } 798 799 // netfs_read_attr 800 static 801 int 802 netfs_read_attr(void *ns, void *_node, const char *name, int type, 803 void *buffer, size_t *bufferSize, off_t pos) 804 { 805 Node* node = (Node*)_node; 806 PRINT("netfs_read_attr(%p, %p, `%s', %d, %p, %lu, %" B_PRIdOFF ")\n", ns, 807 node, name, type, buffer, *bufferSize, pos); 808 status_t error = node->GetVolume()->ReadAttr(node, name, type, pos, buffer, 809 *bufferSize, bufferSize); 810 PRINT("netfs_read_attr() done: (%" B_PRIx32 ", %ld)\n", error, 811 *bufferSize); 812 return error; 813 } 814 815 // netfs_write_attr 816 static 817 int 818 netfs_write_attr(void *ns, void *_node, const char *name, int type, 819 const void *buffer, size_t *bufferSize, off_t pos) 820 { 821 Node* node = (Node*)_node; 822 PRINT("netfs_write_attr(%p, %p, `%s', %d, %p, %lu, %" B_PRIdOFF ")\n", ns, 823 node, name, type, buffer, *bufferSize, pos); 824 status_t error = node->GetVolume()->WriteAttr(node, name, type, pos, buffer, 825 *bufferSize, bufferSize); 826 PRINT("netfs_write_attr() done: (%" B_PRIx32 ", %ld)\n", error, 827 *bufferSize); 828 return error; 829 } 830 831 // netfs_remove_attr 832 static 833 int 834 netfs_remove_attr(void *ns, void *_node, const char *name) 835 { 836 Node* node = (Node*)_node; 837 PRINT("netfs_remove_attr(%p, %p, `%s')\n", ns, node, name); 838 status_t error = node->GetVolume()->RemoveAttr(node, name); 839 PRINT("netfs_remove_attr() done: (%" B_PRIx32 ")\n", error); 840 return error; 841 } 842 843 // netfs_rename_attr 844 static 845 int 846 netfs_rename_attr(void *ns, void *_node, const char *oldName, 847 const char *newName) 848 { 849 Node* node = (Node*)_node; 850 PRINT("netfs_rename_attr(%p, %p, `%s', `%s')\n", ns, node, oldName, 851 newName); 852 status_t error = node->GetVolume()->RenameAttr(node, oldName, newName); 853 PRINT("netfs_rename_attr() done: (%" B_PRIx32 ")\n", error); 854 return error; 855 } 856 857 // netfs_stat_attr 858 static 859 int 860 netfs_stat_attr(void *ns, void *_node, const char *name, 861 struct attr_info *attrInfo) 862 { 863 Node* node = (Node*)_node; 864 PRINT("netfs_stat_attr(%p, %p, `%s', %p)\n", ns, node, name, 865 attrInfo); 866 status_t error = node->GetVolume()->StatAttr(node, name, attrInfo); 867 PRINT("netfs_stat_attr() done: (%" B_PRIx32 ")\n", error); 868 return error; 869 } 870 871 // #pragma mark - 872 // #pragma mark ----- queries ----- 873 874 // netfs_open_query 875 static 876 int 877 netfs_open_query(void *ns, const char *queryString, ulong flags, 878 port_id port, long token, void **cookie) 879 { 880 VolumeManager* volumeManager = (VolumeManager*)ns; 881 Volume* volume = volumeManager->GetRootVolume(); 882 VolumePutter _(volume); 883 884 PRINT("netfs_open_query(%p, `%s', %lu, %" B_PRId32 ", %ld, %p)\n", ns, 885 queryString, flags, port, token, cookie); 886 887 status_t error = B_BAD_VALUE; 888 if (volume) { 889 error = volume->OpenQuery(queryString, flags, port, token, 890 (QueryIterator**)cookie); 891 } 892 893 PRINT("netfs_open_query() done: (%" B_PRIx32 ", %p)\n", error, *cookie); 894 return error; 895 } 896 897 // netfs_close_query 898 static 899 int 900 netfs_close_query(void *ns, void *cookie) 901 { 902 PRINT("netfs_close_query(%p, %p)\n", ns, cookie); 903 904 status_t error = B_OK; 905 // no-op: we don't use this hook 906 907 PRINT("netfs_close_query() done: (%" B_PRIx32 ")\n", error); 908 return error; 909 } 910 911 // netfs_free_query_cookie 912 static 913 int 914 netfs_free_query_cookie(void *ns, void *node, void *cookie) 915 { 916 VolumeManager* volumeManager = (VolumeManager*)ns; 917 QueryIterator* iterator = (QueryIterator*)cookie; 918 919 PRINT("netfs_free_query_cookie(%p, %p)\n", ns, cookie); 920 921 status_t error = B_OK; 922 volumeManager->GetQueryManager()->PutIterator(iterator); 923 924 PRINT("netfs_free_query_cookie() done: (%" B_PRIx32 ")\n", error); 925 return error; 926 } 927 928 // netfs_read_query 929 static 930 int 931 netfs_read_query(void *ns, void *cookie, long *count, 932 struct dirent *buffer, size_t bufferSize) 933 { 934 VolumeManager* volumeManager = (VolumeManager*)ns; 935 Volume* volume = volumeManager->GetRootVolume(); 936 QueryIterator* iterator = (QueryIterator*)cookie; 937 VolumePutter _(volume); 938 939 PRINT("netfs_read_query(%p, %p, %ld, %p, %lu)\n", ns, cookie, 940 *count, buffer, bufferSize); 941 942 status_t error = B_BAD_VALUE; 943 if (volume) { 944 int32 _count = *count; 945 error = volume->ReadQuery(iterator, buffer, bufferSize, 946 _count, &_count); 947 *count = _count; 948 } 949 950 PRINT("netfs_read_query() done: (%" B_PRIx32 ", %ld)\n", error, *count); 951 return error; 952 } 953 954