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: %" B_PRIx32 " \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: %" B_PRIx32 " \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: %" 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 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, %" 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 335static 336int 337netfs_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 352static 353int 354netfs_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 370static 371int 372netfs_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 384static 385int 386netfs_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 396static 397int 398netfs_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 408static 409int 410netfs_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 423static 424int 425netfs_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 439static 440int 441netfs_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 451static 452int 453netfs_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 463static 464int 465netfs_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 475static 476int 477netfs_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 490static 491int 492netfs_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 505static 506int 507netfs_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 535static 536int 537netfs_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 548static 549int 550netfs_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 560static 561int 562netfs_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 572static 573int 574netfs_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 591static 592int 593netfs_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 610static 611int 612netfs_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 622static 623int 624netfs_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 634static 635int 636netfs_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 646static 647int 648netfs_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 658static 659int 660netfs_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 670static 671int 672netfs_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 705static 706int 707netfs_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 717static 718int 719netfs_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 735static 736int 737netfs_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 747static 748int 749netfs_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 759static 760int 761netfs_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 771static 772int 773netfs_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 788static 789int 790netfs_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 800static 801int 802netfs_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 816static 817int 818netfs_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 832static 833int 834netfs_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 844static 845int 846netfs_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 858static 859int 860netfs_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 875static 876int 877netfs_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 898static 899int 900netfs_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 912static 913int 914netfs_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 929static 930int 931netfs_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